Merge branch 'master' into vulkan
This commit is contained in:
@@ -50,6 +50,8 @@ namespace Ndk
|
||||
virtual void OnComponentDetached(BaseComponent& component);
|
||||
virtual void OnDetached();
|
||||
virtual void OnEntityDestruction();
|
||||
virtual void OnEntityDisabled();
|
||||
virtual void OnEntityEnabled();
|
||||
|
||||
void SetEntity(Entity* entity);
|
||||
|
||||
|
||||
@@ -17,5 +17,6 @@
|
||||
#include <NDK/Components/PhysicsComponent2D.hpp>
|
||||
#include <NDK/Components/PhysicsComponent3D.hpp>
|
||||
#include <NDK/Components/VelocityComponent.hpp>
|
||||
#include <NDK/Components/ConstraintComponent2D.hpp>
|
||||
|
||||
#endif // NDK_COMPONENTS_GLOBAL_HPP
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace Ndk
|
||||
class NDK_API CollisionComponent2D : public Component<CollisionComponent2D>
|
||||
{
|
||||
friend class PhysicsSystem2D;
|
||||
friend class ConstraintComponent2D;
|
||||
|
||||
public:
|
||||
CollisionComponent2D(Nz::Collider2DRef geom = Nz::Collider2DRef());
|
||||
|
||||
@@ -40,6 +40,8 @@ namespace Ndk
|
||||
void OnComponentAttached(BaseComponent& component) override;
|
||||
void OnComponentDetached(BaseComponent& component) override;
|
||||
void OnDetached() override;
|
||||
void OnEntityDisabled() override;
|
||||
void OnEntityEnabled() override;
|
||||
|
||||
std::unique_ptr<Nz::RigidBody3D> m_staticBody;
|
||||
Nz::Collider3DRef m_geom;
|
||||
|
||||
34
SDK/include/NDK/Components/ConstraintComponent2D.hpp
Normal file
34
SDK/include/NDK/Components/ConstraintComponent2D.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NDK_COMPONENTS_CONSTRAINTCOMPONENT2D_HPP
|
||||
#define NDK_COMPONENTS_CONSTRAINTCOMPONENT2D_HPP
|
||||
|
||||
#include <NDK/Component.hpp>
|
||||
#include <Nazara/Physics2D/Constraint2D.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
class NDK_API ConstraintComponent2D : public Component<ConstraintComponent2D>
|
||||
{
|
||||
public:
|
||||
ConstraintComponent2D() = default;
|
||||
ConstraintComponent2D(const ConstraintComponent2D& joint) = default;
|
||||
ConstraintComponent2D(ConstraintComponent2D&& joint) = default;
|
||||
|
||||
template<typename T, typename... Args> inline Nz::ObjectRef<T> CreateConstraint(const Ndk::EntityHandle& first, const Ndk::EntityHandle& second, Args&&... args);
|
||||
|
||||
static ComponentIndex componentIndex;
|
||||
|
||||
private:
|
||||
|
||||
std::vector<Nz::Constraint2DRef> m_constraints;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include <NDK/Components/ConstraintComponent2D.inl>
|
||||
|
||||
#endif// NDK_COMPONENTS_CONSTRAINTCOMPONENT2D_HPP
|
||||
31
SDK/include/NDK/Components/ConstraintComponent2D.inl
Normal file
31
SDK/include/NDK/Components/ConstraintComponent2D.inl
Normal file
@@ -0,0 +1,31 @@
|
||||
#include <NDK/Components/ConstraintComponent2D.hpp>
|
||||
#include <NDK/Components/PhysicsComponent2D.hpp>
|
||||
#include <NDK/Components/CollisionComponent2D.hpp>
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
template<typename T, typename ...Args>
|
||||
Nz::ObjectRef<T> ConstraintComponent2D::CreateConstraint(const Ndk::EntityHandle& first, const Ndk::EntityHandle& second, Args && ...args)
|
||||
{
|
||||
auto FetchBody = [](const Ndk::EntityHandle& entity) -> Nz::RigidBody2D*
|
||||
{
|
||||
if (entity->HasComponent<Ndk::PhysicsComponent2D>())
|
||||
return entity->GetComponent<Ndk::PhysicsComponent2D>().GetRigidBody();
|
||||
else if (entity->HasComponent<Ndk::CollisionComponent2D>())
|
||||
return entity->GetComponent<Ndk::CollisionComponent2D>().GetStaticBody();
|
||||
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
Nz::RigidBody2D* firstBody = FetchBody(first);
|
||||
NazaraAssert(firstBody, "First entity has no CollisionComponent2D nor PhysicsComponent2D component");
|
||||
|
||||
Nz::RigidBody2D* secondBody = FetchBody(second);
|
||||
NazaraAssert(secondBody, "Second entity has no CollisionComponent2D nor PhysicsComponent2D component");
|
||||
|
||||
Nz::ObjectRef<T> constraint = T::New(*firstBody, *secondBody, std::forward<Args>(args)...);
|
||||
m_constraints.push_back(constraint);
|
||||
|
||||
return constraint;
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ namespace Ndk
|
||||
{
|
||||
m_renderables.reserve(graphicsComponent.m_renderables.size());
|
||||
for (const Renderable& r : graphicsComponent.m_renderables)
|
||||
Attach(r.renderable, r.data.renderOrder);
|
||||
Attach(r.renderable, r.data.localMatrix, r.data.renderOrder);
|
||||
}
|
||||
|
||||
inline void GraphicsComponent::AddToCullingList(GraphicsComponentCullingList* cullingList) const
|
||||
@@ -55,8 +55,15 @@ namespace Ndk
|
||||
|
||||
inline void GraphicsComponent::Clear()
|
||||
{
|
||||
m_materialEntries.clear();
|
||||
m_renderables.clear();
|
||||
|
||||
if (m_reflectiveMaterialCount > 0)
|
||||
{
|
||||
m_reflectiveMaterialCount = 0;
|
||||
InvalidateReflectionMap();
|
||||
}
|
||||
|
||||
InvalidateBoundingVolume();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace Ndk
|
||||
{
|
||||
friend class CollisionComponent2D;
|
||||
friend class PhysicsSystem2D;
|
||||
friend class ConstraintComponent2D;
|
||||
|
||||
public:
|
||||
PhysicsComponent2D() = default;
|
||||
@@ -49,7 +50,7 @@ namespace Ndk
|
||||
static ComponentIndex componentIndex;
|
||||
|
||||
private:
|
||||
Nz::RigidBody2D& GetRigidBody();
|
||||
Nz::RigidBody2D* GetRigidBody();
|
||||
|
||||
void OnAttached() override;
|
||||
void OnComponentAttached(BaseComponent& component) override;
|
||||
|
||||
@@ -307,8 +307,8 @@ namespace Ndk
|
||||
* \return A reference to the physics object
|
||||
*/
|
||||
|
||||
inline Nz::RigidBody2D& PhysicsComponent2D::GetRigidBody()
|
||||
inline Nz::RigidBody2D* PhysicsComponent2D::GetRigidBody()
|
||||
{
|
||||
return *m_object.get();
|
||||
return m_object.get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Ndk
|
||||
friend class PhysicsSystem3D;
|
||||
|
||||
public:
|
||||
PhysicsComponent3D() = default;
|
||||
inline PhysicsComponent3D();
|
||||
PhysicsComponent3D(const PhysicsComponent3D& physics);
|
||||
~PhysicsComponent3D() = default;
|
||||
|
||||
@@ -28,41 +28,65 @@ namespace Ndk
|
||||
void AddTorque(const Nz::Vector3f& torque, Nz::CoordSys coordSys = Nz::CoordSys_Global);
|
||||
|
||||
void EnableAutoSleep(bool autoSleep);
|
||||
void EnableNodeSynchronization(bool nodeSynchronization);
|
||||
|
||||
Nz::Boxf GetAABB() const;
|
||||
Nz::Vector3f GetAngularDamping() const;
|
||||
Nz::Vector3f GetAngularVelocity() const;
|
||||
float GetGravityFactor() const;
|
||||
float GetLinearDamping() const;
|
||||
Nz::Vector3f GetLinearVelocity() const;
|
||||
float GetMass() const;
|
||||
Nz::Vector3f GetMassCenter(Nz::CoordSys coordSys = Nz::CoordSys_Local) const;
|
||||
const Nz::Matrix4f& GetMatrix() const;
|
||||
Nz::Vector3f GetPosition() const;
|
||||
Nz::Quaternionf GetRotation() const;
|
||||
Nz::Vector3f GetVelocity() const;
|
||||
|
||||
bool IsAutoSleepEnabled() const;
|
||||
bool IsMoveable() const;
|
||||
bool IsNodeSynchronizationEnabled() const;
|
||||
bool IsSleeping() const;
|
||||
|
||||
void SetAngularDamping(const Nz::Vector3f& angularDamping);
|
||||
void SetAngularVelocity(const Nz::Vector3f& angularVelocity);
|
||||
void SetGravityFactor(float gravityFactor);
|
||||
void SetLinearDamping(float damping);
|
||||
void SetLinearVelocity(const Nz::Vector3f& velocity);
|
||||
void SetMass(float mass);
|
||||
void SetMassCenter(const Nz::Vector3f& center);
|
||||
void SetPosition(const Nz::Vector3f& position);
|
||||
void SetRotation(const Nz::Quaternionf& rotation);
|
||||
void SetVelocity(const Nz::Vector3f& velocity);
|
||||
|
||||
static ComponentIndex componentIndex;
|
||||
|
||||
private:
|
||||
Nz::RigidBody3D& GetRigidBody();
|
||||
void ApplyPhysicsState(Nz::RigidBody3D& rigidBody) const;
|
||||
void CopyPhysicsState(const Nz::RigidBody3D& rigidBody);
|
||||
Nz::RigidBody3D* GetRigidBody();
|
||||
const Nz::RigidBody3D& GetRigidBody() const;
|
||||
|
||||
void OnAttached() override;
|
||||
void OnComponentAttached(BaseComponent& component) override;
|
||||
void OnComponentDetached(BaseComponent& component) override;
|
||||
void OnDetached() override;
|
||||
void OnEntityDestruction() override;
|
||||
void OnEntityDisabled() override;
|
||||
void OnEntityEnabled() override;
|
||||
|
||||
struct PendingPhysObjectStates
|
||||
{
|
||||
Nz::Vector3f angularDamping;
|
||||
Nz::Vector3f massCenter;
|
||||
bool autoSleep;
|
||||
bool valid = false;
|
||||
float gravityFactor;
|
||||
float linearDamping;
|
||||
float mass;
|
||||
};
|
||||
|
||||
std::unique_ptr<Nz::RigidBody3D> m_object;
|
||||
PendingPhysObjectStates m_pendingStates;
|
||||
bool m_nodeSynchronizationEnabled;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,19 +3,25 @@
|
||||
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
|
||||
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include "PhysicsComponent3D.hpp"
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
inline PhysicsComponent3D::PhysicsComponent3D() :
|
||||
m_nodeSynchronizationEnabled(true)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a PhysicsComponent3D object by copy semantic
|
||||
*
|
||||
* \param physics PhysicsComponent3D to copy
|
||||
*/
|
||||
|
||||
inline PhysicsComponent3D::PhysicsComponent3D(const PhysicsComponent3D& physics)
|
||||
inline PhysicsComponent3D::PhysicsComponent3D(const PhysicsComponent3D& physics) :
|
||||
m_nodeSynchronizationEnabled(physics.m_nodeSynchronizationEnabled)
|
||||
{
|
||||
// No copy of physical object (because we only create it when attached to an entity)
|
||||
NazaraUnused(physics);
|
||||
// We can't make a copy of the RigidBody3D, as we are not attached yet (and will possibly be attached to another world)
|
||||
CopyPhysicsState(physics.GetRigidBody());
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -74,7 +80,6 @@ namespace Ndk
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
|
||||
inline void PhysicsComponent3D::EnableAutoSleep(bool autoSleep)
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
@@ -82,13 +87,28 @@ namespace Ndk
|
||||
m_object->EnableAutoSleep(autoSleep);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enables position/rotation synchronization with the NodeComponent
|
||||
*
|
||||
* By default, at every update of the PhysicsSystem3D, the NodeComponent's position and rotation (if any) will be synchronized with
|
||||
* the values of the PhysicsComponent3D. This function allows to enable/disable this behavior on a per-entity basis.
|
||||
*
|
||||
* \param nodeSynchronization Should synchronization occur between NodeComponent and PhysicsComponent3D
|
||||
*/
|
||||
inline void PhysicsComponent3D::EnableNodeSynchronization(bool nodeSynchronization)
|
||||
{
|
||||
m_nodeSynchronizationEnabled = nodeSynchronization;
|
||||
|
||||
if (m_entity)
|
||||
m_entity->Invalidate();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the AABB of the physics object
|
||||
* \return AABB of the object
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
|
||||
inline Nz::Boxf PhysicsComponent3D::GetAABB() const
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
@@ -96,13 +116,23 @@ namespace Ndk
|
||||
return m_object->GetAABB();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the angular damping of the physics object
|
||||
* \return Angular damping of the object
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
inline Nz::Vector3f PhysicsComponent3D::GetAngularDamping() const
|
||||
{
|
||||
return m_object->GetAngularDamping();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the angular velocity of the physics object
|
||||
* \return Angular velocity of the object
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
|
||||
inline Nz::Vector3f PhysicsComponent3D::GetAngularVelocity() const
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
@@ -116,7 +146,6 @@ namespace Ndk
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
|
||||
inline float PhysicsComponent3D::GetGravityFactor() const
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
@@ -124,6 +153,33 @@ namespace Ndk
|
||||
return m_object->GetGravityFactor();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the linear damping of the physics object
|
||||
* \return Linear damping of the object
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
inline float PhysicsComponent3D::GetLinearDamping() const
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
|
||||
return m_object->GetLinearDamping();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the linear velocity of the physics object
|
||||
* \return Linear velocity of the object
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
|
||||
inline Nz::Vector3f PhysicsComponent3D::GetLinearVelocity() const
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
|
||||
return m_object->GetLinearVelocity();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the mass of the physics object
|
||||
* \return Mass of the object
|
||||
@@ -142,7 +198,7 @@ namespace Ndk
|
||||
* \brief Gets the gravity center of the physics object
|
||||
* \return Gravity center of the object
|
||||
*
|
||||
* \param coordSys System coordinates to consider
|
||||
* \param coordSys System coordinates to consider
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
@@ -196,27 +252,12 @@ namespace Ndk
|
||||
return m_object->GetRotation();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the velocity of the physics object
|
||||
* \return Velocity of the object
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
|
||||
inline Nz::Vector3f PhysicsComponent3D::GetVelocity() const
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
|
||||
return m_object->GetVelocity();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the auto sleep is enabled
|
||||
* \return true If it is the case
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
|
||||
inline bool PhysicsComponent3D::IsAutoSleepEnabled() const
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
@@ -224,13 +265,36 @@ namespace Ndk
|
||||
return m_object->IsAutoSleepEnabled();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the object is moveable
|
||||
* \return true If it is the case
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
inline bool PhysicsComponent3D::IsMoveable() const
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
|
||||
return m_object->IsMoveable();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks if position & rotation are synchronized with NodeComponent
|
||||
* \return true If synchronization is enabled
|
||||
*
|
||||
* \see EnableNodeSynchronization
|
||||
*/
|
||||
inline bool PhysicsComponent3D::IsNodeSynchronizationEnabled() const
|
||||
{
|
||||
return m_nodeSynchronizationEnabled;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the entity is currently sleeping
|
||||
* \return true If it is the case
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
|
||||
inline bool PhysicsComponent3D::IsSleeping() const
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
@@ -238,6 +302,20 @@ namespace Ndk
|
||||
return m_object->IsSleeping();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the angular damping of the physics object
|
||||
*
|
||||
* \param angularDamping Angular damping of the object
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
inline void PhysicsComponent3D::SetAngularDamping(const Nz::Vector3f& angularDamping)
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
|
||||
m_object->SetAngularDamping(angularDamping);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the angular velocity of the physics object
|
||||
*
|
||||
@@ -245,7 +323,6 @@ namespace Ndk
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
|
||||
inline void PhysicsComponent3D::SetAngularVelocity(const Nz::Vector3f& angularVelocity)
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
@@ -260,7 +337,6 @@ namespace Ndk
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
|
||||
inline void PhysicsComponent3D::SetGravityFactor(float gravityFactor)
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
@@ -268,6 +344,34 @@ namespace Ndk
|
||||
m_object->SetGravityFactor(gravityFactor);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the linear damping of the physics object
|
||||
*
|
||||
* \param damping Linear damping of the object
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
inline void PhysicsComponent3D::SetLinearDamping(float damping)
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
|
||||
m_object->SetLinearDamping(damping);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the linear velocity of the physics object
|
||||
*
|
||||
* \param velocity New linear velocity of the object
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
inline void PhysicsComponent3D::SetLinearVelocity(const Nz::Vector3f& velocity)
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
|
||||
m_object->SetLinearVelocity(velocity);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the mass of the physics object
|
||||
*
|
||||
@@ -276,11 +380,11 @@ namespace Ndk
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
* \remark Produces a NazaraAssert if the mass is negative
|
||||
*/
|
||||
|
||||
inline void PhysicsComponent3D::SetMass(float mass)
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
NazaraAssert(mass > 0.f, "Mass should be positive");
|
||||
NazaraAssert(mass >= 0.f, "Mass must be positive and finite");
|
||||
NazaraAssert(std::isfinite(mass), "Mass must be positive and finite");
|
||||
|
||||
m_object->SetMass(mass);
|
||||
}
|
||||
@@ -330,27 +434,43 @@ namespace Ndk
|
||||
m_object->SetRotation(rotation);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the velocity of the physics object
|
||||
*
|
||||
* \param velocity Velocity of the object
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
|
||||
inline void PhysicsComponent3D::SetVelocity(const Nz::Vector3f& velocity)
|
||||
inline void PhysicsComponent3D::ApplyPhysicsState(Nz::RigidBody3D& rigidBody) const
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
assert(m_pendingStates.valid);
|
||||
|
||||
m_object->SetVelocity(velocity);
|
||||
rigidBody.EnableAutoSleep(m_pendingStates.autoSleep);
|
||||
rigidBody.SetAngularDamping(m_pendingStates.angularDamping);
|
||||
rigidBody.SetGravityFactor(m_pendingStates.gravityFactor);
|
||||
rigidBody.SetLinearDamping(m_pendingStates.linearDamping);
|
||||
rigidBody.SetMass(m_pendingStates.mass);
|
||||
rigidBody.SetMassCenter(m_pendingStates.massCenter);
|
||||
}
|
||||
|
||||
inline void PhysicsComponent3D::CopyPhysicsState(const Nz::RigidBody3D& rigidBody)
|
||||
{
|
||||
m_pendingStates.autoSleep = rigidBody.IsAutoSleepEnabled();
|
||||
m_pendingStates.angularDamping = rigidBody.GetAngularDamping();
|
||||
m_pendingStates.gravityFactor = rigidBody.GetGravityFactor();
|
||||
m_pendingStates.linearDamping = rigidBody.GetLinearDamping();
|
||||
m_pendingStates.mass = rigidBody.GetMass();
|
||||
m_pendingStates.massCenter = rigidBody.GetMassCenter(Nz::CoordSys_Local);
|
||||
m_pendingStates.valid = true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the underlying physics object
|
||||
* \return A reference to the physics object
|
||||
*/
|
||||
inline Nz::RigidBody3D* PhysicsComponent3D::GetRigidBody()
|
||||
{
|
||||
return m_object.get();
|
||||
}
|
||||
|
||||
inline Nz::RigidBody3D& PhysicsComponent3D::GetRigidBody()
|
||||
/*!
|
||||
* \brief Gets the underlying physics object
|
||||
* \return A reference to the physics object
|
||||
*/
|
||||
inline const Nz::RigidBody3D& PhysicsComponent3D::GetRigidBody() const
|
||||
{
|
||||
return *m_object.get();
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Ndk
|
||||
const EntityHandle& Clone() const;
|
||||
|
||||
inline void Disable();
|
||||
inline void Enable(bool enable = true);
|
||||
void Enable(bool enable = true);
|
||||
|
||||
inline BaseComponent& GetComponent(ComponentIndex index);
|
||||
template<typename ComponentType> ComponentType& GetComponent();
|
||||
|
||||
@@ -38,20 +38,6 @@ namespace Ndk
|
||||
Enable(false);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enables the entity
|
||||
*
|
||||
* \param enable Should the entity be enabled
|
||||
*/
|
||||
inline void Entity::Enable(bool enable)
|
||||
{
|
||||
if (m_enabled != enable)
|
||||
{
|
||||
m_enabled = enable;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets a component in the entity by index
|
||||
* \return A reference to the component
|
||||
|
||||
@@ -31,4 +31,4 @@ namespace Ndk
|
||||
|
||||
#include <NDK/EntityOwner.inl>
|
||||
|
||||
#endif // NDK_ENTITYOwner_HPP
|
||||
#endif // NDK_ENTITYOWNER_HPP
|
||||
|
||||
@@ -10,9 +10,11 @@ namespace Ndk
|
||||
{
|
||||
m_cursorPosition.MakeZero();
|
||||
m_drawer.Clear();
|
||||
m_text.Clear();
|
||||
m_textSprite->Update(m_drawer);
|
||||
|
||||
RefreshCursor();
|
||||
OnTextChanged(this, m_text);
|
||||
}
|
||||
|
||||
inline void TextAreaWidget::EnableMultiline(bool enable)
|
||||
|
||||
@@ -63,6 +63,26 @@ namespace Ndk
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when the entity is disabled
|
||||
*
|
||||
* \remark Disabling an entity will remove it from systems it belongs to, but sometimes the entity will need to do
|
||||
* additional work in order to be properly disabled (i.e.: disabling physics simulation & collisions)
|
||||
*/
|
||||
void BaseComponent::OnEntityDisabled()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operation to perform when the entity is disabled
|
||||
*
|
||||
* \remark Enabling an entity will add it back to systems it belongs to, but sometimes the entity will need to do
|
||||
* additional work in order to be properly re-enabled (i.e.: enabling physics simulation & collisions)
|
||||
*/
|
||||
void BaseComponent::OnEntityEnabled()
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<BaseComponent::ComponentEntry> BaseComponent::s_entries;
|
||||
std::unordered_map<ComponentId, ComponentIndex> BaseComponent::s_idToIndex;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Ndk
|
||||
{
|
||||
// We update the geometry of the PhysiscsObject linked to the PhysicsComponent2D
|
||||
PhysicsComponent2D& physComponent = m_entity->GetComponent<PhysicsComponent2D>();
|
||||
physComponent.GetRigidBody().SetGeom(m_geom);
|
||||
physComponent.GetRigidBody()->SetGeom(m_geom);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -58,7 +58,7 @@ namespace Ndk
|
||||
NazaraAssert(entityWorld->HasSystem<PhysicsSystem2D>(), "World must have a physics system");
|
||||
Nz::PhysWorld2D& physWorld = entityWorld->GetSystem<PhysicsSystem2D>().GetWorld();
|
||||
|
||||
m_staticBody.reset(new Nz::RigidBody2D(&physWorld, 0.f, m_geom));
|
||||
m_staticBody = std::make_unique<Nz::RigidBody2D>(&physWorld, 0.f, m_geom);
|
||||
|
||||
Nz::Matrix4f matrix;
|
||||
if (m_entity->HasComponent<NodeComponent>())
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Ndk
|
||||
{
|
||||
// We update the geometry of the PhysiscsObject linked to the PhysicsComponent3D
|
||||
PhysicsComponent3D& physComponent = m_entity->GetComponent<PhysicsComponent3D>();
|
||||
physComponent.GetRigidBody().SetGeom(m_geom);
|
||||
physComponent.GetRigidBody()->SetGeom(m_geom);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -57,7 +57,7 @@ namespace Ndk
|
||||
NazaraAssert(entityWorld->HasSystem<PhysicsSystem3D>(), "World must have a physics system");
|
||||
Nz::PhysWorld3D& physWorld = entityWorld->GetSystem<PhysicsSystem3D>().GetWorld();
|
||||
|
||||
m_staticBody.reset(new Nz::RigidBody3D(&physWorld, m_geom));
|
||||
m_staticBody = std::make_unique<Nz::RigidBody3D>(&physWorld, m_geom);
|
||||
m_staticBody->EnableAutoSleep(false);
|
||||
}
|
||||
|
||||
@@ -104,5 +104,17 @@ namespace Ndk
|
||||
m_staticBody.reset();
|
||||
}
|
||||
|
||||
void CollisionComponent3D::OnEntityDisabled()
|
||||
{
|
||||
if (m_staticBody)
|
||||
m_staticBody->EnableSimulation(false);
|
||||
}
|
||||
|
||||
void CollisionComponent3D::OnEntityEnabled()
|
||||
{
|
||||
if (m_staticBody)
|
||||
m_staticBody->EnableSimulation(true);
|
||||
}
|
||||
|
||||
ComponentIndex CollisionComponent3D::componentIndex;
|
||||
}
|
||||
|
||||
6
SDK/src/NDK/Components/ConstraintComponent2D.cpp
Normal file
6
SDK/src/NDK/Components/ConstraintComponent2D.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#include <NDK/Components/ConstraintComponent2D.hpp>
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
ComponentIndex ConstraintComponent2D::componentIndex;
|
||||
}
|
||||
@@ -40,8 +40,12 @@ namespace Ndk
|
||||
else
|
||||
matrix.MakeIdentity();
|
||||
|
||||
m_object.reset(new Nz::RigidBody3D(&world, geom, matrix));
|
||||
m_object->SetMass(1.f);
|
||||
m_object = std::make_unique<Nz::RigidBody3D>(&world, geom, matrix);
|
||||
|
||||
if (m_pendingStates.valid)
|
||||
ApplyPhysicsState(*m_object);
|
||||
else
|
||||
m_object->SetMass(1.f);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -57,6 +61,7 @@ namespace Ndk
|
||||
if (IsComponent<CollisionComponent3D>(component))
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid object");
|
||||
|
||||
m_object->SetGeom(static_cast<CollisionComponent3D&>(component).GetGeom());
|
||||
}
|
||||
}
|
||||
@@ -74,6 +79,7 @@ namespace Ndk
|
||||
if (IsComponent<CollisionComponent3D>(component))
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid object");
|
||||
|
||||
m_object->SetGeom(Nz::NullCollider3D::New());
|
||||
}
|
||||
}
|
||||
@@ -84,7 +90,11 @@ namespace Ndk
|
||||
|
||||
void PhysicsComponent3D::OnDetached()
|
||||
{
|
||||
m_object.reset();
|
||||
if (m_object)
|
||||
{
|
||||
CopyPhysicsState(*m_object);
|
||||
m_object.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsComponent3D::OnEntityDestruction()
|
||||
@@ -93,5 +103,19 @@ namespace Ndk
|
||||
m_object.reset();
|
||||
}
|
||||
|
||||
void PhysicsComponent3D::OnEntityDisabled()
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
|
||||
m_object->EnableSimulation(false);
|
||||
}
|
||||
|
||||
void PhysicsComponent3D::OnEntityEnabled()
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
|
||||
m_object->EnableSimulation(true);
|
||||
}
|
||||
|
||||
ComponentIndex PhysicsComponent3D::componentIndex;
|
||||
}
|
||||
|
||||
@@ -96,6 +96,10 @@ namespace Ndk
|
||||
m_components[i]->OnComponentAttached(component);
|
||||
}
|
||||
|
||||
// If we are currently disabled, inform the component
|
||||
if (!m_enabled)
|
||||
component.OnEntityDisabled();
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
@@ -106,7 +110,6 @@ namespace Ndk
|
||||
* \remark The close is enable by default, even if the original is disabled
|
||||
* \remark Produces a NazaraAssert if the entity is not valid
|
||||
*/
|
||||
|
||||
const EntityHandle& Entity::Clone() const
|
||||
{
|
||||
NazaraAssert(IsValid(), "Invalid entity");
|
||||
@@ -114,10 +117,34 @@ namespace Ndk
|
||||
return m_world->CloneEntity(m_id);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enables the entity
|
||||
*
|
||||
* \param enable Should the entity be enabled
|
||||
*/
|
||||
void Entity::Enable(bool enable)
|
||||
{
|
||||
if (m_enabled != enable)
|
||||
{
|
||||
m_enabled = enable;
|
||||
if (m_enabled)
|
||||
{
|
||||
for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i))
|
||||
m_components[i]->OnEntityEnabled();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i))
|
||||
m_components[i]->OnEntityDisabled();
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Kills the entity
|
||||
*/
|
||||
|
||||
void Entity::Kill()
|
||||
{
|
||||
m_world->KillEntity(this);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <NDK/Components/PhysicsComponent2D.hpp>
|
||||
#include <NDK/Components/PhysicsComponent3D.hpp>
|
||||
#include <NDK/Components/VelocityComponent.hpp>
|
||||
#include <NDK/Components/ConstraintComponent2D.hpp>
|
||||
#include <NDK/Systems/PhysicsSystem2D.hpp>
|
||||
#include <NDK/Systems/PhysicsSystem3D.hpp>
|
||||
#include <NDK/Systems/VelocitySystem.hpp>
|
||||
@@ -89,6 +90,7 @@ namespace Ndk
|
||||
InitializeComponent<PhysicsComponent2D>("NdkPhys2");
|
||||
InitializeComponent<PhysicsComponent3D>("NdkPhys3");
|
||||
InitializeComponent<VelocityComponent>("NdkVeloc");
|
||||
InitializeComponent<VelocityComponent>("NdkCons2");
|
||||
|
||||
#ifndef NDK_SERVER
|
||||
// Client components
|
||||
|
||||
@@ -80,9 +80,9 @@ namespace Ndk
|
||||
NodeComponent& node = entity->GetComponent<NodeComponent>();
|
||||
PhysicsComponent2D& phys = entity->GetComponent<PhysicsComponent2D>();
|
||||
|
||||
Nz::RigidBody2D& body = phys.GetRigidBody();
|
||||
node.SetRotation(Nz::EulerAnglesf(0.f, 0.f, body.GetRotation()), Nz::CoordSys_Global);
|
||||
node.SetPosition(Nz::Vector3f(body.GetPosition(), node.GetPosition(Nz::CoordSys_Global).z), Nz::CoordSys_Global);
|
||||
Nz::RigidBody2D* body = phys.GetRigidBody();
|
||||
node.SetRotation(Nz::EulerAnglesf(0.f, 0.f, body->GetRotation()), Nz::CoordSys_Global);
|
||||
node.SetPosition(Nz::Vector3f(body->GetPosition(), node.GetPosition(Nz::CoordSys_Global).z), Nz::CoordSys_Global);
|
||||
}
|
||||
|
||||
float invElapsedTime = 1.f / elapsedTime;
|
||||
|
||||
@@ -47,16 +47,32 @@ namespace Ndk
|
||||
|
||||
void PhysicsSystem3D::OnEntityValidation(Entity* entity, bool justAdded)
|
||||
{
|
||||
// It's possible our entity got revalidated because of the addition/removal of a PhysicsComponent3D
|
||||
if (!justAdded)
|
||||
if (entity->HasComponent<PhysicsComponent3D>())
|
||||
{
|
||||
// We take the opposite array from which the entity should belong to
|
||||
auto& entities = (entity->HasComponent<PhysicsComponent3D>()) ? m_staticObjects : m_dynamicObjects;
|
||||
entities.Remove(entity);
|
||||
}
|
||||
if (entity->GetComponent<PhysicsComponent3D>().IsNodeSynchronizationEnabled())
|
||||
m_dynamicObjects.Insert(entity);
|
||||
else
|
||||
m_dynamicObjects.Remove(entity);
|
||||
|
||||
auto& entities = (entity->HasComponent<PhysicsComponent3D>()) ? m_dynamicObjects : m_staticObjects;
|
||||
entities.Insert(entity);
|
||||
m_staticObjects.Remove(entity);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dynamicObjects.Remove(entity);
|
||||
m_staticObjects.Insert(entity);
|
||||
|
||||
// If entities just got added to the system, teleport them to their NodeComponent position/rotation
|
||||
// This will prevent the physics engine to mess with the scene while correcting position/rotation
|
||||
if (justAdded)
|
||||
{
|
||||
auto& collision = entity->GetComponent<CollisionComponent3D>();
|
||||
auto& node = entity->GetComponent<NodeComponent>();
|
||||
|
||||
Nz::RigidBody3D* physObj = collision.GetStaticBody();
|
||||
physObj->SetPosition(node.GetPosition());
|
||||
physObj->SetRotation(node.GetRotation());
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_world)
|
||||
CreatePhysWorld();
|
||||
@@ -80,9 +96,9 @@ namespace Ndk
|
||||
NodeComponent& node = entity->GetComponent<NodeComponent>();
|
||||
PhysicsComponent3D& phys = entity->GetComponent<PhysicsComponent3D>();
|
||||
|
||||
Nz::RigidBody3D& physObj = phys.GetRigidBody();
|
||||
node.SetRotation(physObj.GetRotation(), Nz::CoordSys_Global);
|
||||
node.SetPosition(physObj.GetPosition(), Nz::CoordSys_Global);
|
||||
Nz::RigidBody3D* physObj = phys.GetRigidBody();
|
||||
node.SetRotation(physObj->GetRotation(), Nz::CoordSys_Global);
|
||||
node.SetPosition(physObj->GetPosition(), Nz::CoordSys_Global);
|
||||
}
|
||||
|
||||
float invElapsedTime = 1.f / elapsedTime;
|
||||
@@ -103,10 +119,10 @@ namespace Ndk
|
||||
if (newPosition != oldPosition)
|
||||
{
|
||||
physObj->SetPosition(newPosition);
|
||||
physObj->SetVelocity((newPosition - oldPosition) * invElapsedTime);
|
||||
physObj->SetLinearVelocity((newPosition - oldPosition) * invElapsedTime);
|
||||
}
|
||||
else
|
||||
physObj->SetVelocity(Nz::Vector3f::Zero());
|
||||
physObj->SetLinearVelocity(Nz::Vector3f::Zero());
|
||||
|
||||
if (newRotation != oldRotation)
|
||||
{
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace Ndk
|
||||
|
||||
Nz::Vector3f textBox = m_textSprite->GetBoundingVolume().obb.localBox.GetLengths();
|
||||
m_textEntity->GetComponent<NodeComponent>().SetPosition(origin.x + checkboxSize.x + (m_adaptativeMargin ? checkboxSize.x / 2.f : m_textMargin),
|
||||
origin.y + checkboxSize.y / 2.f - textBox.y / 2.f);
|
||||
origin.y + checkboxSize.y / 2.f - textBox.y / 2.f);
|
||||
}
|
||||
|
||||
void CheckboxWidget::OnMouseButtonRelease(int x, int y, Nz::Mouse::Button button)
|
||||
|
||||
@@ -138,12 +138,11 @@ namespace Ndk
|
||||
*
|
||||
* \param id Identifier of the entity
|
||||
*
|
||||
* \remark Produces a NazaraError if the entity to clone does not exist
|
||||
* \remark Cloning a disabled entity will produce an enabled clone
|
||||
*/
|
||||
|
||||
const EntityHandle& World::CloneEntity(EntityId id)
|
||||
{
|
||||
EntityHandle original = GetEntity(id);
|
||||
const EntityHandle& original = GetEntity(id);
|
||||
if (!original)
|
||||
{
|
||||
NazaraError("Invalid entity ID");
|
||||
@@ -151,6 +150,8 @@ namespace Ndk
|
||||
}
|
||||
|
||||
const EntityHandle& clone = CreateEntity();
|
||||
if (!original->IsEnabled())
|
||||
clone->Disable();
|
||||
|
||||
const Nz::Bitset<>& componentBits = original->GetComponentBits();
|
||||
for (std::size_t i = componentBits.FindFirst(); i != componentBits.npos; i = componentBits.FindNext(i))
|
||||
@@ -159,6 +160,8 @@ namespace Ndk
|
||||
clone->AddComponent(std::move(component));
|
||||
}
|
||||
|
||||
clone->Enable();
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user