@@ -87,10 +87,12 @@ const char *CSkelMeshInstance::GetAnimName(int Index) const
87
87
-----------------------------------------------------------------------------*/
88
88
89
89
CSkelMeshInstance::CSkelMeshInstance ()
90
- : LodNum(0 )
90
+ : LodIndex(0 )
91
+ , MorphIndex(-1 )
91
92
, UVIndex(0 )
92
93
, RotationMode(EARO_AnimSet)
93
- , LastLodNum(-2 ) // differs from LodNum and from all other values
94
+ , LastLodIndex(-2 ) // differs from LodNum and from all other values
95
+ , LastMorphIndex(-1 )
94
96
, MaxAnimChannel(-1 )
95
97
, Animation(NULL )
96
98
, DataBlock(NULL )
@@ -202,12 +204,15 @@ void CSkelMeshInstance::SetMesh(CSkeletalMesh *Mesh)
202
204
InfColors = NULL ;
203
205
}
204
206
// allocate data arrays in a single block
205
- int DataSize = sizeof (CMeshBoneData) * NumBones + sizeof (CSkinVert) * NumVerts;
207
+ int NumMorphVerts = Mesh->Morphs .Num () ? NumVerts : 0 ;
208
+ int DataSize = sizeof (CMeshBoneData) * NumBones + sizeof (CSkinVert) * NumVerts + sizeof (CSkelMeshVertex) * NumMorphVerts;
206
209
DataBlock = appMalloc (DataSize, 16 );
207
210
BoneData = (CMeshBoneData*)DataBlock;
208
211
Skinned = (CSkinVert*)(BoneData + NumBones);
212
+ MorphedVerts = Mesh->Morphs .Num () ? (CSkelMeshVertex*)(Skinned + NumVerts) : NULL ;
209
213
210
- LastLodNum = -2 ;
214
+ LastLodIndex = -2 ;
215
+ LastMorphIndex = -1 ;
211
216
212
217
CMeshBoneData *data;
213
218
for (i = 0 , data = BoneData; i < NumBones; i++, data++)
@@ -1003,14 +1008,16 @@ void CSkelMeshInstance::SkinMeshVerts()
1003
1008
{
1004
1009
guard (CSkelMeshInstance::SkinMeshVerts);
1005
1010
1006
- const CSkelMeshLod& Mesh = pMesh->Lods [LodNum ];
1011
+ const CSkelMeshLod& Mesh = pMesh->Lods [LodIndex ];
1007
1012
int NumVerts = Mesh.NumVerts ;
1008
1013
1009
1014
memset (Skinned, 0 , sizeof (CSkinVert) * NumVerts);
1010
1015
1016
+ const CSkelMeshVertex* MeshVerts = BuildMorphVerts () ? MorphedVerts : Mesh.Verts ;
1017
+
1011
1018
for (int i = 0 ; i < NumVerts; i++)
1012
1019
{
1013
- const CSkelMeshVertex &V = Mesh. Verts [i];
1020
+ const CSkelMeshVertex &V = MeshVerts [i];
1014
1021
CSkinVert &D = Skinned[i];
1015
1022
1016
1023
CVec4 UnpackedWeights;
@@ -1102,7 +1109,7 @@ void CSkelMeshInstance::DrawMesh(unsigned flags)
1102
1109
1103
1110
if (!pMesh->Lods .Num ()) return ;
1104
1111
1105
- /* const*/ CSkelMeshLod& Mesh = pMesh->Lods [LodNum ]; // ?? not 'const' because of BuildTangents(); change this?
1112
+ /* const*/ CSkelMeshLod& Mesh = pMesh->Lods [LodIndex ]; // ?? not 'const' because of BuildTangents(); change this?
1106
1113
int NumSections = Mesh.Sections .Num ();
1107
1114
int NumVerts = Mesh.NumVerts ;
1108
1115
if (!NumSections || !NumVerts) return ;
@@ -1356,7 +1363,7 @@ void CSkelMeshInstance::Draw(unsigned flags)
1356
1363
guard (CSkelMeshInstance::Draw);
1357
1364
1358
1365
// switch LOD model
1359
- if (LodNum != LastLodNum )
1366
+ if (LodIndex != LastLodIndex )
1360
1367
{
1361
1368
// LOD has been changed
1362
1369
@@ -1365,7 +1372,7 @@ void CSkelMeshInstance::Draw(unsigned flags)
1365
1372
delete[] InfColors;
1366
1373
InfColors = NULL ;
1367
1374
}
1368
- LastLodNum = LodNum ;
1375
+ LastLodIndex = LodIndex ;
1369
1376
}
1370
1377
// draw ...
1371
1378
DrawMesh (flags);
@@ -1380,7 +1387,7 @@ void CSkelMeshInstance::BuildInfColors()
1380
1387
1381
1388
int i;
1382
1389
1383
- const CSkelMeshLod &Lod = pMesh->Lods [LodNum ];
1390
+ const CSkelMeshLod &Lod = pMesh->Lods [LodIndex ];
1384
1391
1385
1392
if (InfColors) delete[] InfColors;
1386
1393
InfColors = new CVec3[Lod.NumVerts ];
@@ -1407,4 +1414,46 @@ void CSkelMeshInstance::BuildInfColors()
1407
1414
unguard;
1408
1415
}
1409
1416
1417
+
1418
+ bool CSkelMeshInstance::BuildMorphVerts ()
1419
+ {
1420
+ guard (CSkelMeshInstance::BuildMorphVerts);
1421
+
1422
+ if (MorphIndex < 0 )
1423
+ {
1424
+ // Morph is inactive
1425
+ return false ;
1426
+ }
1427
+
1428
+ if (LodIndex >= pMesh->Morphs [MorphIndex]->Lods .Num ())
1429
+ {
1430
+ // No morph information for this LOD
1431
+ return false ;
1432
+ }
1433
+
1434
+ if (LastMorphIndex == MorphIndex)
1435
+ {
1436
+ // Already built
1437
+ return true ;
1438
+ }
1439
+ LastMorphIndex = MorphIndex;
1440
+
1441
+ const CSkelMeshLod& Lod = pMesh->Lods [LodIndex];
1442
+ const TArray<CMorphVertex>& Deltas = pMesh->Morphs [MorphIndex]->Lods [LodIndex].Vertices ;
1443
+
1444
+ // Copy unmodified vertices
1445
+ memcpy (MorphedVerts, Lod.Verts , Lod.NumVerts * sizeof (CSkelMeshVertex));
1446
+
1447
+ // Apply delta
1448
+ for (const CMorphVertex& Delta : Deltas)
1449
+ {
1450
+ CSkelMeshVertex& V = MorphedVerts[Delta.VertexIndex ];
1451
+ VectorAdd (V.Position , Delta.PositionDelta , V.Position );
1452
+ }
1453
+
1454
+ return true ;
1455
+
1456
+ unguard;
1457
+ }
1458
+
1410
1459
#endif // RENDERING
0 commit comments