Give access to individual node transforms
s-ol
2 years ago
228 | 228 | float4x4 matrix; |
229 | 229 | }; |
230 | 230 | |
231 | struct GLTF_Transform | |
232 | { | |
233 | float3 Translation; | |
234 | float _pad0; | |
235 | float3 Scale = float3{1, 1, 1}; | |
236 | float _pad1; | |
237 | Quaternion Rotation; | |
238 | float4x4 Matrix; | |
239 | }; | |
240 | ||
231 | 241 | struct Node |
232 | 242 | { |
233 | 243 | std::string Name; |
236 | 246 | |
237 | 247 | std::vector<std::unique_ptr<Node>> Children; |
238 | 248 | |
239 | float4x4 Matrix; | |
240 | 249 | std::unique_ptr<Mesh> pMesh; |
241 | 250 | std::unique_ptr<Camera> pCamera; |
242 | 251 | Skin* pSkin = nullptr; |
243 | 252 | Int32 SkinIndex = -1; |
244 | float3 Translation; | |
245 | float3 Scale = float3{1, 1, 1}; | |
246 | Quaternion Rotation; | |
253 | GLTF_Transform Transform; | |
254 | // float3 Translation; | |
255 | // float3 Scale = float3{1, 1, 1}; | |
256 | // Quaternion Rotation; | |
257 | // float4x4 Matrix; | |
247 | 258 | BoundBox BVH; |
248 | 259 | BoundBox AABB; |
249 | 260 | |
383 | 394 | return VertBuff.pSuballocation ? |
384 | 395 | static_cast<Uint32>(VertBuff.pSuballocation->GetOffset() / sizeof(VertexBasicAttribs)) : |
385 | 396 | 0; |
397 | } | |
398 | ||
399 | virtual bool GetNodeIndex(const char* Name, Uint32* Idx) const override final | |
400 | { | |
401 | uint32_t i = 0; | |
402 | for (auto* node : LinearNodes) | |
403 | { | |
404 | if (node->Name.compare(Name) == 0) | |
405 | { | |
406 | *Idx = i; | |
407 | return true; | |
408 | } | |
409 | i++; | |
410 | } | |
411 | ||
412 | return false; | |
413 | } | |
414 | ||
415 | virtual void GetNodeTransform(Uint32 Idx, GLTF_Transform* Transform) override final | |
416 | { | |
417 | *Transform = LinearNodes[Idx]->Transform; | |
418 | } | |
419 | ||
420 | virtual void SetNodeTransform(Uint32 Idx, GLTF_Transform* Transform) override final | |
421 | { | |
422 | LinearNodes[Idx]->Transform = *Transform; | |
423 | } | |
424 | ||
425 | virtual void UpdateTransforms() override final | |
426 | { | |
427 | for (auto& root_node : Nodes) | |
428 | { | |
429 | root_node->UpdateTransforms(); | |
430 | } | |
431 | CalculateSceneDimensions(); | |
386 | 432 | } |
387 | 433 | |
388 | 434 | private: |
45 | 45 | |
46 | 46 | #if DILIGENT_CPP_INTERFACE |
47 | 47 | class ResourceManager; |
48 | ||
49 | struct GLTF_Transform; | |
48 | 50 | #else |
49 | 51 | struct ResourceManager; |
50 | 52 | typedef struct ResourceManager ResourceManager; |
53 | ||
54 | struct GLTF_Transform | |
55 | { | |
56 | float Translation[3]; | |
57 | float _pad0; | |
58 | float Scale[3]; | |
59 | float _pad1; | |
60 | float Rotation[4]; | |
61 | float Matrix[4*4]; | |
62 | }; | |
63 | typedef struct GLTF_Transform GLTF_Transform; | |
51 | 64 | #endif |
52 | 65 | |
53 | 66 | struct GLTF_ResourceCacheUseInfo |
167 | 180 | VIRTUAL IBuffer* METHOD(GetBuffer)(THIS_ GLTF_BUFFER_ID BuffId) PURE; |
168 | 181 | |
169 | 182 | VIRTUAL ITexture* METHOD(GetTexture)(THIS_ Uint32 Index) PURE; |
183 | ||
184 | VIRTUAL bool METHOD(GetNodeIndex)(THIS_ const char* Name, Uint32* Idx) CONST PURE; | |
185 | ||
186 | VIRTUAL void METHOD(GetNodeTransform)(THIS_ Uint32 Idx, GLTF_Transform* Transform) PURE; | |
187 | ||
188 | VIRTUAL void METHOD(SetNodeTransform)(THIS_ Uint32 Idx, GLTF_Transform* Transform) PURE; | |
189 | ||
190 | VIRTUAL void METHOD(UpdateTransforms)(THIS) PURE; | |
170 | 191 | |
171 | 192 | VIRTUAL Uint32 METHOD(GetFirstIndexLocation)(THIS) CONST PURE; |
172 | 193 | |
184 | 205 | # define IGLTFModel_Transform(This, ...) CALL_IFACE_METHOD(GLTF_Model, Transform, This, __VA_ARGS__) |
185 | 206 | # define IGLTFModel_GetBuffer(This, ...) CALL_IFACE_METHOD(GLTF_Model, GetBuffer, This, __VA_ARGS__) |
186 | 207 | # define IGLTFModel_GetTexture(This, ...) CALL_IFACE_METHOD(GLTF_Model, GetTexture, This, __VA_ARGS__) |
208 | # define IGLTFModel_GetNodeIndex(This, ...) CALL_IFACE_METHOD(GLTF_Model, GetNodeIndex, This, __VA_ARGS__) | |
209 | # define IGLTFModel_GetNodeTransform(This, ...) CALL_IFACE_METHOD(GLTF_Model, GetNodeTransform, This, __VA_ARGS__) | |
210 | # define IGLTFModel_SetNodeTransform(This, ...) CALL_IFACE_METHOD(GLTF_Model, SetNodeTransform, This, __VA_ARGS__) | |
211 | # define IGLTFModel_UpdateTransforms(This) CALL_IFACE_METHOD(GLTF_Model, UpdateTransforms, This) | |
187 | 212 | # define IGLTFModel_GetFirstIndexLocation(This) CALL_IFACE_METHOD(GLTF_Model, GetFirstIndexLocation, This) |
188 | 213 | # define IGLTFModel_GetBaseVertex(This) CALL_IFACE_METHOD(GLTF_Model, GetBaseVertex, This) |
189 | 214 |
196 | 196 | // Translation, rotation, and scale properties and local space transformation are |
197 | 197 | // mutually exclusive in GLTF. |
198 | 198 | // We, however, may use non-trivial Matrix with TRS to apply transform to a model. |
199 | return float4x4::Scale(Scale) * Rotation.ToMatrix() * float4x4::Translation(Translation) * Matrix; | |
199 | return float4x4::Scale(Transform.Scale) * Transform.Rotation.ToMatrix() * float4x4::Translation(Transform.Translation) * Transform.Matrix; | |
200 | 200 | } |
201 | 201 | |
202 | 202 | float4x4 Node::GetMatrix() const |
275 | 275 | NewNode->Parent = parent; |
276 | 276 | NewNode->Name = gltf_node.name; |
277 | 277 | NewNode->SkinIndex = gltf_node.skin; |
278 | NewNode->Matrix = float4x4::Identity(); | |
278 | NewNode->Transform.Matrix = float4x4::Identity(); | |
279 | 279 | |
280 | 280 | // Any node can define a local space transformation either by supplying a matrix property, |
281 | 281 | // or any of translation, rotation, and scale properties (also known as TRS properties). |
284 | 284 | //float3 Translation; |
285 | 285 | if (gltf_node.translation.size() == 3) |
286 | 286 | { |
287 | NewNode->Translation = float3::MakeVector(gltf_node.translation.data()); | |
287 | NewNode->Transform.Translation = float3::MakeVector(gltf_node.translation.data()); | |
288 | 288 | } |
289 | 289 | |
290 | 290 | if (gltf_node.rotation.size() == 4) |
291 | 291 | { |
292 | NewNode->Rotation.q = float4::MakeVector(gltf_node.rotation.data()); | |
292 | NewNode->Transform.Rotation.q = float4::MakeVector(gltf_node.rotation.data()); | |
293 | 293 | //NewNode->rotation = glm::mat4(q); |
294 | 294 | } |
295 | 295 | |
296 | 296 | if (gltf_node.scale.size() == 3) |
297 | 297 | { |
298 | NewNode->Scale = float3::MakeVector(gltf_node.scale.data()); | |
298 | NewNode->Transform.Scale = float3::MakeVector(gltf_node.scale.data()); | |
299 | 299 | } |
300 | 300 | |
301 | 301 | if (gltf_node.matrix.size() == 16) |
302 | 302 | { |
303 | NewNode->Matrix = float4x4::MakeMatrix(gltf_node.matrix.data()); | |
303 | NewNode->Transform.Matrix = float4x4::MakeMatrix(gltf_node.matrix.data()); | |
304 | 304 | } |
305 | 305 | |
306 | 306 | // Node with children |
317 | 317 | if (gltf_node.mesh >= 0) |
318 | 318 | { |
319 | 319 | const tinygltf::Mesh& gltf_mesh = gltf_model.meshes[gltf_node.mesh]; |
320 | std::unique_ptr<Mesh> pNewMesh{new Mesh{NewNode->Matrix}}; | |
320 | std::unique_ptr<Mesh> pNewMesh{new Mesh{NewNode->Transform.Matrix}}; | |
321 | 321 | for (size_t j = 0; j < gltf_mesh.primitives.size(); j++) |
322 | 322 | { |
323 | 323 | const tinygltf::Primitive& primitive = gltf_mesh.primitives[j]; |
2016 | 2016 | case AnimationChannel::PATH_TYPE::TRANSLATION: |
2017 | 2017 | { |
2018 | 2018 | float4 trans = lerp(sampler.OutputsVec4[i], sampler.OutputsVec4[i + 1], u); |
2019 | channel.pNode->Translation = float3(trans); | |
2019 | channel.pNode->Transform.Translation = float3(trans); | |
2020 | 2020 | break; |
2021 | 2021 | } |
2022 | 2022 | |
2023 | 2023 | case AnimationChannel::PATH_TYPE::SCALE: |
2024 | 2024 | { |
2025 | 2025 | float4 scale = lerp(sampler.OutputsVec4[i], sampler.OutputsVec4[i + 1], u); |
2026 | channel.pNode->Scale = float3(scale); | |
2026 | channel.pNode->Transform.Scale = float3(scale); | |
2027 | 2027 | break; |
2028 | 2028 | } |
2029 | 2029 | |
2041 | 2041 | q2.q.z = sampler.OutputsVec4[i + 1].z; |
2042 | 2042 | q2.q.w = sampler.OutputsVec4[i + 1].w; |
2043 | 2043 | |
2044 | channel.pNode->Rotation = normalize(slerp(q1, q2, u)); | |
2044 | channel.pNode->Transform.Rotation = normalize(slerp(q1, q2, u)); | |
2045 | 2045 | break; |
2046 | 2046 | } |
2047 | 2047 | } |
2065 | 2065 | auto Matrix = float4x4::MakeMatrix(_Matrix); |
2066 | 2066 | for (auto& root_node : Nodes) |
2067 | 2067 | { |
2068 | root_node->Matrix *= Matrix; | |
2068 | root_node->Transform.Matrix *= Matrix; | |
2069 | 2069 | root_node->UpdateTransforms(); |
2070 | 2070 | } |
2071 | 2071 |