Utility: Add a better way to attach objects to joints

This commit is contained in:
SirLynix 2022-08-30 18:31:04 +02:00
parent 45c947faf1
commit 7949c57f16
9 changed files with 67 additions and 20 deletions

View File

@ -167,17 +167,17 @@ int main()
} }
}*/ }*/
entt::entity bobEntity = registry.create(); entt::handle bobEntity = entt::handle(registry, registry.create());
{ {
auto& bobNode = registry.emplace<Nz::NodeComponent>(bobEntity); auto& bobNode = bobEntity.emplace<Nz::NodeComponent>();
//bobNode.SetRotation(Nz::EulerAnglesf(-90.f, -90.f, 0.f)); //bobNode.SetRotation(Nz::EulerAnglesf(-90.f, -90.f, 0.f));
//bobNode.SetScale(1.f / 40.f * 0.5f); //bobNode.SetScale(1.f / 40.f * 0.5f);
//bobNode.SetPosition(bobNode.GetScale() * Nz::Vector3f(0.f, -bobAABB.height / 2.f + bobAABB.y, 0.f)); //bobNode.SetPosition(bobNode.GetScale() * Nz::Vector3f(0.f, -bobAABB.height / 2.f + bobAABB.y, 0.f));
auto& bobGfx = registry.emplace<Nz::GraphicsComponent>(bobEntity); auto& bobGfx = bobEntity.emplace<Nz::GraphicsComponent>();
bobGfx.AttachRenderable(bobModel, 0xFFFFFFFF); bobGfx.AttachRenderable(bobModel, 0xFFFFFFFF);
auto& sharedSkeleton = registry.emplace<Nz::SharedSkeletonComponent>(bobEntity, skeleton); auto& sharedSkeleton = bobEntity.emplace<Nz::SharedSkeletonComponent>(skeleton);
entt::entity sphereEntity = registry.create(); entt::entity sphereEntity = registry.create();
@ -219,7 +219,7 @@ int main()
auto& sphereNode = registry.emplace<Nz::NodeComponent>(sphereEntity); auto& sphereNode = registry.emplace<Nz::NodeComponent>(sphereEntity);
sphereNode.SetScale(0.1f); sphereNode.SetScale(0.1f);
sphereNode.SetInheritScale(false); sphereNode.SetInheritScale(false);
sphereNode.SetParent(sharedSkeleton.GetAttachedJoint(83)); sphereNode.SetParentJoint(bobEntity, "RightHand");
auto& sphereBody = registry.emplace<Nz::RigidBody3DComponent>(sphereEntity, &physSytem.GetPhysWorld()); auto& sphereBody = registry.emplace<Nz::RigidBody3DComponent>(sphereEntity, &physSytem.GetPhysWorld());
sphereBody.SetGeom(std::make_shared<Nz::SphereCollider3D>(0.1f)); sphereBody.SetGeom(std::make_shared<Nz::SphereCollider3D>(0.1f));
@ -230,7 +230,7 @@ int main()
entt::entity smallBobEntity = registry.create(); entt::entity smallBobEntity = registry.create();
auto& smallBobNode = registry.emplace<Nz::NodeComponent>(smallBobEntity); auto& smallBobNode = registry.emplace<Nz::NodeComponent>(smallBobEntity);
smallBobNode.SetParent(sharedSkeleton.GetAttachedJoint(59)); smallBobNode.SetParentJoint(bobEntity, "LeftHand");
auto& smallBobGfx = registry.emplace<Nz::GraphicsComponent>(smallBobEntity); auto& smallBobGfx = registry.emplace<Nz::GraphicsComponent>(smallBobEntity);
smallBobGfx.AttachRenderable(bobModel, 0xFFFFFFFF); smallBobGfx.AttachRenderable(bobModel, 0xFFFFFFFF);

View File

@ -22,6 +22,8 @@ namespace Nz
~NodeComponent() = default; ~NodeComponent() = default;
void SetParent(entt::handle entity, bool keepDerived = false); void SetParent(entt::handle entity, bool keepDerived = false);
void SetParentJoint(entt::handle entity, const std::string& jointName, bool keepDerived = false);
void SetParentJoint(entt::handle entity, std::size_t jointIndex, bool keepDerived = false);
using Node::SetParent; using Node::SetParent;
NodeComponent& operator=(const NodeComponent&) = default; NodeComponent& operator=(const NodeComponent&) = default;

View File

@ -23,12 +23,11 @@ namespace Nz
SharedSkeletonComponent(SharedSkeletonComponent&& sharedSkeletalComponent) noexcept; SharedSkeletonComponent(SharedSkeletonComponent&& sharedSkeletalComponent) noexcept;
~SharedSkeletonComponent() = default; ~SharedSkeletonComponent() = default;
const Joint& GetAttachedJoint(std::size_t jointIndex) const override;
SharedSkeletonComponent& operator=(const SharedSkeletonComponent& sharedSkeletalComponent); SharedSkeletonComponent& operator=(const SharedSkeletonComponent& sharedSkeletalComponent);
SharedSkeletonComponent& operator=(SharedSkeletonComponent&& sharedSkeletalComponent) noexcept; SharedSkeletonComponent& operator=(SharedSkeletonComponent&& sharedSkeletalComponent) noexcept;
private: private:
const Skeleton& GetAttachedSkeleton() const override;
inline bool IsAttachedSkeletonOutdated() const; inline bool IsAttachedSkeletonOutdated() const;
void OnReferenceJointsInvalidated(const Skeleton* skeleton); void OnReferenceJointsInvalidated(const Skeleton* skeleton);
void SetSkeletonParent(Node* parent); void SetSkeletonParent(Node* parent);

View File

@ -23,11 +23,13 @@ namespace Nz
SkeletonComponent(SkeletonComponent&& skeletalComponent) noexcept = default; SkeletonComponent(SkeletonComponent&& skeletalComponent) noexcept = default;
~SkeletonComponent() = default; ~SkeletonComponent() = default;
const Joint& GetAttachedJoint(std::size_t jointIndex) const override;
Node* GetRootNode(); Node* GetRootNode();
SkeletonComponent& operator=(const SkeletonComponent&) = delete; SkeletonComponent& operator=(const SkeletonComponent&) = delete;
SkeletonComponent& operator=(SkeletonComponent&& skeletalComponent) noexcept = default; SkeletonComponent& operator=(SkeletonComponent&& skeletalComponent) noexcept = default;
private:
const Skeleton& GetAttachedSkeleton() const override;
}; };
} }

