6e8fbca745
match the genesis editor version 1.3.0.653.
769 lines
22 KiB
C++
769 lines
22 KiB
C++
/****************************************************************************
|
||
Copyright (c) 2011-2013,WebJet Business Division,CYOU
|
||
|
||
http://www.genesis-3d.com.cn
|
||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
of this software and associated documentation files (the "Software"), to deal
|
||
in the Software without restriction, including without limitation the rights
|
||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
copies of the Software, and to permit persons to whom the Software is
|
||
furnished to do so, subject to the following conditions:
|
||
|
||
The above copyright notice and this permission notice shall be included in
|
||
all copies or substantial portions of the Software.
|
||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||
THE SOFTWARE.
|
||
****************************************************************************/
|
||
#include "stdneb.h"
|
||
#include "meshSpliter.h"
|
||
#include "RenderSystem.h"
|
||
|
||
//#define __DEBUG_MESHSPLITER__
|
||
//#define __DEBUG_MESHSPLITER_Print__
|
||
namespace Resources
|
||
{
|
||
//---------------------------------------------------------------------
|
||
__ImplementClass(MeshSpliter,'MHSP',Core::RefCounted);
|
||
__ImplementImageSingleton(MeshSpliter);
|
||
//---------------------------------------------------------------------
|
||
MeshSpliter::MeshSpliter():mMaxBoneBySubmesh( (128-16)/4 ),
|
||
mbInit(false)
|
||
{
|
||
__ConstructImageSingleton;
|
||
|
||
}
|
||
MeshSpliter::~MeshSpliter()
|
||
{
|
||
__DestructImageSingleton;
|
||
}
|
||
void MeshSpliter::Init()
|
||
{
|
||
if ( mbInit )
|
||
{
|
||
return;
|
||
}
|
||
mbInit = true;
|
||
#if RENDERDEVICE_OPENGLES
|
||
mMaxBoneBySubmesh = (RenderBase::GraphicCardCapability::s_mMaxUniformVectors-16)/4;
|
||
#else
|
||
mMaxBoneBySubmesh = 60;
|
||
#endif
|
||
#ifdef __DEBUG_MESHSPLITER__
|
||
mMaxBoneBySubmesh = 30;
|
||
#endif
|
||
|
||
|
||
}
|
||
void MeshSpliter::DebugPrint(GPtr<MeshRes>& pMesh)
|
||
{
|
||
#ifdef __DEBUG_MESHSPLITER_Print__
|
||
if ( pMesh->GetAffectedBonesIndex(0).Size() == 0 )
|
||
{
|
||
return;
|
||
}
|
||
mMeshRes=pMesh;
|
||
|
||
//debug=============
|
||
n_printf("meshID %s===================================\n",pMesh->GetMeshID().Get());
|
||
n_printf("submesh===================================\n");
|
||
for ( IndexT i = 0; i < mMeshRes->mSubMeshs.Size(); i++ )
|
||
{
|
||
n_printf("sub%d: \n",i);
|
||
n_printf("first index %d\n",mMeshRes->mSubMeshs[i].FirstIndex);
|
||
n_printf("number index %d\n",mMeshRes->mSubMeshs[i].numIndex);
|
||
n_printf("first vertex %d\n",mMeshRes->mSubMeshs[i].firstVertex);
|
||
n_printf("number vertex %d:\n",mMeshRes->mSubMeshs[i].numVertex);
|
||
}
|
||
n_printf("affected bone===================================\n");
|
||
for ( IndexT i = 0; i < mMeshRes->mAffectedBonesIndex.Size(); i++ )
|
||
{
|
||
Util::Array<uchar> affectedIdx = mMeshRes->mAffectedBonesIndex[i];
|
||
n_printf("sub%d------------------ \n",i);
|
||
for ( IndexT j = 0; j < affectedIdx.Size(); j++ )
|
||
{
|
||
uchar uVal = affectedIdx[j];
|
||
n_printf("%d\n",uVal);
|
||
}
|
||
}
|
||
n_printf("bone info===================================\n");
|
||
for ( IndexT i = 0; i < mMeshRes->mBoneInfo.Size(); i++ )
|
||
{
|
||
n_printf("mBoneInfo[%d]: ",i);
|
||
for ( IndexT j = 0; j < 4; j++ )
|
||
{
|
||
IndexT val = mMeshRes->mBoneInfo[i].boneIndex[j];
|
||
n_printf("%d ",val);
|
||
|
||
}
|
||
n_printf("\n");
|
||
}
|
||
|
||
n_printf("IB ===================================\n");
|
||
for ( IndexT i = 0; i < mMeshRes->mIndex16.Size(); i++ )
|
||
{
|
||
n_printf("Index16: ");
|
||
|
||
IndexT val = mMeshRes->mIndex16[i];
|
||
n_printf("%d ",val);
|
||
|
||
|
||
n_printf("\n");
|
||
}
|
||
|
||
/* n_printf("VB ===================================\n");
|
||
for ( IndexT i = 0; i < mMeshRes->mPosition.Size(); i++ )
|
||
{
|
||
n_printf("vbData: ");
|
||
|
||
Math::float3& v3Val = mMeshRes->mPosition[i];
|
||
n_printf("%f,%f,%f \n",v3Val.x(),v3Val.y(),v3Val.z());
|
||
}*/
|
||
|
||
//====================
|
||
#endif
|
||
}
|
||
void MeshSpliter::DoWork(GPtr<MeshRes>& pMesh)
|
||
{
|
||
#if RENDERDEVICE_OPENGLES
|
||
|
||
|
||
|
||
#ifdef __DEBUG_MESHSPLITER__
|
||
static bool bSkip = false;
|
||
#ifdef __GENESIS_EDITOR__
|
||
bSkip = true;
|
||
#endif
|
||
if ( bSkip )
|
||
{
|
||
return;
|
||
}
|
||
//if ( pMesh->GetMeshID() != "body_di" )
|
||
//{
|
||
// return;
|
||
//}
|
||
|
||
|
||
n_printf("meshspliter editor======================\n");
|
||
DebugPrint(pMesh);
|
||
|
||
|
||
|
||
#endif
|
||
|
||
DoWork_1(pMesh);
|
||
#ifdef __DEBUG_MESHSPLITER__
|
||
n_printf("meshspliter after======================\n");
|
||
DebugPrint(pMesh);
|
||
#endif
|
||
#endif
|
||
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void MeshSpliter::DoWork_1(GPtr<MeshRes>& pMesh)
|
||
{
|
||
if ( pMesh->GetAffectedBonesIndex(0).Size() == 0 )
|
||
{
|
||
return;
|
||
}
|
||
if ( !_IsNeedSplit(pMesh) )
|
||
{
|
||
return;
|
||
}
|
||
|
||
mMeshRes=pMesh;
|
||
|
||
mSubmeshMapWorkPart.Clear();
|
||
SubMeshArray allSubMeshArray;
|
||
bool bSuc(false);
|
||
bSuc = _SplitMesh(mMeshRes,allSubMeshArray);
|
||
if ( !bSuc )
|
||
{
|
||
return;
|
||
}
|
||
|
||
#ifdef __DEBUG_MESHSPLITER_Print__
|
||
n_printf("meshspliter meshid %s======================\n",pMesh->GetMeshID().Get());
|
||
n_printf("meshspliter before======================\n");
|
||
DebugPrint(pMesh);
|
||
#endif
|
||
MeshReviseWorkspace workspace;
|
||
workspace.Init(mMeshRes);
|
||
|
||
// update AffectedBonesIndex
|
||
//_UpdateAffectedBonesIndex(mMeshRes->mSubMeshs,workspace);
|
||
|
||
_RestoreRawBoneInfo(mMeshRes->mSubMeshs,workspace);
|
||
|
||
_SplitVertexs(allSubMeshArray,workspace);
|
||
|
||
//update
|
||
//debug start==============================
|
||
//allSubMeshArray.EraseIndex(1);
|
||
//mMeshRes->mSummeshUsedMaterial[0] = 0;
|
||
//debug end==============================
|
||
mMeshRes->mSubMeshs.Swap(allSubMeshArray);
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
bool MeshSpliter::_IsNeedSplit(GPtr<MeshRes>& pMesh)
|
||
{
|
||
SizeT oldSubmeshCount =pMesh->GetSubMeshCount();
|
||
for ( SizeT i = 0; i < oldSubmeshCount; ++i )
|
||
{
|
||
Util::Array<uchar>& affectdBones = pMesh->GetAffectedBonesIndex(i);
|
||
if ( affectdBones.Size() > mMaxBoneBySubmesh )
|
||
{
|
||
n_warning("dynamic split bone,cur device support boneNum:%d,mesh boneNum:%d,meshID:%s",mMaxBoneBySubmesh,affectdBones.Size(),pMesh->GetMeshID().Get());
|
||
return true;
|
||
}
|
||
|
||
}
|
||
return false;
|
||
}
|
||
|
||
//--------------------------------------------------------------------------
|
||
bool MeshSpliter::_SplitMesh(GPtr<MeshRes>& pMesh,SubMeshArray& mergeResult)
|
||
{
|
||
bool bSuc(false);
|
||
SizeT oldSubmeshCount =pMesh->GetSubMeshCount();
|
||
for ( SizeT i = 0; i < oldSubmeshCount; ++i )
|
||
{
|
||
SubMesh* pSubMesh= pMesh->GetSubMesh(i);
|
||
Util::Array<uchar>& affectdBones = pMesh->GetAffectedBonesIndex(i);
|
||
bSuc |= _TrySplitSubmesh(i,pSubMesh,affectdBones);
|
||
}
|
||
|
||
// submesh<73>ϲ<EFBFBD>
|
||
_MergeSubmeshes(mergeResult,mSubmeshMapWorkPart);
|
||
|
||
// add materialIdx used by submesh
|
||
mMeshRes->mSummeshUsedMaterial.Resize(oldSubmeshCount,1);
|
||
for ( SizeT i = 0; i < oldSubmeshCount; ++i )
|
||
{
|
||
IndexT keyIdx = mSubmeshMapWorkPart.FindIndex(i);
|
||
if ( keyIdx != InvalidIndex )
|
||
{// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
mMeshRes->mSummeshUsedMaterial[i] = mSubmeshMapWorkPart[i].Size();
|
||
}
|
||
}
|
||
|
||
return bSuc;
|
||
}
|
||
bool MeshSpliter::_TrySplitSubmesh(int iSubmesh,SubMesh* pSubmesh,Util::Array<uchar>& affectdBones)
|
||
{
|
||
int nSubmesh_bones = affectdBones.Size();
|
||
if ( nSubmesh_bones <= mMaxBoneBySubmesh )
|
||
{// no need split
|
||
return false;
|
||
}
|
||
|
||
// ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
int numIndex = pSubmesh->numIndex;
|
||
IndexT begin = pSubmesh->FirstIndex;
|
||
IndexT end = begin + pSubmesh->numIndex;
|
||
int curIndexByNewSubmesh = begin;
|
||
n_assert(numIndex%3 == 0);
|
||
|
||
Util::FixedArray<uint> aVertex;
|
||
aVertex.Resize(3);
|
||
SubMeshArray aSubmesh;
|
||
StdSetHelper helperSet;
|
||
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>λ<EFBFBD><CEBB><EFBFBD>ж<EFBFBD><D0B6>Ƿ<C7B7>subMesh<73><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
for (IndexT iIndex = begin; iIndex < end; iIndex += 3)
|
||
{
|
||
aVertex[0] = _GetVertexIndex(iIndex);
|
||
aVertex[1] = _GetVertexIndex(iIndex+1);
|
||
aVertex[2] = _GetVertexIndex(iIndex+2);
|
||
|
||
if ( _IsOverMaxBonesByTri(aVertex,helperSet) )
|
||
{
|
||
// add one new submesh
|
||
SubMesh newSubmesh;
|
||
newSubmesh.FirstIndex = curIndexByNewSubmesh;
|
||
//newSubmesh.numIndex = (iIndex - 1) - curIndexByNewSubmesh + 1;
|
||
newSubmesh.numIndex = (iIndex-1) - curIndexByNewSubmesh + 1;
|
||
|
||
curIndexByNewSubmesh = newSubmesh.FirstIndex + newSubmesh.numIndex;
|
||
|
||
aSubmesh.Append(newSubmesh);
|
||
helperSet.clear();
|
||
iIndex -= 3;
|
||
}
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD>old submesh <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>new submesh <20><>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƭsubmesh
|
||
IndexT endIdxByOldSubmesh = pSubmesh->FirstIndex + pSubmesh->numIndex -1;
|
||
if ( curIndexByNewSubmesh-1 < endIdxByOldSubmesh)
|
||
{//<2F><><EFBFBD><EFBFBD>Ƭ
|
||
// add one new submesh by left
|
||
SubMesh newSubmesh;
|
||
newSubmesh.FirstIndex = curIndexByNewSubmesh ;
|
||
newSubmesh.numIndex = endIdxByOldSubmesh - newSubmesh.FirstIndex + 1;
|
||
aSubmesh.Append(newSubmesh);
|
||
}
|
||
|
||
n_assert(aSubmesh.Size() >= 2); //<2F><>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if ( aSubmesh.Size() > 0 )
|
||
{
|
||
mSubmeshMapWorkPart.Add(iSubmesh,aSubmesh);
|
||
}
|
||
return true;
|
||
}
|
||
int MeshSpliter::_GetSubmeshFirstIndex(int iSubmesh)
|
||
{
|
||
int firstIndex = 0;
|
||
for ( int i = 0; i < iSubmesh; ++i)
|
||
{
|
||
firstIndex += mMeshRes->GetSubMesh(i)->numIndex;
|
||
}
|
||
return firstIndex;
|
||
}
|
||
bool MeshSpliter::_IsOverMaxBonesByTri(Util::FixedArray<uint>& aVertex,StdSetHelper& helperSet)
|
||
{
|
||
n_assert(aVertex.Size() == 3);
|
||
BoneInfoData::Elem* boneInfo = (BoneInfoData::Elem*)mMeshRes->GetDataImpl(VertexIndex::egBoneInfo,0);
|
||
for ( IndexT iVet = 0; iVet < aVertex.Size(); ++iVet )
|
||
{
|
||
uint iVetex = aVertex[iVet];
|
||
|
||
// һ<><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>4<EFBFBD><34><EFBFBD><EFBFBD>ͷӰ<CDB7><D3B0>
|
||
for ( int i = 0; i < 4; ++i )
|
||
{
|
||
ushort usIdxValue = boneInfo[iVetex].boneIndex[i]; // <20><>BoneInfoData<74><61><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
helperSet.insert(usIdxValue);
|
||
if ( (IndexT)helperSet.size() >= mMaxBoneBySubmesh )
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
#ifdef __DEBUG_MESHSPLITER__
|
||
typedef std::set<IndexT> StdSetIdx;
|
||
typedef std::map<IndexT,StdSetIdx> StdMapIdx;
|
||
static StdMapIdx g_stdMapIdx;
|
||
bool PreSubMeshHaveIVetIdx(IndexT iSubmesh,IndexT iVet)
|
||
{
|
||
for ( IndexT i = 0; i< iSubmesh; i++ )
|
||
{
|
||
StdSetIdx& oSet = g_stdMapIdx[i];
|
||
return (oSet.count(iVet) == 1);
|
||
}
|
||
return false;
|
||
|
||
}
|
||
#endif
|
||
void MeshSpliter::_RestoreRawBoneInfo(SubMeshArray& arrayRawSubmeshs, MeshReviseWorkspace& workspace)
|
||
{
|
||
#ifdef __DEBUG_MESHSPLITER__
|
||
g_stdMapIdx.clear();
|
||
#endif
|
||
|
||
// <20>ָ<EFBFBD>ԭʼ<D4AD><CABC><EFBFBD><EFBFBD>ֵ
|
||
workspace.mRestoreBoneInfo = mMeshRes->mBoneInfo;
|
||
IndexT boneIdxOffset(0);
|
||
for ( IndexT iSubmesh = 0; iSubmesh < (IndexT)arrayRawSubmeshs.Size(); ++iSubmesh )
|
||
{
|
||
|
||
std::set<IndexT> stdSetModifedIdx;
|
||
if ( iSubmesh >= 1 )
|
||
{
|
||
boneIdxOffset += mMeshRes->GetAffectedBonesIndex(iSubmesh-1).Size();
|
||
}
|
||
IndexT begin = arrayRawSubmeshs[iSubmesh].FirstIndex;
|
||
IndexT end = begin + arrayRawSubmeshs[iSubmesh].numIndex;
|
||
for ( IndexT i = begin; i < end; i++ )
|
||
{
|
||
IndexT iVet = _GetVertexIndex(i);
|
||
#ifdef __DEBUG_MESHSPLITER__
|
||
if ( iSubmesh >= 1 && PreSubMeshHaveIVetIdx(iSubmesh,iVet) )
|
||
{
|
||
n_error("pre submesh have ivet!!");
|
||
}
|
||
g_stdMapIdx[iSubmesh].insert(iVet);
|
||
#endif
|
||
if ( stdSetModifedIdx.count(iVet) == 1 )
|
||
{
|
||
continue;
|
||
|
||
}
|
||
stdSetModifedIdx.insert(iVet);
|
||
for ( int j = 0; j < 4; j++ )
|
||
{
|
||
workspace.mRestoreBoneInfo[iVet].boneIndex[j] = workspace.mRestoreBoneInfo[iVet].boneIndex[j] + boneIdxOffset;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
void MeshSpliter::_MergeSubmeshes(SubMeshArray& outResult, Util::Dictionary<IndexT,SubMeshArray>& aNewSubmesh)
|
||
{
|
||
SubMeshArray& oldSubmesh = mMeshRes->mSubMeshs;
|
||
for ( IndexT i = 0; i < oldSubmesh.Size(); i++ )
|
||
{
|
||
IndexT keyIdx = aNewSubmesh.FindIndex(i);
|
||
if ( keyIdx != InvalidIndex )
|
||
{// <20><>submesh <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
outResult.AppendArray( aNewSubmesh.ValueAtIndex(keyIdx) );
|
||
}
|
||
else
|
||
{// <20><><EFBFBD><EFBFBD>old submesh
|
||
outResult.Append( oldSubmesh[i]);
|
||
}
|
||
}
|
||
}
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>======================================================================
|
||
void MeshSpliter::_SplitVertexs(SubMeshArray& allSubMeshArray,MeshReviseWorkspace& workspace)
|
||
{// vertex<65><78><EFBFBD><EFBFBD>
|
||
/*
|
||
* <20><>allSubMeshArray<61><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>clone<6E><65>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>¹<EFBFBD><C2B9><EFBFBD><EFBFBD><EFBFBD>
|
||
* 1.<2E><><EFBFBD><EFBFBD>vertexBuffer<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD>vertexcolor,norma<6D>ȶ<EFBFBD><C8B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><D4A3><EFBFBD>IndexBuffer<65><72>
|
||
* 2.<2E><><EFBFBD><EFBFBD>vertexBuffer<65><72>Indexbuffer
|
||
* 3.<2E><><EFBFBD><EFBFBD>submesh<73><68><EFBFBD>ݣ<EFBFBD>firstVertex<65><78>numVertex,firstIndex,numIndex<65><78>
|
||
* remark:ͬ<>༭<EFBFBD><E0BCAD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>£<EFBFBD>clone<6E>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD>ź<EFBFBD><C5BA><EFBFBD>
|
||
*/
|
||
n_assert(allSubMeshArray.Size() >= 1);
|
||
n_printf("=====================submeshID: %s \n",mMeshRes->meshId.Get());
|
||
|
||
//Util::Array<StdMapVertexArrayIdx> ssvaVertexIdx;
|
||
std::vector<StdMapVertexArrayIdx> ssvaVertexIdx;
|
||
Util::Array<IndexT> helperAfftectedBone;
|
||
std::vector<uint> subIndexVB;
|
||
StdMapVertexArrayIdx emptyMap;
|
||
emptyMap.clear();
|
||
//ssvaVertexIdx.Resize(allSubMeshArray.Size(),emptyMap);
|
||
ssvaVertexIdx.resize(allSubMeshArray.Size(),emptyMap);
|
||
|
||
//workspace
|
||
Util::Array<uchar> emptArrayUChar;
|
||
workspace.mAffectedBoneIndex.Resize(allSubMeshArray.Size(),emptArrayUChar);
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30>submesh<73>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>submesh<73>й<EFBFBD><D0B9>õĶ<C3B5><C4B6>㣩
|
||
IndexT begin = allSubMeshArray[0].FirstIndex;
|
||
IndexT end = begin + allSubMeshArray[0].numIndex;
|
||
IndexT vertexCountDebug = 0;
|
||
IndexT iSub(0);
|
||
for ( IndexT i = begin; i < end; i++ )
|
||
{
|
||
IndexT rawVertexIdx = _GetVertexIndex(i);
|
||
_MakeAffectedBoneAndBoneInfo(iSub,rawVertexIdx,rawVertexIdx,workspace,helperAfftectedBone);
|
||
|
||
//std::vector< uint >itFindRaw = std::find(subIndexVB.begin(),subIndexVB.end(),rawVertexIdx);
|
||
//if ( itFindRaw == subIndexVB.end() )
|
||
//{
|
||
subIndexVB.push_back(rawVertexIdx);
|
||
//}
|
||
ssvaVertexIdx[iSub].insert(std::make_pair(rawVertexIdx,-1));
|
||
|
||
|
||
}
|
||
helperAfftectedBone.Clear();
|
||
|
||
|
||
// update submesh vertexIdx vertexNum
|
||
std::sort(subIndexVB.begin(), subIndexVB.end());
|
||
allSubMeshArray[0].firstVertex = subIndexVB.front();
|
||
allSubMeshArray[0].numVertex = subIndexVB.back() - subIndexVB.front() + 1;
|
||
subIndexVB.clear();
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>submesh<73><68><EFBFBD>õĶ<C3B5><C4B6><EFBFBD>
|
||
for ( IndexT iSub = 1; iSub < allSubMeshArray.Size(); ++iSub )
|
||
{
|
||
subIndexVB.clear();
|
||
helperAfftectedBone.Clear();
|
||
IndexT begin = allSubMeshArray[iSub].FirstIndex;
|
||
IndexT end = begin + allSubMeshArray[iSub].numIndex;
|
||
for ( IndexT indexIdx = begin; indexIdx < end; indexIdx++ )
|
||
{
|
||
IndexT rawVertexIdx = _GetVertexIndex(indexIdx);
|
||
bool bNeedClone = _HaveVertexIdx(ssvaVertexIdx,iSub,rawVertexIdx);
|
||
StdMapVertexArrayIdx::iterator itFind = ssvaVertexIdx[iSub].find(rawVertexIdx);
|
||
bool bHadCloned = ( ( itFind != ssvaVertexIdx[iSub].end() ) && ( itFind->second != (uint)-1) ) ;
|
||
|
||
// clone vertex
|
||
if ( bNeedClone )
|
||
{
|
||
if ( !bHadCloned )
|
||
{// <20><>ǰsubmesh<73>е<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>Ҫclone
|
||
IndexT lastVertexIdx = workspace.AddVertex(rawVertexIdx);
|
||
workspace.SetIBValue(indexIdx,lastVertexIdx);
|
||
|
||
ssvaVertexIdx[iSub].insert(std::make_pair(rawVertexIdx,lastVertexIdx));
|
||
subIndexVB.push_back(lastVertexIdx);
|
||
_MakeAffectedBoneAndBoneInfo(iSub,rawVertexIdx,lastVertexIdx,workspace,helperAfftectedBone);
|
||
}
|
||
else
|
||
{// had cloned ֱ<><D6B1>ָ<EFBFBD><D6B8><EFBFBD>Ǹ<EFBFBD><C7B8><EFBFBD><EFBFBD><EFBFBD>
|
||
workspace.SetIBValue(indexIdx,itFind->second);
|
||
//subIndexVB.push_back(itFind->second);
|
||
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
//
|
||
ssvaVertexIdx[iSub].insert(std::make_pair(rawVertexIdx,-1));
|
||
subIndexVB.push_back(rawVertexIdx);
|
||
_MakeAffectedBoneAndBoneInfo(iSub,rawVertexIdx,rawVertexIdx,workspace,helperAfftectedBone);
|
||
}
|
||
|
||
|
||
|
||
}
|
||
|
||
// update submesh vertexIdx vertexNum
|
||
std::sort(subIndexVB.begin(), subIndexVB.end());
|
||
allSubMeshArray[iSub].firstVertex = subIndexVB.front();
|
||
allSubMeshArray[iSub].numVertex = subIndexVB.back() - subIndexVB.front() + 1;
|
||
}
|
||
workspace.Swap();
|
||
|
||
|
||
}
|
||
|
||
//------------------------------------------------------------------------
|
||
void MeshSpliter::_MakeAffectedBoneAndBoneInfo(IndexT iSub,IndexT rawVertexIdx,IndexT newVertexIdx,MeshReviseWorkspace& workspace,Util::Array<IndexT>& helperAfftectedBone)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD>ԭʼaffectedBone<6E><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>workspace<63>е<EFBFBD>affectedbone<6E><65>
|
||
// <20><><EFBFBD><EFBFBD>workspace<63>е<EFBFBD>affectedbone <20><><EFBFBD><EFBFBD>boneInfo<66>е<EFBFBD>boneidxΪ<78><CEAA>Ⱦ<EFBFBD><C8BE>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
|
||
for ( int j = 0; j < 4; j++ )
|
||
{
|
||
// <20>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>boneIndex
|
||
IndexT idxAffetedBone = workspace.mRestoreBoneInfo[rawVertexIdx].boneIndex[j];
|
||
//
|
||
IndexT affectedBoneValue = _GetRawAffectedBonesValue(mMeshRes->mAffectedBonesIndex,idxAffetedBone);
|
||
|
||
|
||
|
||
if ( helperAfftectedBone.FindIndex(affectedBoneValue) == InvalidIndex )
|
||
{// û<>У<EFBFBD><EFBFBD><D7B7>
|
||
helperAfftectedBone.Append(affectedBoneValue);
|
||
|
||
// make affecteBone
|
||
workspace.mAffectedBoneIndex[iSub].Append( (uchar)affectedBoneValue );
|
||
IndexT lastIdxAffectedBoneIndex = workspace.mAffectedBoneIndex[iSub].Size() - 1;
|
||
|
||
// make boneInfo<66>е<EFBFBD>boneIndex
|
||
workspace.mBoneInfo[newVertexIdx].boneIndex[j] = lastIdxAffectedBoneIndex;
|
||
|
||
}
|
||
else
|
||
{// <20>У<EFBFBD><D0A3><EFBFBD>Ҫ<EFBFBD><EFBFBD>boneInfo<66>е<EFBFBD>boneIndex
|
||
IndexT idxFind = workspace.mAffectedBoneIndex[iSub].FindIndex(affectedBoneValue);
|
||
n_assert(idxFind != InvalidIndex); //idxFind <20><> helperAfftectedBone.FindIndex(affectedBoneValue)<29><><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD>
|
||
|
||
// make boneInfo<66>е<EFBFBD>boneIndex
|
||
workspace.mBoneInfo[newVertexIdx].boneIndex[j] = idxFind;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>======================================================================
|
||
|
||
IndexT MeshSpliter::_GetVertexIndex(IndexT idxAtIndexArray)
|
||
{
|
||
Index16Container::value_type* index16;
|
||
Index32Container::value_type* index32;
|
||
if ( mMeshRes->IsUseIndex16() )
|
||
{
|
||
index16 = mMeshRes->GetIndex16();
|
||
}
|
||
else
|
||
{
|
||
index32 = mMeshRes->GetIndex32();
|
||
}
|
||
|
||
IndexT iVet = mMeshRes->IsUseIndex16() ? index16[idxAtIndexArray] : index32[idxAtIndexArray];
|
||
return iVet;
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
void MeshSpliter::_GetAffectedBonesIndex(FixedArrayBonesIndex& outAffectedBonesIndex, IndexT idxAtVertexArray,MeshReviseWorkspace& workspace)
|
||
{
|
||
outAffectedBonesIndex.Resize(4);
|
||
for ( int i = 0; i < 4; i++ )
|
||
{
|
||
outAffectedBonesIndex[i] = workspace.mRestoreBoneInfo[idxAtVertexArray].boneIndex[i];
|
||
}
|
||
|
||
}
|
||
|
||
|
||
//------------------------------------------------------------------------
|
||
bool MeshSpliter::_HaveVertexIdx(std::vector<StdMapVertexArrayIdx> ssvaVertexIdx, IndexT end, IndexT testVal)
|
||
{
|
||
for ( IndexT iSub = 0; iSub < end; iSub++ )
|
||
{
|
||
if ( ssvaVertexIdx[iSub].find(testVal) != ssvaVertexIdx[iSub].end() )
|
||
{
|
||
return true;
|
||
}
|
||
|
||
}
|
||
return false;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
IndexT MeshSpliter::_GetRawAffectedBonesValue(AffectedBonesIndex& rawAffectedBones, IndexT restoreBoneIdx)
|
||
{
|
||
IndexT totalIdx(0),preTotalNum(0);
|
||
for ( IndexT i = 0; i < rawAffectedBones.Size(); i++ )
|
||
{
|
||
if ( i >= 1 )
|
||
{
|
||
preTotalNum += rawAffectedBones[i-1].Size();
|
||
}
|
||
|
||
totalIdx += rawAffectedBones[i].Size();
|
||
if ( restoreBoneIdx <totalIdx )
|
||
{
|
||
return rawAffectedBones[i][restoreBoneIdx - preTotalNum];
|
||
}
|
||
|
||
}
|
||
n_assert(0);
|
||
return InvalidIndex;
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
MeshReviseWorkspace::MeshReviseWorkspace()
|
||
{
|
||
|
||
}
|
||
MeshReviseWorkspace::~MeshReviseWorkspace()
|
||
{
|
||
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
void MeshReviseWorkspace::Init(GPtr<MeshRes>& pMesh)
|
||
{
|
||
mMeshRes = pMesh;
|
||
mbUseIndex16 = mMeshRes->IsUseIndex16();
|
||
|
||
// clone IB
|
||
if ( mbUseIndex16 )
|
||
{
|
||
mIndex16 = mMeshRes->mIndex16;
|
||
}
|
||
else
|
||
{
|
||
mIndex32 = mMeshRes->mIndex32;
|
||
}
|
||
// clone VB
|
||
// position
|
||
mPosition = mMeshRes->mPosition;
|
||
|
||
// color
|
||
mColor = mMeshRes->mColor;
|
||
|
||
// other...
|
||
mTexCoords = mMeshRes->mTexCoords;
|
||
mNormal = mMeshRes->mNormal;
|
||
mTangent = mMeshRes->mTangent;
|
||
mBiNormal = mMeshRes->mBiNormal;
|
||
mBoneInfo = mMeshRes->mBoneInfo;
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
void MeshReviseWorkspace::Reserve(int num)
|
||
{
|
||
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
IndexT MeshReviseWorkspace::AddVertex(int rawVetexArrayIdx)
|
||
{// <20><>ԭʼvb<76>е<EFBFBD><D0B5><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
// position
|
||
if(rawVetexArrayIdx < mMeshRes->mPosition.Size())
|
||
mPosition.Append( mMeshRes->mPosition[rawVetexArrayIdx] );
|
||
// color
|
||
if(rawVetexArrayIdx < mMeshRes->mColor.Size())
|
||
mColor.Append( mMeshRes->mColor[rawVetexArrayIdx] );
|
||
|
||
// other...
|
||
for ( IndexT i = 0 ; i < mMeshRes->mTexCoords.Size(); ++i )
|
||
{
|
||
TexCoordData& texcoordRht = mMeshRes->mTexCoords[i];
|
||
TexCoordData& texcoord = mTexCoords[i];
|
||
texcoord.Append(texcoordRht[rawVetexArrayIdx]);
|
||
}
|
||
|
||
if(rawVetexArrayIdx < mMeshRes->mNormal.Size())
|
||
mNormal.Append( mMeshRes->mNormal[rawVetexArrayIdx] );
|
||
if(rawVetexArrayIdx < mMeshRes->mTangent.Size())
|
||
mTangent.Append( mMeshRes->mTangent[rawVetexArrayIdx] );
|
||
if(rawVetexArrayIdx < mMeshRes->mBiNormal.Size())
|
||
mBiNormal.Append( mMeshRes->mBiNormal[rawVetexArrayIdx] );
|
||
if(rawVetexArrayIdx < mMeshRes->mBoneInfo.Size())
|
||
mBoneInfo.Append( mMeshRes->mBoneInfo[rawVetexArrayIdx] );
|
||
|
||
|
||
return mPosition.Size() - 1;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void MeshReviseWorkspace::Swap()
|
||
{
|
||
if ( mbUseIndex16 )
|
||
{
|
||
mIndex16.Swap( mMeshRes->mIndex16);
|
||
}
|
||
else
|
||
{
|
||
mIndex32.Swap( mMeshRes->mIndex32);
|
||
}
|
||
mPosition.Swap(mMeshRes->mPosition);
|
||
mColor.Swap(mMeshRes->mColor);
|
||
mTexCoords.Swap(mMeshRes->mTexCoords);
|
||
mNormal.Swap(mMeshRes->mNormal);
|
||
mTangent.Swap(mMeshRes->mTangent);
|
||
|
||
mBiNormal.Swap(mMeshRes->mBiNormal);
|
||
mBoneInfo.Swap(mMeshRes->mBoneInfo);
|
||
mAffectedBoneIndex.Swap(mMeshRes->mAffectedBonesIndex);
|
||
|
||
n_assert(mMeshRes->Validate());
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
void MeshReviseWorkspace::AddIndex(IndexT newIndexArrayIdxValue)
|
||
{
|
||
if ( mbUseIndex16 )
|
||
{
|
||
mIndex16.Append( (ushort)newIndexArrayIdxValue );
|
||
}
|
||
else
|
||
{
|
||
mIndex32.Append( newIndexArrayIdxValue );
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void MeshReviseWorkspace::SetIBValue(IndexT indexIB,IndexT val)
|
||
{
|
||
if ( mbUseIndex16 )
|
||
{
|
||
mIndex16[indexIB] = (ushort)val;
|
||
}
|
||
else
|
||
{
|
||
mIndex32[indexIB] = val;
|
||
}
|
||
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
IndexT MeshReviseWorkspace::GetVertexArraySize()
|
||
{
|
||
return mPosition.Size();
|
||
}
|
||
|
||
|
||
|
||
} |