Polyphase Game Engine
Loading...
Searching...
No Matches
SkeletalMesh.h
Go to the documentation of this file.
1#pragma once
2
3#include <string>
4
5#include "Assets/Material.h"
6#include "Asset.h"
7#include "Vertex.h"
8#include "Constants.h"
9
10#include "Graphics/Graphics.h"
13
14#include "Maths.h"
15
16#if EDITOR
17#include <assimp/scene.h>
18#endif
19
20struct Bone
21{
22 std::string mName;
23 int32_t mIndex = -1;
24 int32_t mParentIndex = -1;
25 glm::mat4 mOffsetMatrix = { };
26 glm::mat4 mInvOffsetMatrix = { };
27};
28
30{
31 float mTime = 0.0f;
32 glm::vec3 mValue = {};
33};
34
36{
37 float mTime = 0.0f;
38 glm::quat mValue = {};
39};
40
42{
43 float mTime = 0.0f;
44 glm::vec3 mValue = {};
45};
46
48{
49 float mTime = 0.0f;
50 glm::vec3 mValue = {};
51};
52
54{
55 std::string mName;
56 std::vector<AnimEventKey> mEventKeys;
57};
58
60{
62 std::string mName;
63 std::string mAnimation;
64 float mTime = 0.0f;
65 glm::vec3 mValue = {};
66};
67
68struct Channel
69{
70 int32_t mBoneIndex = -1;
71 std::vector<PositionKey> mPositionKeys;
72 std::vector<RotationKey> mRotationKeys;
73 std::vector<ScaleKey> mScaleKeys;
74};
75
77{
78 std::string mName;
79 float mDuration = 0.0f;
80 float mTicksPerSecond = 0.0f;
81 std::vector<Channel> mChannels;
82 std::vector<AnimEventTrack> mEventTracks;
83};
84
85// Contiguous range inside the SkeletalMesh's shared vertex/index buffers
86// that should be drawn with its own material. One section per source aiMesh
87// when the mesh was imported with "combineMeshes".
89{
90 std::string mName;
91 uint32_t mFirstIndex = 0;
92 uint32_t mIndexCount = 0;
93 uint32_t mBaseVertex = 0;
94 uint32_t mVertexCount = 0;
96};
97
98// A named attachment point on the skeleton: a bone plus a constant local offset.
99// Authored once per rig so props (swords, shields, muzzle flashes) get consistent
100// placement without every instance hand-tuning its own transform.
101//
102// Keyed by bone NAME rather than index, like BoneMaskAsset, so re-importing a mesh
103// with a different bone order doesn't silently relocate everything attached to it.
105{
106 std::string mName;
107 std::string mBoneName;
108 glm::vec3 mPosition = { 0.0f, 0.0f, 0.0f };
109 glm::vec3 mRotation = { 0.0f, 0.0f, 0.0f }; // euler degrees
110 glm::vec3 mScale = { 1.0f, 1.0f, 1.0f };
111};
112
114{
115public:
116
118
119 SkeletalMesh();
121
122 SkeletalMeshResource* GetResource();
123
124 // Asset Interface
125 virtual void LoadStream(Stream& stream, Platform platform) override;
126 virtual void SaveStream(Stream& stream, Platform platform) override;
127 virtual void Create() override;
128 virtual void Destroy() override;
129 virtual bool Import(const std::string& path, ImportOptions* options) override;
130 virtual void GatherProperties(std::vector<Property>& outProps) override;
131 virtual glm::vec4 GetTypeColor() override;
132 virtual const char* GetTypeName() override;
133 virtual const char* GetTypeImportExt() override;
134
135 class Material* GetMaterial();
136 void SetMaterial(class Material* newMaterial);
137
138 // Multi-section accessors. A legacy single-material mesh appears as one
139 // implicit section named "Default" covering the entire index range.
140 uint32_t GetNumSections() const;
141 const SkeletalMeshSection& GetSection(uint32_t index) const;
142 SkeletalMeshSection& GetSectionMutable(uint32_t index);
143 class Material* GetSectionMaterial(uint32_t index) const;
144 void SetSectionMaterial(uint32_t index, class Material* material);
145 int32_t FindSectionIndex(const std::string& name) const;
146 const std::vector<SkeletalMeshSection>& GetSections() const;
147
148 uint32_t GetNumIndices();
149 uint32_t GetNumFaces();
150 uint32_t GetNumVertices();
151
152 const IndexType* GetIndices() const;
153
154 int32_t FindBoneIndex(const std::string& name) const;
155 const std::vector<Bone>& GetBones() const;
156 const Bone& GetBone(int32_t index) const;
157 uint32_t GetNumBones() const;
158
159 // Named attachment points. See MeshSocket.
160 uint32_t GetNumSockets() const;
161 const MeshSocket& GetSocket(uint32_t index) const;
162 MeshSocket& GetSocketMutable(uint32_t index);
163 const std::vector<MeshSocket>& GetSockets() const;
164 int32_t FindSocketIndex(const std::string& name) const;
165 // Returns the index of the added socket. The name is uniquified if it collides.
166 uint32_t AddSocket(const MeshSocket& socket);
167 void RemoveSocket(uint32_t index);
168 // The socket's constant offset relative to its bone, as a matrix.
169 glm::mat4 GetSocketLocalMatrix(uint32_t index) const;
170
171 glm::mat4 GetInvRootTransform() const;
172
173 const std::vector<Animation>& GetAnimations() const;
174 const Animation* GetAnimation(const char* name);
175
176 // Get length of animation in seconds
177 float GetAnimationDuration(const char* name);
178
179 const std::vector<VertexSkinned>& GetVertices() const;
180
181 void FinalizeBoneTransforms(std::vector<glm::mat4>& inoutTransforms);
182
183 void CopyBindPose(std::vector<glm::mat4>& outTransforms);
184
185 // Decomposed local-bind TRS, cached in InitBindPose. Used by
186 // SkeletalMesh3D's blend loop to seed bones from bind pose before
187 // accumulating animation layers, so masked-out bones in lower slots
188 // and unmasked bones in upper slots both blend against a known pose.
189 const glm::vec3& GetBindPosePos(int32_t boneIndex) const;
190 const glm::quat& GetBindPoseRot(int32_t boneIndex) const;
191 const glm::vec3& GetBindPoseScale(int32_t boneIndex) const;
192
193 // Mark every bone in [rootIndex, descendants...] in outBitset (size = numBones).
194 // Exploits the parent-before-child DFS order produced by SetupBoneHierarchy.
195 void GatherDescendants(int32_t rootIndex, std::vector<uint8_t>& outBitset, bool includeRoot = true) const;
196
197 // Resolve an include/exclude subtree spec into a per-bone bitset. Unknown
198 // bone names are skipped (caller logs). selfOnly = include only the named
199 // bones without recursing.
200 void GatherSubtreeBoneSet(
201 const std::vector<std::string>& includes,
202 const std::vector<std::string>& excludes,
203 bool selfOnly,
204 std::vector<uint8_t>& outBitset) const;
205
206 Bounds GetBounds() const;
207 AABB GetAABB() const;
208 // Exact bind-pose box from the vertices, without the Bounds Scale
209 // padding GetAABB() applies. Use for placement/fitting, not culling.
210 AABB GetBindPoseAABB() const { return mAABB; }
211
212 const glm::mat4 GetBindPoseMatrix(int32_t boneIndex) const;
213
214 SkeletalMesh* GetAnimationLookupMesh();
215 void SetAnimationLookupMesh(SkeletalMesh* lookupMesh);
216
217 static bool HandlePropChange(Datum* datum, uint32_t index, const void* newValue);
218
219private:
220
221 void InitBindPose();
222 void ComputeBounds();
223
224 MaterialRef mMaterial;
225 SkeletalMeshRef mAnimationLookupMesh;
226 uint32_t mNumVertices;
227 uint32_t mNumIndices;
228 uint32_t mNumUvMaps;
229
230 std::vector<Bone> mBones;
231 std::vector<Animation> mAnimations;
232 std::vector<VertexSkinned> mVertices;
233 std::vector<SkeletalMeshSection> mSections;
234 std::vector<MeshSocket> mSockets;
235
236 glm::mat4 mInvRootTransform;
237 std::vector<glm::mat4> mBindPoseMatrices;
238 // Decomposed local-bind TRS, parallel to mBindPoseMatrices. Populated by
239 // InitBindPose. Zero-sized while bones haven't been initialised.
240 std::vector<glm::vec3> mBindPoseDecompPos;
241 std::vector<glm::quat> mBindPoseDecompRot;
242 std::vector<glm::vec3> mBindPoseDecompScale;
243 std::vector<IndexType> mIndices;
244
245 Bounds mBounds;
246
247 // Bind-pose AABB derived from vertex positions in ComputeBounds().
248 // Intentionally NOT serialized -- Create() recomputes bounds on every load.
249 AABB mAABB;
250
251 float mBoundsScale = 1.1f;
252
253 // Graphics Resource
254 SkeletalMeshResource mResource;
255
256#if EDITOR
257public:
258 void Create(const aiScene& scene,
259 const aiMesh& meshData,
260 std::vector<Material>* materials = nullptr);
261
262 void SetupBoneHierarchy(
263 const aiNode& node,
264 const aiMesh& meshData,
265 std::vector<uint8_t>& boneIndices,
266 std::vector<float>& boneWeights,
267 int32_t parentBoneIndex);
268
269 void SetupAnimations(const aiScene& scene);
270 void SetupResource(const aiMesh& meshData,
271 const std::vector<float>& boneWeights,
272 const std::vector<uint8_t>& boneIndices);
273
274 void CreateCombined(const aiScene& scene,
275 const std::vector<const aiMesh*>& renderMeshes);
276#endif // EDITOR
277};
Platform
Definition EngineTypes.h:32
uint16_t IndexType
Definition GraphicsTypes.h:122
#define POLYPHASE_API
Definition PolyphaseAPI.h:31
Bounds ComputeBounds(const std::vector< T > &vertices)
Definition Utilities.h:158
Definition AssetRef.h:18
Definition Asset.h:125
virtual bool Import(const std::string &path, ImportOptions *options=nullptr)
Definition Asset.cpp:342
virtual void Create()
Definition Asset.cpp:78
virtual void SaveStream(Stream &stream, Platform platform)
Definition Asset.cpp:334
virtual glm::vec4 GetTypeColor()
Definition Asset.cpp:352
virtual const char * GetTypeImportExt()
Definition Asset.cpp:362
virtual const char * GetTypeName()
Definition Asset.cpp:357
virtual void GatherProperties(std::vector< Property > &outProps) override
Definition Asset.cpp:347
virtual void LoadStream(Stream &stream, Platform platform)
Definition Asset.cpp:320
virtual void Destroy()
Definition Asset.cpp:93
Definition Datum.h:169
Definition Asset.h:114
Definition Material.h:48
Definition SkeletalMesh3d.h:129
Definition SkeletalMesh.h:114
AABB GetBindPoseAABB() const
Definition SkeletalMesh.h:210
DECLARE_ASSET(SkeletalMesh, Asset)
Definition Stream.h:21
Definition EngineTypes.h:213
Definition SkeletalMesh.h:48
float mTime
Definition SkeletalMesh.h:49
glm::vec3 mValue
Definition SkeletalMesh.h:50
Definition SkeletalMesh.h:54
std::string mName
Definition SkeletalMesh.h:55
std::vector< AnimEventKey > mEventKeys
Definition SkeletalMesh.h:56
Definition SkeletalMesh.h:60
SkeletalMesh3D * mNode
Definition SkeletalMesh.h:61
float mTime
Definition SkeletalMesh.h:64
std::string mAnimation
Definition SkeletalMesh.h:63
glm::vec3 mValue
Definition SkeletalMesh.h:65
std::string mName
Definition SkeletalMesh.h:62
Definition SkeletalMesh.h:77
std::string mName
Definition SkeletalMesh.h:78
std::vector< Channel > mChannels
Definition SkeletalMesh.h:81
float mTicksPerSecond
Definition SkeletalMesh.h:80
std::vector< AnimEventTrack > mEventTracks
Definition SkeletalMesh.h:82
float mDuration
Definition SkeletalMesh.h:79
Definition SkeletalMesh.h:21
glm::mat4 mInvOffsetMatrix
Definition SkeletalMesh.h:26
glm::mat4 mOffsetMatrix
Definition SkeletalMesh.h:25
std::string mName
Definition SkeletalMesh.h:22
int32_t mIndex
Definition SkeletalMesh.h:23
int32_t mParentIndex
Definition SkeletalMesh.h:24
Definition EngineTypes.h:204
Definition SkeletalMesh.h:69
std::vector< ScaleKey > mScaleKeys
Definition SkeletalMesh.h:73
int32_t mBoneIndex
Definition SkeletalMesh.h:70
std::vector< PositionKey > mPositionKeys
Definition SkeletalMesh.h:71
std::vector< RotationKey > mRotationKeys
Definition SkeletalMesh.h:72
Definition SkeletalMesh.h:105
std::string mName
Definition SkeletalMesh.h:106
glm::vec3 mPosition
Definition SkeletalMesh.h:108
glm::vec3 mScale
Definition SkeletalMesh.h:110
glm::vec3 mRotation
Definition SkeletalMesh.h:109
std::string mBoneName
Definition SkeletalMesh.h:107
Definition SkeletalMesh.h:30
glm::vec3 mValue
Definition SkeletalMesh.h:32
float mTime
Definition SkeletalMesh.h:31
Definition SkeletalMesh.h:36
glm::quat mValue
Definition SkeletalMesh.h:38
float mTime
Definition SkeletalMesh.h:37
Definition SkeletalMesh.h:42
float mTime
Definition SkeletalMesh.h:43
glm::vec3 mValue
Definition SkeletalMesh.h:44
Definition GraphicsTypes.h:198
Definition SkeletalMesh.h:89
std::string mName
Definition SkeletalMesh.h:90
MaterialRef mMaterial
Definition SkeletalMesh.h:95
uint32_t mBaseVertex
Definition SkeletalMesh.h:93
uint32_t mVertexCount
Definition SkeletalMesh.h:94
uint32_t mIndexCount
Definition SkeletalMesh.h:92
uint32_t mFirstIndex
Definition SkeletalMesh.h:91