Skip to content

Commit

Permalink
Merge pull request #68 from DavidWyand-GG/issue66-SkinnedMeshCrash
Browse files Browse the repository at this point in the history
Fix for Issue #66 for Skinned mesh crash
  • Loading branch information
DavidWyand-GG committed Oct 4, 2012
2 parents 811f27f + 75d9470 commit 1ca29b1
Showing 1 changed file with 53 additions and 2 deletions.
55 changes: 53 additions & 2 deletions Engine/source/ts/tsMesh.cpp
Expand Up @@ -1301,6 +1301,8 @@ void TSSkinMesh::createBatchData()
// Temp vector to build batch operations
Vector<BatchData::BatchedVertex> batchOperations;

bool issuedWeightWarning = false;

// Build the batch operations
while( curVtx != endVtx )
{
Expand All @@ -1313,13 +1315,43 @@ void TSSkinMesh::createBatchData()
const F32 w = *curWeight;
++curWeight;

// Ignore empty weights
if ( vidx < 0 || midx < 0 || w == 0 )
continue;

if( !batchOperations.empty() &&
batchOperations.last().vertexIndex == vidx )
{
AssertFatal( batchOperations.last().transformCount > 0, "Not sure how this happened!" );

const int opIdx = batchOperations.last().transformCount++;
AssertISV( BatchData::maxBonePerVert > opIdx, "Too many bones affecting the same vertex, increase the size of 'TSMesh::BatchData::maxBonePerVert'" );
S32 opIdx = batchOperations.last().transformCount++;

// Limit the number of weights per bone (keep the N largest influences)
if ( opIdx >= TSSkinMesh::BatchData::maxBonePerVert )
{
if ( !issuedWeightWarning )
{
issuedWeightWarning = true;
Con::warnf( "At least one vertex has too many bone weights - limiting "
"to the largest %d influences (see maxBonePerVert in tsMesh.h).",
TSSkinMesh::BatchData::maxBonePerVert );
}

// Too many weights => find and replace the smallest one
S32 minIndex = 0;
F32 minWeight = batchOperations.last().transform[0].weight;
for ( S32 i = 1; i < batchOperations.last().transformCount; i++ )
{
if ( batchOperations.last().transform[i].weight < minWeight )
{
minWeight = batchOperations.last().transform[i].weight;
minIndex = i;
}
}

opIdx = minIndex;
batchOperations.last().transformCount = TSSkinMesh::BatchData::maxBonePerVert;
}

batchOperations.last().transform[opIdx].transformIndex = midx;
batchOperations.last().transform[opIdx].weight = w;
Expand All @@ -1337,6 +1369,25 @@ void TSSkinMesh::createBatchData()
}
//Con::printf("End skin update");

// Normalize vertex weights (force weights for each vert to sum to 1)
if ( issuedWeightWarning )
{
for ( S32 i = 0; i < batchOperations.size(); i++ )
{
BatchData::BatchedVertex& batchOp = batchOperations[i];

// Sum weights for this vertex
F32 invTotalWeight = 0;
for ( S32 j = 0; j < batchOp.transformCount; j++ )
invTotalWeight += batchOp.transform[j].weight;

// Then normalize the vertex weights
invTotalWeight = 1.0f / invTotalWeight;
for ( S32 j = 0; j < batchOp.transformCount; j++ )
batchOp.transform[j].weight *= invTotalWeight;
}
}

#ifdef _BATCH_BY_VERTEX
// Copy data to member, and be done
batchData.vertexBatchOperations.set(batchOperations.address(), batchOperations.size());
Expand Down

0 comments on commit 1ca29b1

Please sign in to comment.