Skip to content

Commit 8003d18

Browse files
committed
Converting morph targets to internal format.
Also showing morph information in viewport.
1 parent 6b86f53 commit 8003d18

File tree

7 files changed

+133
-13
lines changed

7 files changed

+133
-13
lines changed

Unreal/SkeletalMesh.h

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,6 @@ struct CSkelMeshVertex : public CMeshVertex
4949
}
5050
};
5151

52-
53-
struct CSkelMeshBone
54-
{
55-
FName Name;
56-
int ParentIndex;
57-
CVec3 Position;
58-
CQuat Orientation;
59-
};
60-
61-
6252
struct CSkelMeshLod : public CBaseMeshLod
6353
{
6454
CSkelMeshVertex *Verts;
@@ -106,6 +96,26 @@ struct CSkelMeshLod : public CBaseMeshLod
10696
#endif // DECLARE_VIEWER_PROPS
10797
};
10898

99+
struct CSkelMeshBone
100+
{
101+
FName Name;
102+
int ParentIndex;
103+
CVec3 Position;
104+
CQuat Orientation;
105+
};
106+
107+
struct CMorphVertex
108+
{
109+
CVec3 PositionDelta;
110+
CVec3 NormalDelta;
111+
int VertexIndex;
112+
};
113+
114+
struct CMorphLod
115+
{
116+
FString Name;
117+
TArray<CMorphVertex> Vertices;
118+
};
109119

110120
struct CSkelMeshSocket
111121
{
@@ -122,18 +132,18 @@ struct CSkelMeshSocket
122132
#endif
123133
};
124134

125-
126135
class CSkeletalMesh
127136
{
128137
public:
129-
UObject *OriginalMesh; //?? make common for all mesh classes
138+
UObject* OriginalMesh; //?? make common for all mesh classes
130139
FBox BoundingBox; //?? common
131140
FSphere BoundingSphere; //?? common
132141
CVec3 MeshOrigin;
133142
CVec3 MeshScale;
134143
FRotator RotOrigin;
135144
TArray<CSkelMeshBone> RefSkeleton;
136145
TArray<CSkelMeshLod> Lods;
146+
TArray<CMorphLod*> Morphs;
137147
TArray<CSkelMeshSocket> Sockets; //?? common (UE4 has StaticMesh sockets)
138148
const class CAnimSet* Anim;
139149

@@ -142,6 +152,14 @@ class CSkeletalMesh
142152
, Anim(NULL)
143153
{}
144154

155+
~CSkeletalMesh()
156+
{
157+
for (CMorphLod* morph : Morphs)
158+
{
159+
delete morph;
160+
}
161+
}
162+
145163
void FinalizeMesh();
146164

147165
#if RENDERING

Unreal/UnMesh.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ void UnpackNormals(const FPackedNormal SrcNormal[3], CMeshVertex &V);
2020
//?? move these declarations outside
2121
class CSkeletalMesh;
2222
struct CSkelMeshLod;
23+
struct CMorphLod;
2324
class CAnimSet;
2425
class CAnimSequence;
2526
class CStaticMesh;

Unreal/UnMesh3.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,52 @@ void FMorphTargetLODModel::Serialize3(FArchive& Ar, FMorphTargetLODModel& Lod)
9696
unguard;
9797
}
9898

99+
CMorphLod* UMorphTarget::ConvertMorph()
100+
{
101+
CMorphLod* morph = new CMorphLod;
102+
morph->Name = Name;
103+
104+
for (int lodIndex = 0; lodIndex < MorphLODModels.Num(); lodIndex++)
105+
{
106+
const FMorphTargetLODModel& SrcLod = MorphLODModels[lodIndex];
107+
int NumVerts = SrcLod.Vertices.Num();
108+
morph->Vertices.AddDefaulted(NumVerts);
109+
for (int i = 0; i < NumVerts; i++)
110+
{
111+
const FMorphTargetDelta& SV = SrcLod.Vertices[i];
112+
CMorphVertex& V = morph->Vertices[i];
113+
V.PositionDelta = CVT(SV.PositionDelta);
114+
V.NormalDelta = CVT(SV.TangentZDelta);
115+
V.VertexIndex = SV.SourceIdx;
116+
}
117+
}
118+
119+
return morph;
120+
}
121+
122+
void UMorphTargetSet::PostLoad()
123+
{
124+
guard(UMorphTargetSet::PostLoad);
125+
126+
if (BaseSkelMesh)
127+
{
128+
if (!BaseSkelMesh->ConvertedMesh)
129+
{
130+
BaseSkelMesh->PostLoad();
131+
assert(BaseSkelMesh->ConvertedMesh);
132+
}
133+
134+
for (UMorphTarget* MorphTarget : Targets)
135+
{
136+
if (MorphTarget)
137+
{
138+
BaseSkelMesh->ConvertedMesh->Morphs.Add(MorphTarget->ConvertMorph());
139+
}
140+
}
141+
}
142+
143+
unguard;
144+
}
99145