View File

@ -20,7 +20,9 @@ namespace Nz
SkeletonComponentBase(SkeletonComponentBase&&) noexcept = default; SkeletonComponentBase(SkeletonComponentBase&&) noexcept = default;
~SkeletonComponentBase() = default; ~SkeletonComponentBase() = default;
virtual const Joint& GetAttachedJoint(std::size_t jointIndex) const = 0; inline std::size_t FindJointByName(const std::string& jointName) const;
inline const Joint& GetAttachedJoint(std::size_t jointIndex) const;
inline const std::shared_ptr<Skeleton>& GetSkeleton() const; inline const std::shared_ptr<Skeleton>& GetSkeleton() const;
SkeletonComponentBase& operator=(const SkeletonComponentBase&) = default; SkeletonComponentBase& operator=(const SkeletonComponentBase&) = default;
@ -29,6 +31,8 @@ namespace Nz
protected: protected:
SkeletonComponentBase(std::shared_ptr<Skeleton> skeleton); SkeletonComponentBase(std::shared_ptr<Skeleton> skeleton);
virtual const Skeleton& GetAttachedSkeleton() const = 0;
std::shared_ptr<Skeleton> m_referenceSkeleton; std::shared_ptr<Skeleton> m_referenceSkeleton;
}; };
} }

View File

