diff options
| author | s-ol <s+removethis@s-ol.nu> | 2021-04-09 12:59:54 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2021-04-12 12:12:40 +0000 |
| commit | 08dd1a975a33aec9dc6f18568b0d014551983b66 (patch) | |
| tree | d80edfa837137e10e3a7ac626cccfc81c650e924 | |
| parent | implement loading GLTF files from memory (diff) | |
| download | DiligentTools-gltf-c-api.tar.gz DiligentTools-gltf-c-api.zip | |
Give access to individual node transformsgltf-c-api
| -rw-r--r-- | AssetLoader/include/GLTFLoader.hpp | 54 | ||||
| -rw-r--r-- | AssetLoader/interface/GLTFLoader.h | 25 | ||||
| -rw-r--r-- | AssetLoader/src/GLTFLoader.cpp | 22 |
3 files changed, 86 insertions, 15 deletions
diff --git a/AssetLoader/include/GLTFLoader.hpp b/AssetLoader/include/GLTFLoader.hpp index 2b9afaf..9f3e10f 100644 --- a/AssetLoader/include/GLTFLoader.hpp +++ b/AssetLoader/include/GLTFLoader.hpp @@ -229,6 +229,16 @@ struct Camera float4x4 matrix; }; +struct GLTF_Transform +{ + float3 Translation; + float _pad0; + float3 Scale = float3{1, 1, 1}; + float _pad1; + Quaternion Rotation; + float4x4 Matrix; +}; + struct Node { std::string Name; @@ -237,14 +247,15 @@ struct Node std::vector<std::unique_ptr<Node>> Children; - float4x4 Matrix; std::unique_ptr<Mesh> pMesh; std::unique_ptr<Camera> pCamera; Skin* pSkin = nullptr; Int32 SkinIndex = -1; - float3 Translation; - float3 Scale = float3{1, 1, 1}; - Quaternion Rotation; + GLTF_Transform Transform; + // float3 Translation; + // float3 Scale = float3{1, 1, 1}; + // Quaternion Rotation; + // float4x4 Matrix; BoundBox BVH; BoundBox AABB; @@ -386,6 +397,41 @@ public: 0; } + virtual bool GetNodeIndex(const char* Name, Uint32* Idx) const override final + { + uint32_t i = 0; + for (auto* node : LinearNodes) + { + if (node->Name.compare(Name) == 0) + { + *Idx = i; + return true; + } + i++; + } + + return false; + } + + virtual void GetNodeTransform(Uint32 Idx, GLTF_Transform* Transform) override final + { + *Transform = LinearNodes[Idx]->Transform; + } + + virtual void SetNodeTransform(Uint32 Idx, GLTF_Transform* Transform) override final + { + LinearNodes[Idx]->Transform = *Transform; + } + + virtual void UpdateTransforms() override final + { + for (auto& root_node : Nodes) + { + root_node->UpdateTransforms(); + } + CalculateSceneDimensions(); + } + private: void LoadFromFile(IRenderDevice* pDevice, IDeviceContext* pContext, diff --git a/AssetLoader/interface/GLTFLoader.h b/AssetLoader/interface/GLTFLoader.h index 402559e..9aba237 100644 --- a/AssetLoader/interface/GLTFLoader.h +++ b/AssetLoader/interface/GLTFLoader.h @@ -46,9 +46,22 @@ DILIGENT_BEGIN_NAMESPACE(GLTF) #if DILIGENT_CPP_INTERFACE class ResourceManager; + + struct GLTF_Transform; #else struct ResourceManager; typedef struct ResourceManager ResourceManager; + + struct GLTF_Transform + { + float Translation[3]; + float _pad0; + float Scale[3]; + float _pad1; + float Rotation[4]; + float Matrix[4*4]; + }; + typedef struct GLTF_Transform GLTF_Transform; #endif struct GLTF_ResourceCacheUseInfo @@ -169,6 +182,14 @@ DILIGENT_BEGIN_INTERFACE1(IGLTFModel) VIRTUAL ITexture* METHOD(GetTexture)(THIS_ Uint32 Index) PURE; + VIRTUAL bool METHOD(GetNodeIndex)(THIS_ const char* Name, Uint32* Idx) CONST PURE; + + VIRTUAL void METHOD(GetNodeTransform)(THIS_ Uint32 Idx, GLTF_Transform* Transform) PURE; + + VIRTUAL void METHOD(SetNodeTransform)(THIS_ Uint32 Idx, GLTF_Transform* Transform) PURE; + + VIRTUAL void METHOD(UpdateTransforms)(THIS) PURE; + VIRTUAL Uint32 METHOD(GetFirstIndexLocation)(THIS) CONST PURE; VIRTUAL Uint32 METHOD(GetBaseVertex)(THIS) CONST PURE; @@ -185,6 +206,10 @@ DILIGENT_END_INTERFACE # define IGLTFModel_Transform(This, ...) CALL_IFACE_METHOD(GLTF_Model, Transform, This, __VA_ARGS__) # define IGLTFModel_GetBuffer(This, ...) CALL_IFACE_METHOD(GLTF_Model, GetBuffer, This, __VA_ARGS__) # define IGLTFModel_GetTexture(This, ...) CALL_IFACE_METHOD(GLTF_Model, GetTexture, This, __VA_ARGS__) +# define IGLTFModel_GetNodeIndex(This, ...) CALL_IFACE_METHOD(GLTF_Model, GetNodeIndex, This, __VA_ARGS__) +# define IGLTFModel_GetNodeTransform(This, ...) CALL_IFACE_METHOD(GLTF_Model, GetNodeTransform, This, __VA_ARGS__) +# define IGLTFModel_SetNodeTransform(This, ...) CALL_IFACE_METHOD(GLTF_Model, SetNodeTransform, This, __VA_ARGS__) +# define IGLTFModel_UpdateTransforms(This) CALL_IFACE_METHOD(GLTF_Model, UpdateTransforms, This) # define IGLTFModel_GetFirstIndexLocation(This) CALL_IFACE_METHOD(GLTF_Model, GetFirstIndexLocation, This) # define IGLTFModel_GetBaseVertex(This) CALL_IFACE_METHOD(GLTF_Model, GetBaseVertex, This) diff --git a/AssetLoader/src/GLTFLoader.cpp b/AssetLoader/src/GLTFLoader.cpp index 9fabac2..9d370f5 100644 --- a/AssetLoader/src/GLTFLoader.cpp +++ b/AssetLoader/src/GLTFLoader.cpp @@ -197,7 +197,7 @@ float4x4 Node::LocalMatrix() const // Translation, rotation, and scale properties and local space transformation are // mutually exclusive in GLTF. // We, however, may use non-trivial Matrix with TRS to apply transform to a model. - return float4x4::Scale(Scale) * Rotation.ToMatrix() * float4x4::Translation(Translation) * Matrix; + return float4x4::Scale(Transform.Scale) * Transform.Rotation.ToMatrix() * float4x4::Translation(Transform.Translation) * Transform.Matrix; } float4x4 Node::GetMatrix() const @@ -276,7 +276,7 @@ void Model::LoadNode(Node* parent, NewNode->Parent = parent; NewNode->Name = gltf_node.name; NewNode->SkinIndex = gltf_node.skin; - NewNode->Matrix = float4x4::Identity(); + NewNode->Transform.Matrix = float4x4::Identity(); // Any node can define a local space transformation either by supplying a matrix property, // or any of translation, rotation, and scale properties (also known as TRS properties). @@ -285,23 +285,23 @@ void Model::LoadNode(Node* parent, //float3 Translation; if (gltf_node.translation.size() == 3) { - NewNode->Translation = float3::MakeVector(gltf_node.translation.data()); + NewNode->Transform.Translation = float3::MakeVector(gltf_node.translation.data()); } if (gltf_node.rotation.size() == 4) { - NewNode->Rotation.q = float4::MakeVector(gltf_node.rotation.data()); + NewNode->Transform.Rotation.q = float4::MakeVector(gltf_node.rotation.data()); //NewNode->rotation = glm::mat4(q); } if (gltf_node.scale.size() == 3) { - NewNode->Scale = float3::MakeVector(gltf_node.scale.data()); + NewNode->Transform.Scale = float3::MakeVector(gltf_node.scale.data()); } if (gltf_node.matrix.size() == 16) { - NewNode->Matrix = float4x4::MakeMatrix(gltf_node.matrix.data()); + NewNode->Transform.Matrix = float4x4::MakeMatrix(gltf_node.matrix.data()); } // Node with children @@ -318,7 +318,7 @@ void Model::LoadNode(Node* parent, if (gltf_node.mesh >= 0) { const tinygltf::Mesh& gltf_mesh = gltf_model.meshes[gltf_node.mesh]; - std::unique_ptr<Mesh> pNewMesh{new Mesh{NewNode->Matrix}}; + std::unique_ptr<Mesh> pNewMesh{new Mesh{NewNode->Transform.Matrix}}; for (size_t j = 0; j < gltf_mesh.primitives.size(); j++) { const tinygltf::Primitive& primitive = gltf_mesh.primitives[j]; @@ -2017,14 +2017,14 @@ void Model::UpdateAnimation(Uint32 index, float time) case AnimationChannel::PATH_TYPE::TRANSLATION: { float4 trans = lerp(sampler.OutputsVec4[i], sampler.OutputsVec4[i + 1], u); - channel.pNode->Translation = float3(trans); + channel.pNode->Transform.Translation = float3(trans); break; } case AnimationChannel::PATH_TYPE::SCALE: { float4 scale = lerp(sampler.OutputsVec4[i], sampler.OutputsVec4[i + 1], u); - channel.pNode->Scale = float3(scale); + channel.pNode->Transform.Scale = float3(scale); break; } @@ -2042,7 +2042,7 @@ void Model::UpdateAnimation(Uint32 index, float time) q2.q.z = sampler.OutputsVec4[i + 1].z; q2.q.w = sampler.OutputsVec4[i + 1].w; - channel.pNode->Rotation = normalize(slerp(q1, q2, u)); + channel.pNode->Transform.Rotation = normalize(slerp(q1, q2, u)); break; } } @@ -2066,7 +2066,7 @@ void Model::Transform(const float* _Matrix) auto Matrix = float4x4::MakeMatrix(_Matrix); for (auto& root_node : Nodes) { - root_node->Matrix *= Matrix; + root_node->Transform.Matrix *= Matrix; root_node->UpdateTransforms(); } |