100146
/*-----------------------------------------------------------------------------
101147
USkeletalMesh
@@ -1955,6 +2001,11 @@ void USkeletalMesh3::ConvertMesh()
19552001
{
19562002
guard(USkeletalMesh3::ConvertMesh);
19572003

2004+
// We're calling ConvertMesh explicitly from UMorphTargetSet::PostLoad to ensure
2005+
// mesh is ready before we're filling morphs, so let's avoid repeating of PostLoad() ...
2006+
if (ConvertedMesh)
2007+
return;
2008+
19582009
CSkeletalMesh *Mesh = new CSkeletalMesh(this);
19592010
ConvertedMesh = Mesh;
19602011

Unreal/UnMesh3.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ class UMorphTarget : public UObject
7575
Serialize3(Ar);
7676
}
7777

78+
CMorphLod* ConvertMorph();
79+
7880
#if UNREAL4
7981
BEGIN_PROP_TABLE
8082
PROP_DROP(BaseSkelMesh)
@@ -90,6 +92,8 @@ class UMorphTargetSet : public UObject
9092
TArray<UMorphTarget*> Targets;
9193
USkeletalMesh3* BaseSkelMesh;
9294

95+
virtual void PostLoad(); // used to convert and add morphs to UE3 mesh
96+
9397
BEGIN_PROP_TABLE
9498
PROP_ARRAY(Targets, UObject*)
9599
PROP_OBJ(BaseSkelMesh)

Unreal/UnMesh4.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,6 +1753,14 @@ void USkeletalMesh4::ConvertMesh()
17531753
}
17541754
unguard; // ProcessSkeleton
17551755

1756+
for (int i = 0; i < MorphTargets.Num(); i++)
1757+
{
1758+
guard(ConvertMorph)
1759+
if (MorphTargets[i])
1760+
Mesh->Morphs.Add(MorphTargets[i]->ConvertMorph());
1761+
unguardf("%d/%d", i, MorphTargets.Num());
1762+
}
1763+
17561764
Mesh->FinalizeMesh();
17571765

17581766
unguard;

Viewers/ObjectViewer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ class CSkelMeshViewer : public CMeshViewer
153153
{
154154
public:
155155
int AnimIndex;
156+
int MorphIndex;
156157
bool IsFollowingMesh;
157158
int ShowSkel; // 0 - mesh, 1 - mesh+skel, 2 - skel only
158159
bool ShowLabels;

Viewers/SkelMeshViewer.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ CSkelMeshViewer::CSkelMeshViewer(CSkeletalMesh* Mesh0, CApplication* Window)
6060
, Mesh(Mesh0)
6161
, Anim(NULL)
6262
, AnimIndex(-1)
63+
, MorphIndex(-1)
6364
, IsFollowingMesh(false)
6465
, ShowSkel(0)
6566
, ShowLabels(false)
@@ -335,12 +336,17 @@ void CSkelMeshViewer::Draw2D()
335336
if (bIsUE4Mesh)
336337
{
337338
if (Skeleton)
338-
DrawTextLeft(S_GREEN"Skeleton: " S_WHITE "%s", Skeleton->Name);
339+
DrawTextLeft(S_GREEN "Skeleton: " S_WHITE "%s", Skeleton->Name);
339340
else
340341
DrawTextBottomLeft(S_RED"WARNING: no skeleton, animation will not work!");
341342
}
342343
#endif // UNREAL4
343344

345+
if (Mesh->Morphs.Num())
346+
{
347+
DrawTextLeft(S_GREEN "Moprhs : " S_WHITE "%d", Mesh->Morphs.Num());
348+
}
349+
344350
// mesh
345351
DrawTextLeft(S_GREEN "LOD : " S_WHITE "%d/%d\n"
346352
S_GREEN "Verts : " S_WHITE "%d\n"
@@ -410,6 +416,19 @@ void CSkelMeshViewer::Draw2D()
410416
DrawTextBottomLeft(S_GREEN "Anim:" S_WHITE " 0/%d (none)", MeshInst->GetAnimCount());
411417
}
412418
}
419+
420+
if (Mesh->Morphs.Num())
421+
{
422+
int MorphCount = Mesh->Morphs.Num();
423+
if (MorphIndex >= 0)
424+
{
425+
DrawTextBottomLeft(S_GREEN "Morph: " S_WHITE " %d/%d (%s)", MorphIndex+1, MorphCount, *Mesh->Morphs[MorphIndex]->Name);
426+
}
427+
else
428+
{
429+
DrawTextBottomLeft(S_GREEN "Morph: " S_WHITE " 0/%d (none)", MorphCount);
430+
}
431+
}
413432
}
414433

415434

@@ -622,6 +641,24 @@ void CSkelMeshViewer::ProcessKey(int key)
622641
}
623642
break;
624643

644+
case '['|KEY_CTRL:
645+
case ']'|KEY_CTRL:
646+
if (Mesh->Morphs.Num())
647+
{
648+
int NumMorphs = Mesh->Morphs.Num();
649+
if (key == ('['|KEY_CTRL))
650+
{
651+
if (--MorphIndex < -1)
652+
MorphIndex = NumMorphs - 1;
653+
}
654+
else
655+
{
656+
if (++MorphIndex >= NumMorphs)
657+
MorphIndex = -1;
658+
}
659+
}
660+
break;
661+
625662
case ',': // '<'
626663
case '.': // '>'
627664
if (NumFrames)

0 commit comments

Comments
 (0)