@ -12,6 +12,16 @@ namespace Nz
{ {
} }
inline std::size_t SkeletonComponentBase::FindJointByName(const std::string& jointName) const
{
return m_referenceSkeleton->GetJointIndex(jointName);
}
inline const Joint& SkeletonComponentBase::GetAttachedJoint(std::size_t jointIndex) const
{
return *GetAttachedSkeleton().GetJoint(jointIndex);
}
inline const std::shared_ptr<Skeleton>& SkeletonComponentBase::GetSkeleton() const inline const std::shared_ptr<Skeleton>& SkeletonComponentBase::GetSkeleton() const
{ {
return m_referenceSkeleton; return m_referenceSkeleton;

View File

@ -3,6 +3,8 @@
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Utility/Components/NodeComponent.hpp> #include <Nazara/Utility/Components/NodeComponent.hpp>
#include <Nazara/Utility/Components/SharedSkeletonComponent.hpp>
#include <Nazara/Utility/Components/SkeletonComponent.hpp>
#include <Nazara/Core/Error.hpp> #include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/Debug.hpp> #include <Nazara/Utility/Debug.hpp>
@ -15,4 +17,32 @@ namespace Nz
Node::SetParent(nodeComponent, keepDerived); Node::SetParent(nodeComponent, keepDerived);
} }
void NodeComponent::SetParentJoint(entt::handle entity, const std::string& jointName, bool keepDerived)
{
SkeletonComponentBase* skeletonComponent = entity.try_get<SkeletonComponent>();
if (!skeletonComponent)
skeletonComponent = entity.try_get<SharedSkeletonComponent>();
NazaraAssert(skeletonComponent, "entity doesn't have a SkeletonComponent nor a SharedSkeletonComponent");
std::size_t jointIndex = skeletonComponent->FindJointByName(jointName);
if (jointIndex == Skeleton::InvalidJointIndex)
{
NazaraError("skeleton has no joint \"" + jointName + "\"");
return;
}
Node::SetParent(skeletonComponent->GetAttachedJoint(jointIndex), keepDerived);
}
void NodeComponent::SetParentJoint(entt::handle entity, std::size_t jointIndex, bool keepDerived)
{
SkeletonComponentBase* skeletonComponent = entity.try_get<SkeletonComponent>();
if (!skeletonComponent)
skeletonComponent = entity.try_get<SharedSkeletonComponent>();
NazaraAssert(skeletonComponent, "entity doesn't have a SkeletonComponent nor a SharedSkeletonComponent");
Node::SetParent(skeletonComponent->GetAttachedJoint(jointIndex), keepDerived);
}
} }

View File

@ -31,11 +31,6 @@ namespace Nz
SetupSkeleton(); SetupSkeleton();
} }
const Joint& SharedSkeletonComponent::GetAttachedJoint(std::size_t jointIndex) const
{
return *m_attachedSkeleton.GetJoint(jointIndex);
}
SharedSkeletonComponent& SharedSkeletonComponent::operator=(const SharedSkeletonComponent& sharedSkeletalComponent) SharedSkeletonComponent& SharedSkeletonComponent::operator=(const SharedSkeletonComponent& sharedSkeletalComponent)
{ {
SkeletonComponentBase::operator=(sharedSkeletalComponent); SkeletonComponentBase::operator=(sharedSkeletalComponent);
@ -58,6 +53,11 @@ namespace Nz
return *this; return *this;
} }
const Skeleton& SharedSkeletonComponent::GetAttachedSkeleton() const
{
return m_attachedSkeleton;
}
void SharedSkeletonComponent::OnReferenceJointsInvalidated(const Skeleton* skeleton) void SharedSkeletonComponent::OnReferenceJointsInvalidated(const Skeleton* skeleton)
{ {
m_skeletonJointInvalidated = true; m_skeletonJointInvalidated = true;

View File

@ -12,13 +12,13 @@ namespace Nz
{ {
} }
const Joint& SkeletonComponent::GetAttachedJoint(std::size_t jointIndex) const
{
return *m_referenceSkeleton->GetJoint(jointIndex);
}
Node* SkeletonComponent::GetRootNode() Node* SkeletonComponent::GetRootNode()
{ {
return m_referenceSkeleton->GetRootJoint(); return m_referenceSkeleton->GetRootJoint();
} }
const Skeleton& SkeletonComponent::GetAttachedSkeleton() const
{
return *m_referenceSkeleton;
}
} }