From 1642536a0ee990b634be769722d7b39a6f38668a Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 19 Apr 2015 18:01:45 +0200 Subject: [PATCH 01/29] Physics/Geom: Improved Geom class Renamed BaseGeom to PhysGeom, made it a reference-counted class Former-commit-id: 5b3a2921addb537c2744346edc9c74eafb3260b0 --- include/Nazara/Physics/Geom.hpp | 115 ++++++++++++++++++++++---- include/Nazara/Physics/Geom.inl | 80 ++++++++++++++++++ include/Nazara/Physics/PhysObject.hpp | 10 ++- src/Nazara/Physics/Geom.cpp | 52 ++++++------ src/Nazara/Physics/PhysObject.cpp | 56 +++++++------ 5 files changed, 243 insertions(+), 70 deletions(-) create mode 100644 include/Nazara/Physics/Geom.inl diff --git a/include/Nazara/Physics/Geom.hpp b/include/Nazara/Physics/Geom.hpp index 5c851ee30..489043f3a 100644 --- a/include/Nazara/Physics/Geom.hpp +++ b/include/Nazara/Physics/Geom.hpp @@ -8,8 +8,12 @@ #define NAZARA_GEOM_HPP #include -#include #include +#include +#include +#include +#include +#include #include #include #include @@ -21,14 +25,21 @@ ///TODO: SceneGeom ///TODO: TreeGeom +class NzPhysGeom; class NzPhysWorld; struct NewtonCollision; -class NAZARA_API NzBaseGeom : NzNonCopyable +using NzPhysGeomConstListener = NzObjectListenerWrapper; +using NzPhysGeomConstRef = NzObjectRef; +using NzPhysGeomLibrary = NzObjectLibrary; +using NzPhysGeomListener = NzObjectListenerWrapper; +using NzPhysGeomRef = NzObjectRef; + +class NAZARA_API NzPhysGeom : public NzRefCounted, NzNonCopyable { public: - NzBaseGeom(NzPhysWorld* physWorld); - virtual ~NzBaseGeom(); + NzPhysGeom(NzPhysWorld* physWorld); + virtual ~NzPhysGeom(); virtual NzBoxf ComputeAABB(const NzVector3f& translation, const NzQuaternionf& rotation, const NzVector3f& scale) const; virtual NzBoxf ComputeAABB(const NzMatrix4f& offsetMatrix = NzMatrix4f::Identity()) const; @@ -40,14 +51,23 @@ class NAZARA_API NzBaseGeom : NzNonCopyable NzPhysWorld* GetWorld() const; - static NzBaseGeom* Build(NzPhysWorld* physWorld, const NzPrimitiveList& list); + static NzPhysGeomRef Build(NzPhysWorld* physWorld, const NzPrimitiveList& list); protected: NewtonCollision* m_collision; NzPhysWorld* m_world; + + static NzPhysGeomLibrary::LibraryMap s_library; }; -class NAZARA_API NzBoxGeom : public NzBaseGeom +class NzBoxGeom; + +using NzBoxGeomConstListener = NzObjectListenerWrapper; +using NzBoxGeomConstRef = NzObjectRef; +using NzBoxGeomListener = NzObjectListenerWrapper; +using NzBoxGeomRef = NzObjectRef; + +class NAZARA_API NzBoxGeom : public NzPhysGeom { public: NzBoxGeom(NzPhysWorld* physWorld, const NzVector3f& lengths, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); @@ -56,11 +76,20 @@ class NAZARA_API NzBoxGeom : public NzBaseGeom NzVector3f GetLengths() const; nzGeomType GetType() const override; + template static NzBoxGeomRef New(Args&&... args); + private: NzVector3f m_lengths; }; -class NAZARA_API NzCapsuleGeom : public NzBaseGeom +class NzCapsuleGeom; + +using NzCapsuleGeomConstListener = NzObjectListenerWrapper; +using NzCapsuleGeomConstRef = NzObjectRef; +using NzCapsuleGeomListener = NzObjectListenerWrapper; +using NzCapsuleGeomRef = NzObjectRef; + +class NAZARA_API NzCapsuleGeom : public NzPhysGeom { public: NzCapsuleGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); @@ -70,20 +99,38 @@ class NAZARA_API NzCapsuleGeom : public NzBaseGeom float GetRadius() const; nzGeomType GetType() const override; + template static NzCapsuleGeomRef New(Args&&... args); + private: float m_length; float m_radius; }; -class NAZARA_API NzCompoundGeom : public NzBaseGeom +class NzCompoundGeom; + +using NzCompoundGeomConstListener = NzObjectListenerWrapper; +using NzCompoundGeomConstRef = NzObjectRef; +using NzCompoundGeomListener = NzObjectListenerWrapper; +using NzCompoundGeomRef = NzObjectRef; + +class NAZARA_API NzCompoundGeom : public NzPhysGeom { public: - NzCompoundGeom(NzPhysWorld* physWorld, NzBaseGeom** geoms, unsigned int geomCount); + NzCompoundGeom(NzPhysWorld* physWorld, NzPhysGeom** geoms, unsigned int geomCount); nzGeomType GetType() const override; + + template static NzCompoundGeomRef New(Args&&... args); }; -class NAZARA_API NzConeGeom : public NzBaseGeom +class NzConeGeom; + +using NzConeGeomConstListener = NzObjectListenerWrapper; +using NzConeGeomConstRef = NzObjectRef; +using NzConeGeomListener = NzObjectListenerWrapper; +using NzConeGeomRef = NzObjectRef; + +class NAZARA_API NzConeGeom : public NzPhysGeom { public: NzConeGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); @@ -93,21 +140,39 @@ class NAZARA_API NzConeGeom : public NzBaseGeom float GetRadius() const; nzGeomType GetType() const override; + template static NzConeGeomRef New(Args&&... args); + private: float m_length; float m_radius; }; -class NAZARA_API NzConvexHullGeom : public NzBaseGeom +class NzConvexHullGeom; + +using NzConvexHullGeomConstListener = NzObjectListenerWrapper; +using NzConvexHullGeomConstRef = NzObjectRef; +using NzConvexHullGeomListener = NzObjectListenerWrapper; +using NzConvexHullGeomRef = NzObjectRef; + +class NAZARA_API NzConvexHullGeom : public NzPhysGeom { public: NzConvexHullGeom(NzPhysWorld* physWorld, const void* vertices, unsigned int vertexCount, unsigned int stride = sizeof(NzVector3f), float tolerance = 0.002f, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); NzConvexHullGeom(NzPhysWorld* physWorld, const void* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); nzGeomType GetType() const override; + + template static NzConvexHullGeomRef New(Args&&... args); }; -class NAZARA_API NzCylinderGeom : public NzBaseGeom +class NzCylinderGeom; + +using NzCylinderGeomConstListener = NzObjectListenerWrapper; +using NzCylinderGeomConstRef = NzObjectRef; +using NzCylinderGeomListener = NzObjectListenerWrapper; +using NzCylinderGeomRef = NzObjectRef; + +class NAZARA_API NzCylinderGeom : public NzPhysGeom { public: NzCylinderGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); @@ -117,20 +182,38 @@ class NAZARA_API NzCylinderGeom : public NzBaseGeom float GetRadius() const; nzGeomType GetType() const override; + template static NzCylinderGeomRef New(Args&&... args); + private: float m_length; float m_radius; }; -class NAZARA_API NzNullGeom : public NzBaseGeom +class NzNullGeom; + +using NzNullGeomConstListener = NzObjectListenerWrapper; +using NzNullGeomConstRef = NzObjectRef; +using NzNullGeomListener = NzObjectListenerWrapper; +using NzNullGeomRef = NzObjectRef; + +class NAZARA_API NzNullGeom : public NzPhysGeom { public: NzNullGeom(NzPhysWorld* physWorld); nzGeomType GetType() const override; + + template static NzNullGeomRef New(Args&&... args); }; -class NAZARA_API NzSphereGeom : public NzBaseGeom +class NzSphereGeom; + +using NzSphereGeomConstListener = NzObjectListenerWrapper; +using NzSphereGeomConstRef = NzObjectRef; +using NzSphereGeomListener = NzObjectListenerWrapper; +using NzSphereGeomRef = NzObjectRef; + +class NAZARA_API NzSphereGeom : public NzPhysGeom { public: NzSphereGeom(NzPhysWorld* physWorld, float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); @@ -139,8 +222,12 @@ class NAZARA_API NzSphereGeom : public NzBaseGeom NzVector3f GetRadius() const; nzGeomType GetType() const override; + template static NzSphereGeomRef New(Args&&... args); + private: NzVector3f m_radius; }; +#include + #endif // NAZARA_PHYSWORLD_HPP diff --git a/include/Nazara/Physics/Geom.inl b/include/Nazara/Physics/Geom.inl new file mode 100644 index 000000000..6254feea8 --- /dev/null +++ b/include/Nazara/Physics/Geom.inl @@ -0,0 +1,80 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Physics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +template +NzBoxGeomRef NzBoxGeom::New(Args&&... args) +{ + std::unique_ptr object(new NzBoxGeom(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); +} + +template +NzCapsuleGeomRef NzCapsuleGeom::New(Args&&... args) +{ + std::unique_ptr object(new NzCapsuleGeom(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); +} + +template +NzCompoundGeomRef NzCompoundGeom::New(Args&&... args) +{ + std::unique_ptr object(new NzCompoundGeom(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); +} + +template +NzConeGeomRef NzConeGeom::New(Args&&... args) +{ + std::unique_ptr object(new NzConeGeom(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); +} + +template +NzConvexHullGeomRef NzConvexHullGeom::New(Args&&... args) +{ + std::unique_ptr object(new NzConvexHullGeom(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); +} + +template +NzCylinderGeomRef NzCylinderGeom::New(Args&&... args) +{ + std::unique_ptr object(new NzCylinderGeom(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); +} + +template +NzNullGeomRef NzNullGeom::New(Args&&... args) +{ + std::unique_ptr object(new NzNullGeom(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); +} + +template +NzSphereGeomRef NzSphereGeom::New(Args&&... args) +{ + std::unique_ptr object(new NzSphereGeom(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); +} + +#include diff --git a/include/Nazara/Physics/PhysObject.hpp b/include/Nazara/Physics/PhysObject.hpp index 10e0bece9..a00a7ed96 100644 --- a/include/Nazara/Physics/PhysObject.hpp +++ b/include/Nazara/Physics/PhysObject.hpp @@ -13,8 +13,8 @@ #include #include #include +#include -class NzBaseGeom; class NzPhysWorld; struct NewtonBody; @@ -22,7 +22,7 @@ class NAZARA_API NzPhysObject : NzNonCopyable { public: NzPhysObject(NzPhysWorld* world, const NzMatrix4f& mat = NzMatrix4f::Identity()); - NzPhysObject(NzPhysWorld* world, const NzBaseGeom* geom, const NzMatrix4f& mat = NzMatrix4f::Identity()); + NzPhysObject(NzPhysWorld* world, NzPhysGeomRef geom, const NzMatrix4f& mat = NzMatrix4f::Identity()); ~NzPhysObject(); void AddForce(const NzVector3f& force, nzCoordSys coordSys = nzCoordSys_Global); @@ -31,7 +31,9 @@ class NAZARA_API NzPhysObject : NzNonCopyable void EnableAutoSleep(bool autoSleep); + NzBoxf GetAABB() const; NzVector3f GetAngularVelocity() const; + const NzPhysGeomRef& GetGeom() const; float GetGravityFactor() const; NewtonBody* GetHandle() const; float GetMass() const; @@ -45,6 +47,7 @@ class NAZARA_API NzPhysObject : NzNonCopyable bool IsMoveable() const; bool IsSleeping() const; + void SetGeom(NzPhysGeomRef geom); void SetGravityFactor(float gravityFactor); void SetMass(float mass); void SetMassCenter(const NzVector3f& center); @@ -60,9 +63,8 @@ class NAZARA_API NzPhysObject : NzNonCopyable NzVector3f m_forceAccumulator; NzVector3f m_torqueAccumulator; NewtonBody* m_body; - const NzBaseGeom* m_geom; + NzPhysGeomRef m_geom; NzPhysWorld* m_world; - bool m_ownsGeom; float m_gravityFactor; float m_mass; }; diff --git a/src/Nazara/Physics/Geom.cpp b/src/Nazara/Physics/Geom.cpp index 8bb344ba4..9e2f59e99 100644 --- a/src/Nazara/Physics/Geom.cpp +++ b/src/Nazara/Physics/Geom.cpp @@ -10,22 +10,22 @@ namespace { - NzBaseGeom* CreateGeomFromPrimitive(NzPhysWorld* physWorld, const NzPrimitive& primitive) + NzPhysGeom* CreateGeomFromPrimitive(NzPhysWorld* physWorld, const NzPrimitive& primitive) { switch (primitive.type) { case nzPrimitiveType_Box: - return new NzBoxGeom(physWorld, primitive.box.lengths, primitive.matrix); + return NzBoxGeom::New(physWorld, primitive.box.lengths, primitive.matrix); case nzPrimitiveType_Cone: - return new NzConeGeom(physWorld, primitive.cone.length, primitive.cone.radius, primitive.matrix); + return NzConeGeom::New(physWorld, primitive.cone.length, primitive.cone.radius, primitive.matrix); case nzPrimitiveType_Plane: - return new NzBoxGeom(physWorld, NzVector3f(primitive.plane.size.x, 0.01f, primitive.plane.size.y), primitive.matrix); + return NzBoxGeom::New(physWorld, NzVector3f(primitive.plane.size.x, 0.01f, primitive.plane.size.y), primitive.matrix); ///TODO: PlaneGeom? case nzPrimitiveType_Sphere: - return new NzSphereGeom(physWorld, primitive.sphere.size, primitive.matrix.GetTranslation()); + return NzSphereGeom::New(physWorld, primitive.sphere.size, primitive.matrix.GetTranslation()); } NazaraError("Primitive type not handled (0x" + NzString::Number(primitive.type, 16) + ')'); @@ -33,17 +33,17 @@ namespace } } -NzBaseGeom::NzBaseGeom(NzPhysWorld* physWorld) : +NzPhysGeom::NzPhysGeom(NzPhysWorld* physWorld) : m_world(physWorld) { } -NzBaseGeom::~NzBaseGeom() +NzPhysGeom::~NzPhysGeom() { NewtonDestroyCollision(m_collision); } -NzBoxf NzBaseGeom::ComputeAABB(const NzVector3f& translation, const NzQuaternionf& rotation, const NzVector3f& scale) const +NzBoxf NzPhysGeom::ComputeAABB(const NzVector3f& translation, const NzQuaternionf& rotation, const NzVector3f& scale) const { NzVector3f min, max; NewtonCollisionCalculateAABB(m_collision, NzMatrix4f::Transform(translation, rotation), min, max); @@ -52,7 +52,7 @@ NzBoxf NzBaseGeom::ComputeAABB(const NzVector3f& translation, const NzQuaternion return NzBoxf(scale*min, scale*max); } -NzBoxf NzBaseGeom::ComputeAABB(const NzMatrix4f& offsetMatrix) const +NzBoxf NzPhysGeom::ComputeAABB(const NzMatrix4f& offsetMatrix) const { NzVector3f min, max; NewtonCollisionCalculateAABB(m_collision, offsetMatrix, min, max); @@ -60,7 +60,7 @@ NzBoxf NzBaseGeom::ComputeAABB(const NzMatrix4f& offsetMatrix) const return NzBoxf(min, max); } -void NzBaseGeom::ComputeInertialMatrix(NzVector3f* inertia, NzVector3f* center) const +void NzPhysGeom::ComputeInertialMatrix(NzVector3f* inertia, NzVector3f* center) const { float inertiaMatrix[3]; float origin[3]; @@ -74,22 +74,22 @@ void NzBaseGeom::ComputeInertialMatrix(NzVector3f* inertia, NzVector3f* center) center->Set(origin); } -float NzBaseGeom::ComputeVolume() const +float NzPhysGeom::ComputeVolume() const { return NewtonConvexCollisionCalculateVolume(m_collision); } -NewtonCollision* NzBaseGeom::GetHandle() const +NewtonCollision* NzPhysGeom::GetHandle() const { return m_collision; } -NzPhysWorld* NzBaseGeom::GetWorld() const +NzPhysWorld* NzPhysGeom::GetWorld() const { return m_world; } -NzBaseGeom* NzBaseGeom::Build(NzPhysWorld* physWorld, const NzPrimitiveList& list) +NzPhysGeomRef NzPhysGeom::Build(NzPhysWorld* physWorld, const NzPrimitiveList& list) { unsigned int primitiveCount = list.GetSize(); @@ -103,21 +103,23 @@ NzBaseGeom* NzBaseGeom::Build(NzPhysWorld* physWorld, const NzPrimitiveList& lis if (primitiveCount > 1) { - std::vector geoms(primitiveCount); + std::vector geoms(primitiveCount); for (unsigned int i = 0; i < primitiveCount; ++i) geoms[i] = CreateGeomFromPrimitive(physWorld, list.GetPrimitive(i)); - return new NzCompoundGeom(physWorld, &geoms[0], primitiveCount); + return NzCompoundGeom::New(physWorld, &geoms[0], primitiveCount); } else return CreateGeomFromPrimitive(physWorld, list.GetPrimitive(0)); } +NzPhysGeomLibrary::LibraryMap NzPhysGeom::s_library; + /********************************** BoxGeom **********************************/ NzBoxGeom::NzBoxGeom(NzPhysWorld* physWorld, const NzVector3f& lengths, const NzMatrix4f& transformMatrix) : -NzBaseGeom(physWorld), +NzPhysGeom(physWorld), m_lengths(lengths) { m_collision = NewtonCreateBox(physWorld->GetHandle(), lengths.x, lengths.y, lengths.z, 0, transformMatrix); @@ -141,7 +143,7 @@ nzGeomType NzBoxGeom::GetType() const /******************************** CapsuleGeom ********************************/ NzCapsuleGeom::NzCapsuleGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix) : -NzBaseGeom(physWorld), +NzPhysGeom(physWorld), m_length(length), m_radius(radius) { @@ -170,8 +172,8 @@ nzGeomType NzCapsuleGeom::GetType() const /******************************* CompoundGeom ********************************/ -NzCompoundGeom::NzCompoundGeom(NzPhysWorld* physWorld, NzBaseGeom** geoms, unsigned int geomCount) : -NzBaseGeom(physWorld) +NzCompoundGeom::NzCompoundGeom(NzPhysWorld* physWorld, NzPhysGeom** geoms, unsigned int geomCount) : +NzPhysGeom(physWorld) { m_collision = NewtonCreateCompoundCollision(physWorld->GetHandle(), 0); NewtonCompoundCollisionBeginAddRemove(m_collision); @@ -195,7 +197,7 @@ nzGeomType NzCompoundGeom::GetType() const /********************************* ConeGeom **********************************/ NzConeGeom::NzConeGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix) : -NzBaseGeom(physWorld), +NzPhysGeom(physWorld), m_length(length), m_radius(radius) { @@ -225,7 +227,7 @@ nzGeomType NzConeGeom::GetType() const /****************************** ConvexHullGeom *******************************/ NzConvexHullGeom::NzConvexHullGeom(NzPhysWorld* physWorld, const void* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const NzMatrix4f& transformMatrix) : -NzBaseGeom(physWorld) +NzPhysGeom(physWorld) { m_collision = NewtonCreateConvexHull(physWorld->GetHandle(), vertexCount, reinterpret_cast(vertices), stride, tolerance, 0, transformMatrix); } @@ -243,7 +245,7 @@ nzGeomType NzConvexHullGeom::GetType() const /******************************* CylinderGeom ********************************/ NzCylinderGeom::NzCylinderGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix) : -NzBaseGeom(physWorld), +NzPhysGeom(physWorld), m_length(length), m_radius(radius) { @@ -273,7 +275,7 @@ nzGeomType NzCylinderGeom::GetType() const /********************************* NullGeom **********************************/ NzNullGeom::NzNullGeom(NzPhysWorld* physWorld) : -NzBaseGeom(physWorld) +NzPhysGeom(physWorld) { m_collision = NewtonCreateNull(physWorld->GetHandle()); } @@ -286,7 +288,7 @@ nzGeomType NzNullGeom::GetType() const /******************************** SphereGeom *********************************/ NzSphereGeom::NzSphereGeom(NzPhysWorld* physWorld, float radius, const NzMatrix4f& transformMatrix) : -NzBaseGeom(physWorld), +NzPhysGeom(physWorld), m_radius(radius) { m_collision = NewtonCreateSphere(physWorld->GetHandle(), radius, 0, transformMatrix); diff --git a/src/Nazara/Physics/PhysObject.cpp b/src/Nazara/Physics/PhysObject.cpp index bde930811..4131802bc 100644 --- a/src/Nazara/Physics/PhysObject.cpp +++ b/src/Nazara/Physics/PhysObject.cpp @@ -4,55 +4,35 @@ #include #include -#include #include #include +#include #include NzPhysObject::NzPhysObject(NzPhysWorld* world, const NzMatrix4f& mat) : -m_matrix(mat), -m_forceAccumulator(NzVector3f::Zero()), -m_torqueAccumulator(NzVector3f::Zero()), -m_world(world), -m_ownsGeom(true), -m_gravityFactor(1.f), -m_mass(0.f) +NzPhysObject(world, NzNullGeom::New(world), mat) { - #if NAZARA_PHYSICS_SAFE - if (!world) - NazaraError("Invalid physics world"); ///TODO: Unexcepted - #endif - - m_geom = new NzNullGeom(world); - m_body = NewtonCreateDynamicBody(world->GetHandle(), m_geom->GetHandle(), mat); - NewtonBodySetUserData(m_body, this); } -NzPhysObject::NzPhysObject(NzPhysWorld* world, const NzBaseGeom* geom, const NzMatrix4f& mat) : +NzPhysObject::NzPhysObject(NzPhysWorld* world, NzPhysGeomRef geom, const NzMatrix4f& mat) : m_matrix(mat), m_forceAccumulator(NzVector3f::Zero()), m_torqueAccumulator(NzVector3f::Zero()), -m_geom(geom), +m_geom(std::move(geom)), m_world(world), -m_ownsGeom(false), m_gravityFactor(1.f), m_mass(0.f) { - #if NAZARA_PHYSICS_SAFE - if (!world) - NazaraError("Invalid physics world"); ///TODO: Unexcepted - #endif + NazaraAssert(m_world, "Invalid world"); + NazaraAssert(m_geom, "Invalid geometry"); - m_body = NewtonCreateDynamicBody(world->GetHandle(), geom->GetHandle(), mat); + m_body = NewtonCreateDynamicBody(world->GetHandle(), m_geom->GetHandle(), mat); NewtonBodySetUserData(m_body, this); } NzPhysObject::~NzPhysObject() { NewtonDestroyBody(m_world->GetHandle(), m_body); - - if (m_ownsGeom) - delete m_geom; } void NzPhysObject::AddForce(const NzVector3f& force, nzCoordSys coordSys) @@ -112,6 +92,14 @@ void NzPhysObject::EnableAutoSleep(bool autoSleep) NewtonBodySetAutoSleep(m_body, autoSleep); } +NzBoxf NzPhysObject::GetAABB() const +{ + NzVector3f min, max; + NewtonBodyGetAABB(m_body, min, max); + + return NzBoxf(min, max); +} + NzVector3f NzPhysObject::GetAngularVelocity() const { NzVector3f angularVelocity; @@ -120,6 +108,11 @@ NzVector3f NzPhysObject::GetAngularVelocity() const return angularVelocity; } +const NzPhysGeomRef& NzPhysObject::GetGeom() const +{ + return m_geom; +} + float NzPhysObject::GetGravityFactor() const { return m_gravityFactor; @@ -191,6 +184,14 @@ bool NzPhysObject::IsSleeping() const return NewtonBodyGetSleepState(m_body) != 0; } +void NzPhysObject::SetGeom(NzPhysGeomRef geom) +{ + if (geom) + m_geom = geom; + else + m_geom = NzNullGeom::New(m_world); +} + void NzPhysObject::SetGravityFactor(float gravityFactor) { m_gravityFactor = gravityFactor; @@ -240,6 +241,7 @@ void NzPhysObject::SetRotation(const NzQuaternionf& rotation) void NzPhysObject::UpdateBody() { NewtonBodySetMatrix(m_body, m_matrix); + /*for (std::set::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it) (*it)->PhysObjectOnUpdate(this);*/ } From f7d6107ec738c83e12b01887dbd4a2a95ccde7d4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 19 Apr 2015 18:11:04 +0200 Subject: [PATCH 02/29] Physics/Geom: CompoundGeom can now include other CompounedGeom pieces Former-commit-id: 8e421be85985bfb86ee7f6fd24569e36afdb34b4 --- include/Nazara/Physics/Geom.hpp | 4 ++++ src/Nazara/Physics/Geom.cpp | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Physics/Geom.hpp b/include/Nazara/Physics/Geom.hpp index 489043f3a..d85077b9d 100644 --- a/include/Nazara/Physics/Geom.hpp +++ b/include/Nazara/Physics/Geom.hpp @@ -118,9 +118,13 @@ class NAZARA_API NzCompoundGeom : public NzPhysGeom public: NzCompoundGeom(NzPhysWorld* physWorld, NzPhysGeom** geoms, unsigned int geomCount); + const std::vector& GetGeoms() const; nzGeomType GetType() const override; template static NzCompoundGeomRef New(Args&&... args); + + private: + std::vector m_geoms; }; class NzConeGeom; diff --git a/src/Nazara/Physics/Geom.cpp b/src/Nazara/Physics/Geom.cpp index 9e2f59e99..681628a9a 100644 --- a/src/Nazara/Physics/Geom.cpp +++ b/src/Nazara/Physics/Geom.cpp @@ -178,17 +178,29 @@ NzPhysGeom(physWorld) m_collision = NewtonCreateCompoundCollision(physWorld->GetHandle(), 0); NewtonCompoundCollisionBeginAddRemove(m_collision); + m_geoms.reserve(geomCount); for (unsigned int i = 0; i < geomCount; ++i) { if (geoms[i]->GetType() == nzGeomType_Compound) - NazaraError("Cannot add compound geoms to other compound geoms"); + { + NzCompoundGeom* compoundGeom = static_cast(geoms[i]); + for (const NzPhysGeomRef& geom : compoundGeom->GetGeoms()) + NewtonCompoundCollisionAddSubCollision(m_collision, geom->GetHandle()); + } else NewtonCompoundCollisionAddSubCollision(m_collision, geoms[i]->GetHandle()); + + m_geoms.emplace_back(geoms[i]); } NewtonCompoundCollisionEndAddRemove(m_collision); } +const std::vector& NzCompoundGeom::GetGeoms() const +{ + return m_geoms; +} + nzGeomType NzCompoundGeom::GetType() const { return nzGeomType_Compound; From 61c6baeabe68b00c25daa704b5926dae7df66920 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 19 Apr 2015 23:20:13 +0200 Subject: [PATCH 03/29] Physics/PhysObject: Added Copy/Move constructor/operator Former-commit-id: 3cec9759476de4eb1adb470d436aa40698357c50 --- include/Nazara/Physics/PhysObject.hpp | 7 +++- src/Nazara/Physics/PhysObject.cpp | 60 +++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Physics/PhysObject.hpp b/include/Nazara/Physics/PhysObject.hpp index a00a7ed96..e4fd64735 100644 --- a/include/Nazara/Physics/PhysObject.hpp +++ b/include/Nazara/Physics/PhysObject.hpp @@ -23,6 +23,8 @@ class NAZARA_API NzPhysObject : NzNonCopyable public: NzPhysObject(NzPhysWorld* world, const NzMatrix4f& mat = NzMatrix4f::Identity()); NzPhysObject(NzPhysWorld* world, NzPhysGeomRef geom, const NzMatrix4f& mat = NzMatrix4f::Identity()); + NzPhysObject(const NzPhysObject& object); + NzPhysObject(NzPhysObject&& object); ~NzPhysObject(); void AddForce(const NzVector3f& force, nzCoordSys coordSys = nzCoordSys_Global); @@ -54,16 +56,19 @@ class NAZARA_API NzPhysObject : NzNonCopyable void SetPosition(const NzVector3f& position); void SetRotation(const NzQuaternionf& rotation); + NzPhysObject& operator=(NzPhysObject object); + NzPhysObject& operator=(NzPhysObject&& object); + private: void UpdateBody(); static void ForceAndTorqueCallback(const NewtonBody* body, float timeStep, int threadIndex); static void TransformCallback(const NewtonBody* body, const float* matrix, int threadIndex); NzMatrix4f m_matrix; + NzPhysGeomRef m_geom; NzVector3f m_forceAccumulator; NzVector3f m_torqueAccumulator; NewtonBody* m_body; - NzPhysGeomRef m_geom; NzPhysWorld* m_world; float m_gravityFactor; float m_mass; diff --git a/src/Nazara/Physics/PhysObject.cpp b/src/Nazara/Physics/PhysObject.cpp index 4131802bc..56ff5b080 100644 --- a/src/Nazara/Physics/PhysObject.cpp +++ b/src/Nazara/Physics/PhysObject.cpp @@ -16,9 +16,9 @@ NzPhysObject(world, NzNullGeom::New(world), mat) NzPhysObject::NzPhysObject(NzPhysWorld* world, NzPhysGeomRef geom, const NzMatrix4f& mat) : m_matrix(mat), +m_geom(std::move(geom)), m_forceAccumulator(NzVector3f::Zero()), m_torqueAccumulator(NzVector3f::Zero()), -m_geom(std::move(geom)), m_world(world), m_gravityFactor(1.f), m_mass(0.f) @@ -26,13 +26,44 @@ m_mass(0.f) NazaraAssert(m_world, "Invalid world"); NazaraAssert(m_geom, "Invalid geometry"); - m_body = NewtonCreateDynamicBody(world->GetHandle(), m_geom->GetHandle(), mat); + m_body = NewtonCreateDynamicBody(m_world->GetHandle(), m_geom->GetHandle(), m_matrix); NewtonBodySetUserData(m_body, this); } +NzPhysObject::NzPhysObject(const NzPhysObject& object) : +m_matrix(object.m_matrix), +m_geom(object.m_geom), +m_forceAccumulator(NzVector3f::Zero()), +m_torqueAccumulator(NzVector3f::Zero()), +m_world(object.m_world), +m_gravityFactor(object.m_gravityFactor), +m_mass(0.f) +{ + NazaraAssert(m_world, "Invalid world"); + NazaraAssert(m_geom, "Invalid geometry"); + + m_body = NewtonCreateDynamicBody(m_world->GetHandle(), m_geom->GetHandle(), m_matrix); + NewtonBodySetUserData(m_body, this); + SetMass(object.m_mass); +} + +NzPhysObject::NzPhysObject(NzPhysObject&& object) : +m_matrix(std::move(object)), +m_forceAccumulator(std::move(object.m_forceAccumulator)), +m_torqueAccumulator(std::move(object.m_torqueAccumulator)), +m_body(object.m_body), +m_geom(std::move(object.m_geom)), +m_world(object.m_world), +m_gravityFactor(object.m_gravityFactor), +m_mass(object.m_mass) +{ + object.m_body = nullptr; +} + NzPhysObject::~NzPhysObject() { - NewtonDestroyBody(m_world->GetHandle(), m_body); + if (m_body) + NewtonDestroyBody(m_world->GetHandle(), m_body); } void NzPhysObject::AddForce(const NzVector3f& force, nzCoordSys coordSys) @@ -238,6 +269,13 @@ void NzPhysObject::SetRotation(const NzQuaternionf& rotation) UpdateBody(); } +NzPhysObject& NzPhysObject::operator=(NzPhysObject object) +{ + std::swap(*this, object); + + return *this; +} + void NzPhysObject::UpdateBody() { NewtonBodySetMatrix(m_body, m_matrix); @@ -246,6 +284,22 @@ void NzPhysObject::UpdateBody() (*it)->PhysObjectOnUpdate(this);*/ } +NzPhysObject& NzPhysObject::operator=(NzPhysObject&& object) +{ + m_body = object.m_body; + m_forceAccumulator = std::move(object.m_forceAccumulator); + m_geom = std::move(object.m_geom); + m_gravityFactor = object.m_gravityFactor; + m_mass = object.m_mass; + m_matrix = std::move(object.m_matrix); + m_torqueAccumulator = std::move(object.m_torqueAccumulator); + m_world = object.m_world; + + object.m_body = nullptr; + + return *this; +} + void NzPhysObject::ForceAndTorqueCallback(const NewtonBody* body, float timeStep, int threadIndex) { NazaraUnused(timeStep); From 1c7c1de3e7acf33c366ee27845db154dd0ae6734 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 20 Apr 2015 01:28:18 +0200 Subject: [PATCH 04/29] Physics/PhysObject: Fixed Copy/Move operator Former-commit-id: 58377ee8d41ef39ade38fcbf03355af5e7d7db58 --- include/Nazara/Physics/PhysObject.hpp | 2 +- src/Nazara/Physics/PhysObject.cpp | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/Nazara/Physics/PhysObject.hpp b/include/Nazara/Physics/PhysObject.hpp index e4fd64735..92c71a2bb 100644 --- a/include/Nazara/Physics/PhysObject.hpp +++ b/include/Nazara/Physics/PhysObject.hpp @@ -56,7 +56,7 @@ class NAZARA_API NzPhysObject : NzNonCopyable void SetPosition(const NzVector3f& position); void SetRotation(const NzQuaternionf& rotation); - NzPhysObject& operator=(NzPhysObject object); + NzPhysObject& operator=(const NzPhysObject& object); NzPhysObject& operator=(NzPhysObject&& object); private: diff --git a/src/Nazara/Physics/PhysObject.cpp b/src/Nazara/Physics/PhysObject.cpp index 56ff5b080..038a7062d 100644 --- a/src/Nazara/Physics/PhysObject.cpp +++ b/src/Nazara/Physics/PhysObject.cpp @@ -269,11 +269,8 @@ void NzPhysObject::SetRotation(const NzQuaternionf& rotation) UpdateBody(); } -NzPhysObject& NzPhysObject::operator=(NzPhysObject object) +NzPhysObject& NzPhysObject::operator=(const NzPhysObject& object) { - std::swap(*this, object); - - return *this; } void NzPhysObject::UpdateBody() @@ -282,10 +279,15 @@ void NzPhysObject::UpdateBody() /*for (std::set::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it) (*it)->PhysObjectOnUpdate(this);*/ + NzPhysObject physObj(object); + return operator=(std::move(physObj)); } NzPhysObject& NzPhysObject::operator=(NzPhysObject&& object) { + if (m_body) + NewtonDestroyBody(m_world->GetHandle(), m_body); + m_body = object.m_body; m_forceAccumulator = std::move(object.m_forceAccumulator); m_geom = std::move(object.m_geom); From 06b265126446ab240a34beb4cc7d8d59ddf8ee90 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 20 Apr 2015 01:34:17 +0200 Subject: [PATCH 05/29] Physics/Geom: Geoms no longer need a pointer to PhysWorld Former-commit-id: 7f9372e3ec13525208b49bc3fd07787657f64acb --- include/Nazara/Physics/Geom.hpp | 86 +++++++--- src/Nazara/Physics/Geom.cpp | 279 ++++++++++++++++++++++---------- 2 files changed, 252 insertions(+), 113 deletions(-) diff --git a/include/Nazara/Physics/Geom.hpp b/include/Nazara/Physics/Geom.hpp index d85077b9d..81319d713 100644 --- a/include/Nazara/Physics/Geom.hpp +++ b/include/Nazara/Physics/Geom.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -18,6 +18,7 @@ #include #include #include +#include ///TODO: CollisionModifier ///TODO: HeightfieldGeom @@ -38,24 +39,23 @@ using NzPhysGeomRef = NzObjectRef; class NAZARA_API NzPhysGeom : public NzRefCounted, NzNonCopyable { public: - NzPhysGeom(NzPhysWorld* physWorld); + NzPhysGeom() = default; virtual ~NzPhysGeom(); - virtual NzBoxf ComputeAABB(const NzVector3f& translation, const NzQuaternionf& rotation, const NzVector3f& scale) const; - virtual NzBoxf ComputeAABB(const NzMatrix4f& offsetMatrix = NzMatrix4f::Identity()) const; + NzBoxf ComputeAABB(const NzVector3f& translation, const NzQuaternionf& rotation, const NzVector3f& scale) const; + virtual NzBoxf ComputeAABB(const NzMatrix4f& offsetMatrix = NzMatrix4f::Identity(), const NzVector3f& scale = NzVector3f::Unit()) const; virtual void ComputeInertialMatrix(NzVector3f* inertia, NzVector3f* center) const; virtual float ComputeVolume() const; - NewtonCollision* GetHandle() const; + NewtonCollision* GetHandle(NzPhysWorld* world) const; virtual nzGeomType GetType() const = 0; - NzPhysWorld* GetWorld() const; - - static NzPhysGeomRef Build(NzPhysWorld* physWorld, const NzPrimitiveList& list); + static NzPhysGeomRef Build(const NzPrimitiveList& list); protected: - NewtonCollision* m_collision; - NzPhysWorld* m_world; + virtual NewtonCollision* CreateHandle(NzPhysWorld* world) const = 0; + + mutable std::unordered_map m_handles; static NzPhysGeomLibrary::LibraryMap s_library; }; @@ -70,8 +70,11 @@ using NzBoxGeomRef = NzObjectRef; class NAZARA_API NzBoxGeom : public NzPhysGeom { public: - NzBoxGeom(NzPhysWorld* physWorld, const NzVector3f& lengths, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - NzBoxGeom(NzPhysWorld* physWorld, const NzVector3f& lengths, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); + NzBoxGeom(const NzVector3f& lengths, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); + NzBoxGeom(const NzVector3f& lengths, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); + + NzBoxf ComputeAABB(const NzMatrix4f& offsetMatrix = NzMatrix4f::Identity(), const NzVector3f& scale = NzVector3f::Unit()) const override; + float ComputeVolume() const override; NzVector3f GetLengths() const; nzGeomType GetType() const override; @@ -79,6 +82,9 @@ class NAZARA_API NzBoxGeom : public NzPhysGeom template static NzBoxGeomRef New(Args&&... args); private: + NewtonCollision* CreateHandle(NzPhysWorld* world) const override; + + NzMatrix4f m_matrix; NzVector3f m_lengths; }; @@ -92,8 +98,8 @@ using NzCapsuleGeomRef = NzObjectRef; class NAZARA_API NzCapsuleGeom : public NzPhysGeom { public: - NzCapsuleGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - NzCapsuleGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); + NzCapsuleGeom(float length, float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); + NzCapsuleGeom(float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); float GetLength() const; float GetRadius() const; @@ -102,6 +108,9 @@ class NAZARA_API NzCapsuleGeom : public NzPhysGeom template static NzCapsuleGeomRef New(Args&&... args); private: + NewtonCollision* CreateHandle(NzPhysWorld* world) const override; + + NzMatrix4f m_matrix; float m_length; float m_radius; }; @@ -116,7 +125,7 @@ using NzCompoundGeomRef = NzObjectRef; class NAZARA_API NzCompoundGeom : public NzPhysGeom { public: - NzCompoundGeom(NzPhysWorld* physWorld, NzPhysGeom** geoms, unsigned int geomCount); + NzCompoundGeom(NzPhysGeom** geoms, unsigned int geomCount); const std::vector& GetGeoms() const; nzGeomType GetType() const override; @@ -124,6 +133,8 @@ class NAZARA_API NzCompoundGeom : public NzPhysGeom template static NzCompoundGeomRef New(Args&&... args); private: + NewtonCollision* CreateHandle(NzPhysWorld* world) const override; + std::vector m_geoms; }; @@ -137,8 +148,8 @@ using NzConeGeomRef = NzObjectRef; class NAZARA_API NzConeGeom : public NzPhysGeom { public: - NzConeGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - NzConeGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); + NzConeGeom(float length, float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); + NzConeGeom(float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); float GetLength() const; float GetRadius() const; @@ -147,6 +158,9 @@ class NAZARA_API NzConeGeom : public NzPhysGeom template static NzConeGeomRef New(Args&&... args); private: + NewtonCollision* CreateHandle(NzPhysWorld* world) const override; + + NzMatrix4f m_matrix; float m_length; float m_radius; }; @@ -161,12 +175,20 @@ using NzConvexHullGeomRef = NzObjectRef; class NAZARA_API NzConvexHullGeom : public NzPhysGeom { public: - NzConvexHullGeom(NzPhysWorld* physWorld, const void* vertices, unsigned int vertexCount, unsigned int stride = sizeof(NzVector3f), float tolerance = 0.002f, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - NzConvexHullGeom(NzPhysWorld* physWorld, const void* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); + NzConvexHullGeom(const void* vertices, unsigned int vertexCount, unsigned int stride = sizeof(NzVector3f), float tolerance = 0.002f, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); + NzConvexHullGeom(const void* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); nzGeomType GetType() const override; template static NzConvexHullGeomRef New(Args&&... args); + + private: + NewtonCollision* CreateHandle(NzPhysWorld* world) const override; + + std::vector m_vertices; + NzMatrix4f m_matrix; + float m_tolerance; + unsigned int m_vertexStride; }; class NzCylinderGeom; @@ -179,8 +201,8 @@ using NzCylinderGeomRef = NzObjectRef; class NAZARA_API NzCylinderGeom : public NzPhysGeom { public: - NzCylinderGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - NzCylinderGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); + NzCylinderGeom(float length, float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); + NzCylinderGeom(float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); float GetLength() const; float GetRadius() const; @@ -189,6 +211,9 @@ class NAZARA_API NzCylinderGeom : public NzPhysGeom template static NzCylinderGeomRef New(Args&&... args); private: + NewtonCollision* CreateHandle(NzPhysWorld* world) const override; + + NzMatrix4f m_matrix; float m_length; float m_radius; }; @@ -203,11 +228,14 @@ using NzNullGeomRef = NzObjectRef; class NAZARA_API NzNullGeom : public NzPhysGeom { public: - NzNullGeom(NzPhysWorld* physWorld); + NzNullGeom(); nzGeomType GetType() const override; template static NzNullGeomRef New(Args&&... args); + + private: + NewtonCollision* CreateHandle(NzPhysWorld* world) const override; }; class NzSphereGeom; @@ -220,16 +248,22 @@ using NzSphereGeomRef = NzObjectRef; class NAZARA_API NzSphereGeom : public NzPhysGeom { public: - NzSphereGeom(NzPhysWorld* physWorld, float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - NzSphereGeom(NzPhysWorld* physWorld, float radius, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); + NzSphereGeom(float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); + NzSphereGeom(float radius, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); - NzVector3f GetRadius() const; + NzBoxf ComputeAABB(const NzMatrix4f& offsetMatrix = NzMatrix4f::Identity(), const NzVector3f& scale = NzVector3f::Unit()) const override; + float ComputeVolume() const override; + + float GetRadius() const; nzGeomType GetType() const override; template static NzSphereGeomRef New(Args&&... args); private: - NzVector3f m_radius; + NewtonCollision* CreateHandle(NzPhysWorld* world) const override; + + NzVector3f m_position; + float m_radius; }; #include diff --git a/src/Nazara/Physics/Geom.cpp b/src/Nazara/Physics/Geom.cpp index 681628a9a..0651921af 100644 --- a/src/Nazara/Physics/Geom.cpp +++ b/src/Nazara/Physics/Geom.cpp @@ -10,54 +10,59 @@ namespace { - NzPhysGeom* CreateGeomFromPrimitive(NzPhysWorld* physWorld, const NzPrimitive& primitive) + NzPhysGeomRef CreateGeomFromPrimitive(const NzPrimitive& primitive) { switch (primitive.type) { case nzPrimitiveType_Box: - return NzBoxGeom::New(physWorld, primitive.box.lengths, primitive.matrix); + return NzBoxGeom::New(primitive.box.lengths, primitive.matrix); case nzPrimitiveType_Cone: - return NzConeGeom::New(physWorld, primitive.cone.length, primitive.cone.radius, primitive.matrix); + return NzConeGeom::New(primitive.cone.length, primitive.cone.radius, primitive.matrix); case nzPrimitiveType_Plane: - return NzBoxGeom::New(physWorld, NzVector3f(primitive.plane.size.x, 0.01f, primitive.plane.size.y), primitive.matrix); + return NzBoxGeom::New(NzVector3f(primitive.plane.size.x, 0.01f, primitive.plane.size.y), primitive.matrix); ///TODO: PlaneGeom? case nzPrimitiveType_Sphere: - return NzSphereGeom::New(physWorld, primitive.sphere.size, primitive.matrix.GetTranslation()); + return NzSphereGeom::New(primitive.sphere.size, primitive.matrix.GetTranslation()); } NazaraError("Primitive type not handled (0x" + NzString::Number(primitive.type, 16) + ')'); - return nullptr; + return NzPhysGeomRef(); } } -NzPhysGeom::NzPhysGeom(NzPhysWorld* physWorld) : -m_world(physWorld) -{ -} - NzPhysGeom::~NzPhysGeom() { - NewtonDestroyCollision(m_collision); + for (auto& pair : m_handles) + NewtonDestroyCollision(pair.second); } NzBoxf NzPhysGeom::ComputeAABB(const NzVector3f& translation, const NzQuaternionf& rotation, const NzVector3f& scale) const { - NzVector3f min, max; - NewtonCollisionCalculateAABB(m_collision, NzMatrix4f::Transform(translation, rotation), min, max); - - // Et on applique le scale à la fin - return NzBoxf(scale*min, scale*max); + return ComputeAABB(NzMatrix4f::Transform(translation, rotation), scale); } -NzBoxf NzPhysGeom::ComputeAABB(const NzMatrix4f& offsetMatrix) const +NzBoxf NzPhysGeom::ComputeAABB(const NzMatrix4f& offsetMatrix, const NzVector3f& scale) const { NzVector3f min, max; - NewtonCollisionCalculateAABB(m_collision, offsetMatrix, min, max); - return NzBoxf(min, max); + // Si nous n'avons aucune instance, nous en créons une temporaire + if (m_handles.empty()) + { + NzPhysWorld world; + + NewtonCollision* collision = CreateHandle(&world); + { + NewtonCollisionCalculateAABB(collision, offsetMatrix, min, max); + } + NewtonDestroyCollision(collision); + } + else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute façon) + NewtonCollisionCalculateAABB(m_handles.begin()->second, offsetMatrix, min, max); + + return NzBoxf(scale * min, scale * max); } void NzPhysGeom::ComputeInertialMatrix(NzVector3f* inertia, NzVector3f* center) const @@ -65,7 +70,19 @@ void NzPhysGeom::ComputeInertialMatrix(NzVector3f* inertia, NzVector3f* center) float inertiaMatrix[3]; float origin[3]; - NewtonConvexCollisionCalculateInertialMatrix(m_collision, inertiaMatrix, origin); + // Si nous n'avons aucune instance, nous en créons une temporaire + if (m_handles.empty()) + { + NzPhysWorld world; + + NewtonCollision* collision = CreateHandle(&world); + { + NewtonConvexCollisionCalculateInertialMatrix(collision, inertiaMatrix, origin); + } + NewtonDestroyCollision(collision); + } + else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute façon) + NewtonConvexCollisionCalculateInertialMatrix(m_handles.begin()->second, inertiaMatrix, origin); if (inertia) inertia->Set(inertiaMatrix); @@ -76,20 +93,35 @@ void NzPhysGeom::ComputeInertialMatrix(NzVector3f* inertia, NzVector3f* center) float NzPhysGeom::ComputeVolume() const { - return NewtonConvexCollisionCalculateVolume(m_collision); + float volume; + + // Si nous n'avons aucune instance, nous en créons une temporaire + if (m_handles.empty()) + { + NzPhysWorld world; + + NewtonCollision* collision = CreateHandle(&world); + { + volume = NewtonConvexCollisionCalculateVolume(collision); + } + NewtonDestroyCollision(collision); + } + else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute façon) + volume = NewtonConvexCollisionCalculateVolume(m_handles.begin()->second); + + return volume; } -NewtonCollision* NzPhysGeom::GetHandle() const +NewtonCollision* NzPhysGeom::GetHandle(NzPhysWorld* world) const { - return m_collision; + auto it = m_handles.find(world); + if (it == m_handles.end()) + it = m_handles.insert(std::make_pair(world, CreateHandle(world))).first; + + return it->second; } -NzPhysWorld* NzPhysGeom::GetWorld() const -{ - return m_world; -} - -NzPhysGeomRef NzPhysGeom::Build(NzPhysWorld* physWorld, const NzPrimitiveList& list) +NzPhysGeomRef NzPhysGeom::Build(const NzPrimitiveList& list) { unsigned int primitiveCount = list.GetSize(); @@ -106,30 +138,45 @@ NzPhysGeomRef NzPhysGeom::Build(NzPhysWorld* physWorld, const NzPrimitiveList& l std::vector geoms(primitiveCount); for (unsigned int i = 0; i < primitiveCount; ++i) - geoms[i] = CreateGeomFromPrimitive(physWorld, list.GetPrimitive(i)); + geoms[i] = CreateGeomFromPrimitive(list.GetPrimitive(i)); - return NzCompoundGeom::New(physWorld, &geoms[0], primitiveCount); + return NzCompoundGeom::New(&geoms[0], primitiveCount); } else - return CreateGeomFromPrimitive(physWorld, list.GetPrimitive(0)); + return CreateGeomFromPrimitive(list.GetPrimitive(0)); } NzPhysGeomLibrary::LibraryMap NzPhysGeom::s_library; /********************************** BoxGeom **********************************/ -NzBoxGeom::NzBoxGeom(NzPhysWorld* physWorld, const NzVector3f& lengths, const NzMatrix4f& transformMatrix) : -NzPhysGeom(physWorld), +NzBoxGeom::NzBoxGeom(const NzVector3f& lengths, const NzMatrix4f& transformMatrix) : +m_matrix(transformMatrix), m_lengths(lengths) { - m_collision = NewtonCreateBox(physWorld->GetHandle(), lengths.x, lengths.y, lengths.z, 0, transformMatrix); } -NzBoxGeom::NzBoxGeom(NzPhysWorld* physWorld, const NzVector3f& lengths, const NzVector3f& translation, const NzQuaternionf& rotation) : -NzBoxGeom(physWorld, lengths, NzMatrix4f::Transform(translation, rotation)) +NzBoxGeom::NzBoxGeom(const NzVector3f& lengths, const NzVector3f& translation, const NzQuaternionf& rotation) : +NzBoxGeom(lengths, NzMatrix4f::Transform(translation, rotation)) { } +NzBoxf NzBoxGeom::ComputeAABB(const NzMatrix4f& offsetMatrix, const NzVector3f& scale) const +{ + NzVector3f halfLengths(m_lengths * 0.5f); + + NzBoxf aabb(-halfLengths.x, -halfLengths.y, -halfLengths.z, m_lengths.x, m_lengths.y, m_lengths.z); + aabb.Transform(offsetMatrix, true); + aabb *= scale; + + return aabb; +} + +float NzBoxGeom::ComputeVolume() const +{ + return m_lengths.x * m_lengths.y * m_lengths.z; +} + NzVector3f NzBoxGeom::GetLengths() const { return m_lengths; @@ -140,18 +187,22 @@ nzGeomType NzBoxGeom::GetType() const return nzGeomType_Box; } +NewtonCollision* NzBoxGeom::CreateHandle(NzPhysWorld* world) const +{ + return NewtonCreateBox(world->GetHandle(), m_lengths.x, m_lengths.y, m_lengths.z, 0, m_matrix); +} + /******************************** CapsuleGeom ********************************/ -NzCapsuleGeom::NzCapsuleGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix) : -NzPhysGeom(physWorld), +NzCapsuleGeom::NzCapsuleGeom(float length, float radius, const NzMatrix4f& transformMatrix) : +m_matrix(transformMatrix), m_length(length), m_radius(radius) { - m_collision = NewtonCreateCapsule(physWorld->GetHandle(), radius, length, 0, transformMatrix); } -NzCapsuleGeom::NzCapsuleGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) : -NzCapsuleGeom(physWorld, length, radius, NzMatrix4f::Transform(translation, rotation)) +NzCapsuleGeom::NzCapsuleGeom(float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) : +NzCapsuleGeom(length, radius, NzMatrix4f::Transform(translation, rotation)) { } @@ -170,30 +221,18 @@ nzGeomType NzCapsuleGeom::GetType() const return nzGeomType_Capsule; } +NewtonCollision* NzCapsuleGeom::CreateHandle(NzPhysWorld* world) const +{ + return NewtonCreateCapsule(world->GetHandle(), m_radius, m_length, 0, m_matrix); +} + /******************************* CompoundGeom ********************************/ -NzCompoundGeom::NzCompoundGeom(NzPhysWorld* physWorld, NzPhysGeom** geoms, unsigned int geomCount) : -NzPhysGeom(physWorld) +NzCompoundGeom::NzCompoundGeom(NzPhysGeom** geoms, unsigned int geomCount) { - m_collision = NewtonCreateCompoundCollision(physWorld->GetHandle(), 0); - NewtonCompoundCollisionBeginAddRemove(m_collision); - m_geoms.reserve(geomCount); for (unsigned int i = 0; i < geomCount; ++i) - { - if (geoms[i]->GetType() == nzGeomType_Compound) - { - NzCompoundGeom* compoundGeom = static_cast(geoms[i]); - for (const NzPhysGeomRef& geom : compoundGeom->GetGeoms()) - NewtonCompoundCollisionAddSubCollision(m_collision, geom->GetHandle()); - } - else - NewtonCompoundCollisionAddSubCollision(m_collision, geoms[i]->GetHandle()); - m_geoms.emplace_back(geoms[i]); - } - - NewtonCompoundCollisionEndAddRemove(m_collision); } const std::vector& NzCompoundGeom::GetGeoms() const @@ -206,18 +245,38 @@ nzGeomType NzCompoundGeom::GetType() const return nzGeomType_Compound; } +NewtonCollision* NzCompoundGeom::CreateHandle(NzPhysWorld* world) const +{ + NewtonCollision* compoundCollision = NewtonCreateCompoundCollision(world->GetHandle(), 0); + + NewtonCompoundCollisionBeginAddRemove(compoundCollision); + for (const NzPhysGeomRef& geom : m_geoms) + { + if (geom->GetType() == nzGeomType_Compound) + { + NzCompoundGeom* compoundGeom = static_cast(geom.Get()); + for (const NzPhysGeomRef& piece : compoundGeom->GetGeoms()) + NewtonCompoundCollisionAddSubCollision(compoundCollision, piece->GetHandle(world)); + } + else + NewtonCompoundCollisionAddSubCollision(compoundCollision, geom->GetHandle(world)); + } + NewtonCompoundCollisionEndAddRemove(compoundCollision); + + return compoundCollision; +} + /********************************* ConeGeom **********************************/ -NzConeGeom::NzConeGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix) : -NzPhysGeom(physWorld), +NzConeGeom::NzConeGeom(float length, float radius, const NzMatrix4f& transformMatrix) : +m_matrix(transformMatrix), m_length(length), m_radius(radius) { - m_collision = NewtonCreateCone(physWorld->GetHandle(), radius, length, 0, transformMatrix); } -NzConeGeom::NzConeGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) : -NzConeGeom(physWorld, length, radius, NzMatrix4f::Transform(translation, rotation)) +NzConeGeom::NzConeGeom(float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) : +NzConeGeom(length, radius, NzMatrix4f::Transform(translation, rotation)) { } @@ -236,16 +295,32 @@ nzGeomType NzConeGeom::GetType() const return nzGeomType_Cone; } -/****************************** ConvexHullGeom *******************************/ - -NzConvexHullGeom::NzConvexHullGeom(NzPhysWorld* physWorld, const void* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const NzMatrix4f& transformMatrix) : -NzPhysGeom(physWorld) +NewtonCollision* NzConeGeom::CreateHandle(NzPhysWorld* world) const { - m_collision = NewtonCreateConvexHull(physWorld->GetHandle(), vertexCount, reinterpret_cast(vertices), stride, tolerance, 0, transformMatrix); + return NewtonCreateCone(world->GetHandle(), m_radius, m_length, 0, m_matrix); } -NzConvexHullGeom::NzConvexHullGeom(NzPhysWorld* physWorld, const void* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const NzVector3f& translation, const NzQuaternionf& rotation) : -NzConvexHullGeom(physWorld, vertices, vertexCount, stride, tolerance, NzMatrix4f::Transform(translation, rotation)) +/****************************** ConvexHullGeom *******************************/ + +NzConvexHullGeom::NzConvexHullGeom(const void* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const NzMatrix4f& transformMatrix) : +m_matrix(transformMatrix), +m_tolerance(tolerance), +m_vertexStride(stride) +{ + const nzUInt8* ptr = static_cast(vertices); + + m_vertices.resize(vertexCount); + if (stride != sizeof(NzVector3f)) + { + for (unsigned int i = 0; i < vertexCount; ++i) + m_vertices[i] = *reinterpret_cast(ptr + stride*i); + } + else // Fast path + std::memcpy(m_vertices.data(), vertices, vertexCount*sizeof(NzVector3f)); +} + +NzConvexHullGeom::NzConvexHullGeom(const void* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const NzVector3f& translation, const NzQuaternionf& rotation) : +NzConvexHullGeom(vertices, vertexCount, stride, tolerance, NzMatrix4f::Transform(translation, rotation)) { } @@ -254,18 +329,22 @@ nzGeomType NzConvexHullGeom::GetType() const return nzGeomType_Compound; } +NewtonCollision* NzConvexHullGeom::CreateHandle(NzPhysWorld* world) const +{ + return NewtonCreateConvexHull(world->GetHandle(), m_vertices.size(), reinterpret_cast(m_vertices.data()), sizeof(NzVector3f), m_tolerance, 0, m_matrix); +} + /******************************* CylinderGeom ********************************/ -NzCylinderGeom::NzCylinderGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix) : -NzPhysGeom(physWorld), +NzCylinderGeom::NzCylinderGeom(float length, float radius, const NzMatrix4f& transformMatrix) : +m_matrix(transformMatrix), m_length(length), m_radius(radius) { - m_collision = NewtonCreateCylinder(physWorld->GetHandle(), radius, length, 0, transformMatrix); } -NzCylinderGeom::NzCylinderGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) : -NzCylinderGeom(physWorld, length, radius, NzMatrix4f::Transform(translation, rotation)) +NzCylinderGeom::NzCylinderGeom(float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) : +NzCylinderGeom(length, radius, NzMatrix4f::Transform(translation, rotation)) { } @@ -284,12 +363,15 @@ nzGeomType NzCylinderGeom::GetType() const return nzGeomType_Cylinder; } +NewtonCollision* NzCylinderGeom::CreateHandle(NzPhysWorld* world) const +{ + return NewtonCreateCylinder(world->GetHandle(), m_radius, m_length, 0, m_matrix); +} + /********************************* NullGeom **********************************/ -NzNullGeom::NzNullGeom(NzPhysWorld* physWorld) : -NzPhysGeom(physWorld) +NzNullGeom::NzNullGeom() { - m_collision = NewtonCreateNull(physWorld->GetHandle()); } nzGeomType NzNullGeom::GetType() const @@ -297,21 +379,39 @@ nzGeomType NzNullGeom::GetType() const return nzGeomType_Null; } +NewtonCollision* NzNullGeom::CreateHandle(NzPhysWorld* world) const +{ + return NewtonCreateNull(world->GetHandle()); +} + /******************************** SphereGeom *********************************/ -NzSphereGeom::NzSphereGeom(NzPhysWorld* physWorld, float radius, const NzMatrix4f& transformMatrix) : -NzPhysGeom(physWorld), +NzSphereGeom::NzSphereGeom(float radius, const NzMatrix4f& transformMatrix) : +NzSphereGeom(radius, transformMatrix.GetTranslation()) +{ +} + +NzSphereGeom::NzSphereGeom(float radius, const NzVector3f& translation, const NzQuaternionf& rotation) : +m_position(translation), m_radius(radius) { - m_collision = NewtonCreateSphere(physWorld->GetHandle(), radius, 0, transformMatrix); + NazaraUnused(rotation); } -NzSphereGeom::NzSphereGeom(NzPhysWorld* physWorld, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) : -NzSphereGeom(physWorld, radius, NzMatrix4f::Transform(translation, rotation)) +NzBoxf NzSphereGeom::ComputeAABB(const NzMatrix4f& offsetMatrix, const NzVector3f& scale) const { + NzVector3f size(m_radius * scale); + NzVector3f position(offsetMatrix.GetTranslation()); + + return NzBoxf(position - size, position + size); } -NzVector3f NzSphereGeom::GetRadius() const +float NzSphereGeom::ComputeVolume() const +{ + return M_PI * m_radius * m_radius * m_radius / 3.f; +} + +float NzSphereGeom::GetRadius() const { return m_radius; } @@ -320,3 +420,8 @@ nzGeomType NzSphereGeom::GetType() const { return nzGeomType_Sphere; } + +NewtonCollision* NzSphereGeom::CreateHandle(NzPhysWorld* world) const +{ + return NewtonCreateSphere(world->GetHandle(), m_radius, 0, NzMatrix4f::Translate(m_position)); +} From a7be4c6346f780b452c59967bd1f2363953b71d6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 20 Apr 2015 01:44:31 +0200 Subject: [PATCH 06/29] Physics/PhysObject: Fixed class Former-commit-id: bb5b3995e6cd8f349ad0a09258976bf163e65201 --- src/Nazara/Physics/PhysObject.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Nazara/Physics/PhysObject.cpp b/src/Nazara/Physics/PhysObject.cpp index 038a7062d..2b72272d4 100644 --- a/src/Nazara/Physics/PhysObject.cpp +++ b/src/Nazara/Physics/PhysObject.cpp @@ -10,7 +10,7 @@ #include NzPhysObject::NzPhysObject(NzPhysWorld* world, const NzMatrix4f& mat) : -NzPhysObject(world, NzNullGeom::New(world), mat) +NzPhysObject(world, NzNullGeom::New(), mat) { } @@ -26,7 +26,7 @@ m_mass(0.f) NazaraAssert(m_world, "Invalid world"); NazaraAssert(m_geom, "Invalid geometry"); - m_body = NewtonCreateDynamicBody(m_world->GetHandle(), m_geom->GetHandle(), m_matrix); + m_body = NewtonCreateDynamicBody(m_world->GetHandle(), m_geom->GetHandle(m_world), m_matrix); NewtonBodySetUserData(m_body, this); } @@ -42,13 +42,13 @@ m_mass(0.f) NazaraAssert(m_world, "Invalid world"); NazaraAssert(m_geom, "Invalid geometry"); - m_body = NewtonCreateDynamicBody(m_world->GetHandle(), m_geom->GetHandle(), m_matrix); + m_body = NewtonCreateDynamicBody(m_world->GetHandle(), m_geom->GetHandle(m_world), m_matrix); NewtonBodySetUserData(m_body, this); SetMass(object.m_mass); } NzPhysObject::NzPhysObject(NzPhysObject&& object) : -m_matrix(std::move(object)), +m_matrix(std::move(object.m_matrix)), m_forceAccumulator(std::move(object.m_forceAccumulator)), m_torqueAccumulator(std::move(object.m_torqueAccumulator)), m_body(object.m_body), @@ -220,7 +220,7 @@ void NzPhysObject::SetGeom(NzPhysGeomRef geom) if (geom) m_geom = geom; else - m_geom = NzNullGeom::New(m_world); + m_geom = NzNullGeom::New(); } void NzPhysObject::SetGravityFactor(float gravityFactor) @@ -271,6 +271,8 @@ void NzPhysObject::SetRotation(const NzQuaternionf& rotation) NzPhysObject& NzPhysObject::operator=(const NzPhysObject& object) { + NzPhysObject physObj(object); + return operator=(std::move(physObj)); } void NzPhysObject::UpdateBody() @@ -279,8 +281,6 @@ void NzPhysObject::UpdateBody() /*for (std::set::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it) (*it)->PhysObjectOnUpdate(this);*/ - NzPhysObject physObj(object); - return operator=(std::move(physObj)); } NzPhysObject& NzPhysObject::operator=(NzPhysObject&& object) From 5b44619592da6d3181c18d3c363f5ea7311d2d20 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 20 Apr 2015 01:54:09 +0200 Subject: [PATCH 07/29] Ndk/Components: Added OnComponent[Attached|Detacted] events And m_entity member variable Former-commit-id: d6bd9e382e55bafd357e7ec62862ae731c21f897 --- SDK/include/NDK/BaseComponent.hpp | 8 +++++++ SDK/include/NDK/BaseComponent.inl | 8 ++++++- SDK/src/NDK/BaseComponent.cpp | 10 +++++++++ SDK/src/NDK/Entity.cpp | 36 +++++++++++++++++++++++++------ 4 files changed, 55 insertions(+), 7 deletions(-) diff --git a/SDK/include/NDK/BaseComponent.hpp b/SDK/include/NDK/BaseComponent.hpp index 53a6121ec..fc1e88058 100644 --- a/SDK/include/NDK/BaseComponent.hpp +++ b/SDK/include/NDK/BaseComponent.hpp @@ -14,8 +14,11 @@ namespace Ndk { + class Entity; + class NDK_API BaseComponent { + friend Entity; friend class Sdk; public: @@ -35,10 +38,15 @@ namespace Ndk protected: ComponentIndex m_componentIndex; + Entity* m_entity; static ComponentIndex RegisterComponent(ComponentId id, Factory factoryFunc); private: + virtual void OnComponentAttached(BaseComponent& component); + virtual void OnComponentDetached(BaseComponent& component); + void SetEntity(Entity* entity); + static bool Initialize(); static void Uninitialize(); diff --git a/SDK/include/NDK/BaseComponent.inl b/SDK/include/NDK/BaseComponent.inl index 0ac1678e0..290a5de2d 100644 --- a/SDK/include/NDK/BaseComponent.inl +++ b/SDK/include/NDK/BaseComponent.inl @@ -7,7 +7,8 @@ namespace Ndk { inline BaseComponent::BaseComponent(ComponentIndex index) : - m_componentIndex(index) + m_componentIndex(index), + m_entity(nullptr) { } @@ -35,6 +36,11 @@ namespace Ndk return index; } + inline void BaseComponent::SetEntity(Entity* entity) + { + m_entity = entity; + } + inline bool BaseComponent::Initialize() { // Rien à faire diff --git a/SDK/src/NDK/BaseComponent.cpp b/SDK/src/NDK/BaseComponent.cpp index 3c90cef21..6a54563df 100644 --- a/SDK/src/NDK/BaseComponent.cpp +++ b/SDK/src/NDK/BaseComponent.cpp @@ -8,6 +8,16 @@ namespace Ndk { BaseComponent::~BaseComponent() = default; + void BaseComponent::OnComponentAttached(BaseComponent& component) + { + NazaraUnused(component); + } + + void BaseComponent::OnComponentDetached(BaseComponent& component) + { + NazaraUnused(component); + } + std::vector BaseComponent::s_entries; std::unordered_map BaseComponent::s_idToIndex; } diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index f7074c9b8..1c051214f 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -23,24 +23,34 @@ namespace Ndk Destroy(); } - BaseComponent& Entity::AddComponent(std::unique_ptr&& component) + BaseComponent& Entity::AddComponent(std::unique_ptr&& componentPtr) { - NazaraAssert(component, "Component must be valid"); + NazaraAssert(componentPtr, "Component must be valid"); - ComponentIndex index = component->GetIndex(); + ComponentIndex index = componentPtr->GetIndex(); // Nous nous assurons que le vecteur de component est suffisamment grand pour contenir le nouveau component if (index >= m_components.size()) m_components.resize(index + 1); // Affectation et retour du component - m_components[index] = std::move(component); + m_components[index] = std::move(componentPtr); m_componentBits.UnboundedSet(index); // On informe le monde que nous avons besoin d'une mise à jour m_world->Invalidate(m_id); - return *m_components[index].get(); + // On récupère le component et on informe les composants existants du nouvel arrivant + BaseComponent& component = *m_components[index].get(); + component.SetEntity(this); + + for (unsigned int i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) + { + if (i != index) + m_components[index]->OnComponentAttached(component); + } + + return component; } EntityHandle Entity::CreateHandle() @@ -60,8 +70,12 @@ namespace Ndk void Entity::RemoveAllComponents() { + for (unsigned int i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) + RemoveComponent(i); + + NazaraAssert(m_componentBits.TestNone(), "All components should be gone"); + m_components.clear(); - m_componentBits.Clear(); // On informe le monde que nous avons besoin d'une mise à jour m_world->Invalidate(m_id); @@ -72,6 +86,16 @@ namespace Ndk ///DOC: N'a aucun effet si le component n'est pas présent if (HasComponent(index)) { + // On récupère le component et on informe les composants du détachement + BaseComponent& component = *m_components[index].get(); + for (unsigned int i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) + { + if (i != index) + m_components[index]->OnComponentDetached(component); + } + + component.SetEntity(nullptr); + m_components[index].reset(); m_componentBits.Reset(index); From 1a403eb79c5ba5c6ee51ad1ca654ea9263cf3c9a Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 20 Apr 2015 13:39:10 +0200 Subject: [PATCH 08/29] Physics/PhysObject: Fixed SetGeom Former-commit-id: e7a343d90b1ec6ced031c5a0816e00e9c5c3b61c --- src/Nazara/Physics/PhysObject.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Physics/PhysObject.cpp b/src/Nazara/Physics/PhysObject.cpp index 2b72272d4..b021c5d92 100644 --- a/src/Nazara/Physics/PhysObject.cpp +++ b/src/Nazara/Physics/PhysObject.cpp @@ -217,10 +217,15 @@ bool NzPhysObject::IsSleeping() const void NzPhysObject::SetGeom(NzPhysGeomRef geom) { - if (geom) - m_geom = geom; - else - m_geom = NzNullGeom::New(); + if (m_geom != geom) + { + if (geom) + m_geom = geom; + else + m_geom = NzNullGeom::New(); + + NewtonBodySetCollision(m_body, m_geom->GetHandle(m_world)); + } } void NzPhysObject::SetGravityFactor(float gravityFactor) From a71c86c0ca2238cece981ec0240719deaee1b33f Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 20 Apr 2015 13:39:40 +0200 Subject: [PATCH 09/29] Physics/PhysObject: PhysObject now always have a valid geom Former-commit-id: 3b93b318545a7f0b28a9afd82868c7460f63a80f --- src/Nazara/Physics/PhysObject.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Nazara/Physics/PhysObject.cpp b/src/Nazara/Physics/PhysObject.cpp index b021c5d92..5b0e34c24 100644 --- a/src/Nazara/Physics/PhysObject.cpp +++ b/src/Nazara/Physics/PhysObject.cpp @@ -24,7 +24,9 @@ m_gravityFactor(1.f), m_mass(0.f) { NazaraAssert(m_world, "Invalid world"); - NazaraAssert(m_geom, "Invalid geometry"); + + if (!m_geom) + m_geom = NzNullGeom::New(); m_body = NewtonCreateDynamicBody(m_world->GetHandle(), m_geom->GetHandle(m_world), m_matrix); NewtonBodySetUserData(m_body, this); From 22f8c1b0a35e8c7d581813a2372424665d948e90 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 23 Apr 2015 14:22:58 +0200 Subject: [PATCH 10/29] Physics/PhysObject: Added Set(Angular)Velocity methods Former-commit-id: cd506b93ad3be1f2c5972b784bef53e02a9211ef --- include/Nazara/Physics/PhysObject.hpp | 2 ++ src/Nazara/Physics/PhysObject.cpp | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/include/Nazara/Physics/PhysObject.hpp b/include/Nazara/Physics/PhysObject.hpp index 92c71a2bb..d6ede942c 100644 --- a/include/Nazara/Physics/PhysObject.hpp +++ b/include/Nazara/Physics/PhysObject.hpp @@ -49,12 +49,14 @@ class NAZARA_API NzPhysObject : NzNonCopyable bool IsMoveable() const; bool IsSleeping() const; + void SetAngularVelocity(const NzVector3f& angularVelocity); void SetGeom(NzPhysGeomRef geom); void SetGravityFactor(float gravityFactor); void SetMass(float mass); void SetMassCenter(const NzVector3f& center); void SetPosition(const NzVector3f& position); void SetRotation(const NzQuaternionf& rotation); + void SetVelocity(const NzVector3f& velocity); NzPhysObject& operator=(const NzPhysObject& object); NzPhysObject& operator=(NzPhysObject&& object); diff --git a/src/Nazara/Physics/PhysObject.cpp b/src/Nazara/Physics/PhysObject.cpp index 5b0e34c24..74f9f0c15 100644 --- a/src/Nazara/Physics/PhysObject.cpp +++ b/src/Nazara/Physics/PhysObject.cpp @@ -217,6 +217,11 @@ bool NzPhysObject::IsSleeping() const return NewtonBodyGetSleepState(m_body) != 0; } +void NzPhysObject::SetAngularVelocity(const NzVector3f& angularVelocity) +{ + NewtonBodySetOmega(m_body, angularVelocity); +} + void NzPhysObject::SetGeom(NzPhysGeomRef geom) { if (m_geom != geom) @@ -276,6 +281,11 @@ void NzPhysObject::SetRotation(const NzQuaternionf& rotation) UpdateBody(); } +void NzPhysObject::SetVelocity(const NzVector3f& velocity) +{ + NewtonBodySetVelocity(m_body, velocity); +} + NzPhysObject& NzPhysObject::operator=(const NzPhysObject& object) { NzPhysObject physObj(object); From b5efe4d907f869381040fc66d3903af030df8c10 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 23 Apr 2015 14:23:13 +0200 Subject: [PATCH 11/29] Physics/PhysObject: Fixed compilation error Former-commit-id: 75c2ea8ff79f985cbd0d88cc395f8ad061793153 --- src/Nazara/Physics/PhysObject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Physics/PhysObject.cpp b/src/Nazara/Physics/PhysObject.cpp index 74f9f0c15..5ee0d02d9 100644 --- a/src/Nazara/Physics/PhysObject.cpp +++ b/src/Nazara/Physics/PhysObject.cpp @@ -224,7 +224,7 @@ void NzPhysObject::SetAngularVelocity(const NzVector3f& angularVelocity) void NzPhysObject::SetGeom(NzPhysGeomRef geom) { - if (m_geom != geom) + if (m_geom.Get() != geom) { if (geom) m_geom = geom; From 8c5101efdaecb36d05cc1b87a52bcfe65fbcea20 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 23 Apr 2015 14:24:31 +0200 Subject: [PATCH 12/29] Physics/PhysObject: Fixed static bodies collisions Former-commit-id: 19304460685ca9e3d8afd9757060ec6094d9526a --- src/Nazara/Physics/PhysObject.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Nazara/Physics/PhysObject.cpp b/src/Nazara/Physics/PhysObject.cpp index 5ee0d02d9..2e1ca8011 100644 --- a/src/Nazara/Physics/PhysObject.cpp +++ b/src/Nazara/Physics/PhysObject.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include @@ -296,6 +297,18 @@ void NzPhysObject::UpdateBody() { NewtonBodySetMatrix(m_body, m_matrix); + if (NzNumberEquals(m_mass, 0.f)) + { + // http://newtondynamics.com/wiki/index.php5?title=Can_i_dynamicly_move_a_TriMesh%3F + NzVector3f min, max; + NewtonBodyGetAABB(m_body, min, max); + + NewtonWorldForEachBodyInAABBDo(m_world->GetHandle(), min, max, [](const NewtonBody* const body, void* const userData) + { + NazaraUnused(userData); + NewtonBodySetSleepState(body, 0); + }, nullptr); + } /*for (std::set::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it) (*it)->PhysObjectOnUpdate(this);*/ } From 581496ce446edba513ef54e37a89c3abe99ce659 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 23 Apr 2015 14:25:25 +0200 Subject: [PATCH 13/29] Ndk/Entity: Fixed entity moving Former-commit-id: 72dcc713e86d8442de6356162735f437ec22292d --- SDK/src/NDK/Entity.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index 1c051214f..df6199e62 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -9,8 +9,11 @@ namespace Ndk { Entity::Entity(Entity&& entity) : + m_components(std::move(entity.m_components)), m_handles(std::move(entity.m_handles)), m_id(entity.m_id), + m_componentBits(std::move(entity.m_componentBits)), + m_systemBits(std::move(entity.m_systemBits)), m_world(entity.m_world), m_valid(entity.m_valid) { From ad290a18f456ade9654a5a9425132dab5d0f64f9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 23 Apr 2015 14:26:48 +0200 Subject: [PATCH 14/29] Ndk/Components: Added On[Attached|Detached] events Former-commit-id: 46e5b5720a8496dfe536181918ae0a995e028fc1 --- SDK/include/NDK/BaseComponent.hpp | 2 ++ SDK/include/NDK/BaseComponent.inl | 10 +++++++++- SDK/src/NDK/BaseComponent.cpp | 8 ++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/SDK/include/NDK/BaseComponent.hpp b/SDK/include/NDK/BaseComponent.hpp index fc1e88058..4e9b53328 100644 --- a/SDK/include/NDK/BaseComponent.hpp +++ b/SDK/include/NDK/BaseComponent.hpp @@ -43,8 +43,10 @@ namespace Ndk static ComponentIndex RegisterComponent(ComponentId id, Factory factoryFunc); private: + virtual void OnAttached(); virtual void OnComponentAttached(BaseComponent& component); virtual void OnComponentDetached(BaseComponent& component); + virtual void OnDetached(); void SetEntity(Entity* entity); static bool Initialize(); diff --git a/SDK/include/NDK/BaseComponent.inl b/SDK/include/NDK/BaseComponent.inl index 290a5de2d..b8637b457 100644 --- a/SDK/include/NDK/BaseComponent.inl +++ b/SDK/include/NDK/BaseComponent.inl @@ -38,7 +38,15 @@ namespace Ndk inline void BaseComponent::SetEntity(Entity* entity) { - m_entity = entity; + if (m_entity != entity) + { + if (m_entity) + OnDetached(); + + m_entity = entity; + if (m_entity) + OnAttached(); + } } inline bool BaseComponent::Initialize() diff --git a/SDK/src/NDK/BaseComponent.cpp b/SDK/src/NDK/BaseComponent.cpp index 6a54563df..1a0b85168 100644 --- a/SDK/src/NDK/BaseComponent.cpp +++ b/SDK/src/NDK/BaseComponent.cpp @@ -8,6 +8,10 @@ namespace Ndk { BaseComponent::~BaseComponent() = default; + void BaseComponent::OnAttached() + { + } + void BaseComponent::OnComponentAttached(BaseComponent& component) { NazaraUnused(component); @@ -18,6 +22,10 @@ namespace Ndk NazaraUnused(component); } + void BaseComponent::OnDetached() + { + } + std::vector BaseComponent::s_entries; std::unordered_map BaseComponent::s_idToIndex; } From 17e5ae1875aadb01ef173e91630c38d758e22b5c Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 23 Apr 2015 15:09:43 +0200 Subject: [PATCH 15/29] Utility/IndexMapper: Fixed missing include Former-commit-id: 3131de5096bfaef56d3e34082029a96c16544155 --- include/Nazara/Utility/IndexMapper.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Nazara/Utility/IndexMapper.hpp b/include/Nazara/Utility/IndexMapper.hpp index e06d1826f..6df36f8db 100644 --- a/include/Nazara/Utility/IndexMapper.hpp +++ b/include/Nazara/Utility/IndexMapper.hpp @@ -9,6 +9,7 @@ #include #include +#include class NzIndexBuffer; class NzIndexIterator; From 9e3dbb7d0962451e31aa0ffc60adf46c80b61763 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 23 Apr 2015 15:10:19 +0200 Subject: [PATCH 16/29] Ndk/ListenerSystem: Handling VelocityComponent Former-commit-id: 5b9107e77350c9289bf91b4bc6268403650245d3 --- SDK/src/NDK/Systems/ListenerSystem.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/SDK/src/NDK/Systems/ListenerSystem.cpp b/SDK/src/NDK/Systems/ListenerSystem.cpp index e7a90c5a9..d7cede524 100644 --- a/SDK/src/NDK/Systems/ListenerSystem.cpp +++ b/SDK/src/NDK/Systems/ListenerSystem.cpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace Ndk { @@ -16,6 +17,8 @@ namespace Ndk void ListenerSystem::Update(float elapsedTime) { + NazaraUnused(elapsedTime); + unsigned int activeListenerCount = 0; for (const Ndk::EntityHandle& entity : GetEntities()) @@ -25,10 +28,19 @@ namespace Ndk if (!listener.IsActive()) continue; + // On récupère la position et la rotation pour les affecter au listener const NodeComponent& node = entity->GetComponent(); NzAudio::SetListenerPosition(node.GetPosition(nzCoordSys_Global)); NzAudio::SetListenerRotation(node.GetRotation(nzCoordSys_Global)); + // On vérifie la présence d'une donnée de vitesse, et on l'affecte + // (La vitesse du listener Audio ne le fait pas se déplacer, mais affecte par exemple l'effet Doppler) + if (entity->HasComponent()) + { + const VelocityComponent& velocity = entity->GetComponent(); + NzAudio::SetListenerVelocity(velocity.linearVelocity); + } + activeListenerCount++; } From 1e30f0c75759ba771492763bb28224d64dbd7c8c Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 2 May 2015 09:56:52 +0200 Subject: [PATCH 17/29] Physics/PhysObject: Fixed class being not copyable Former-commit-id: 34f2787e06a0158a802e8ceacaf2c1946850195f --- include/Nazara/Physics/PhysObject.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Physics/PhysObject.hpp b/include/Nazara/Physics/PhysObject.hpp index d6ede942c..e2cf7f82e 100644 --- a/include/Nazara/Physics/PhysObject.hpp +++ b/include/Nazara/Physics/PhysObject.hpp @@ -18,7 +18,7 @@ class NzPhysWorld; struct NewtonBody; -class NAZARA_API NzPhysObject : NzNonCopyable +class NAZARA_API NzPhysObject { public: NzPhysObject(NzPhysWorld* world, const NzMatrix4f& mat = NzMatrix4f::Identity()); From 55519b5e31e10b4ae064c4b6fe52fb2a3bb2ae3f Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 2 May 2015 09:57:33 +0200 Subject: [PATCH 18/29] Ndk/Component: Modified comment and error messages Former-commit-id: 6a5fad6d2b7e3c1dbc58df0a1614012eee4df2b7 --- SDK/include/NDK/BaseSystem.inl | 1 - SDK/include/NDK/Component.inl | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/SDK/include/NDK/BaseSystem.inl b/SDK/include/NDK/BaseSystem.inl index 7c688138b..6c4ac16cd 100644 --- a/SDK/include/NDK/BaseSystem.inl +++ b/SDK/include/NDK/BaseSystem.inl @@ -132,5 +132,4 @@ namespace Ndk { // Rien à faire } - } diff --git a/SDK/include/NDK/Component.inl b/SDK/include/NDK/Component.inl index 4715e8d7d..b016fd8be 100644 --- a/SDK/include/NDK/Component.inl +++ b/SDK/include/NDK/Component.inl @@ -20,7 +20,7 @@ namespace Ndk BaseComponent* Component::Clone() const { ///FIXME: Pas encore supporté par GCC (4.9.2) - //static_assert(std::is_trivially_copy_constructible::value, "ComponentType should be copy-constructible"); + //static_assert(std::is_trivially_copy_constructible::value, "ComponentType must be copy-constructible"); return new ComponentType(static_cast(*this)); } @@ -29,7 +29,7 @@ namespace Ndk ComponentIndex Component::RegisterComponent(ComponentId id) { // Il faut que notre composant possède un constructeur par défaut (pour la factory) - static_assert(std::is_default_constructible::value, "ComponentType should be default-constructible"); + static_assert(std::is_default_constructible::value, "ComponentType must be default-constructible"); // On utilise les lambda pour créer une fonction factory auto factory = []() -> BaseComponent* @@ -37,8 +37,6 @@ namespace Ndk return new ComponentType; }; - // Je ne sais pas si c'est un bug de GCC ou si c'est quelque chose que j'ai mal compris - // mais le fait est que ça ne compile pas si je ne précise pas Basecomponent:: return BaseComponent::RegisterComponent(id, factory); } From d558b04aa7c515f07619e9f2e5c11f8cb61ee2f2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 2 May 2015 10:00:07 +0200 Subject: [PATCH 19/29] Ndk/Physics: Added first physics components/systems Former-commit-id: 654b7a2a4645487d139474dcbd02c0882d7c8f02 --- .../NDK/Components/CollisionComponent.hpp | 56 ++++++ .../NDK/Components/CollisionComponent.inl | 40 ++++ .../NDK/Components/PhysicsComponent.hpp | 72 ++++++++ .../NDK/Components/PhysicsComponent.inl | 174 ++++++++++++++++++ SDK/include/NDK/Systems/PhysicsSystem.hpp | 36 ++++ SDK/include/NDK/Systems/PhysicsSystem.inl | 16 ++ .../NDK/Systems/StaticCollisionSystem.hpp | 29 +++ .../NDK/Systems/StaticCollisionSystem.inl | 7 + SDK/src/NDK/Components/CollisionComponent.cpp | 67 +++++++ SDK/src/NDK/Components/PhysicsComponent.cpp | 59 ++++++ SDK/src/NDK/Sdk.cpp | 8 + SDK/src/NDK/Systems/PhysicsSystem.cpp | 40 ++++ SDK/src/NDK/Systems/StaticCollisionSystem.cpp | 60 ++++++ SDK/src/NDK/Systems/VelocitySystem.cpp | 2 + SDK/src/NDK/World.cpp | 4 + 15 files changed, 670 insertions(+) create mode 100644 SDK/include/NDK/Components/CollisionComponent.hpp create mode 100644 SDK/include/NDK/Components/CollisionComponent.inl create mode 100644 SDK/include/NDK/Components/PhysicsComponent.hpp create mode 100644 SDK/include/NDK/Components/PhysicsComponent.inl create mode 100644 SDK/include/NDK/Systems/PhysicsSystem.hpp create mode 100644 SDK/include/NDK/Systems/PhysicsSystem.inl create mode 100644 SDK/include/NDK/Systems/StaticCollisionSystem.hpp create mode 100644 SDK/include/NDK/Systems/StaticCollisionSystem.inl create mode 100644 SDK/src/NDK/Components/CollisionComponent.cpp create mode 100644 SDK/src/NDK/Components/PhysicsComponent.cpp create mode 100644 SDK/src/NDK/Systems/PhysicsSystem.cpp create mode 100644 SDK/src/NDK/Systems/StaticCollisionSystem.cpp diff --git a/SDK/include/NDK/Components/CollisionComponent.hpp b/SDK/include/NDK/Components/CollisionComponent.hpp new file mode 100644 index 000000000..c421f127a --- /dev/null +++ b/SDK/include/NDK/Components/CollisionComponent.hpp @@ -0,0 +1,56 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_COMPONENTS_COLLISIONCOMPONENT_HPP +#define NDK_COMPONENTS_COLLISIONCOMPONENT_HPP + +#include +#include +#include + +class NzPhysObject; + +namespace Ndk +{ + class Entity; + + class NDK_API CollisionComponent : public Component + { + friend class PhysicsSystem; + friend class StaticCollisionSystem; + + public: + CollisionComponent(NzPhysGeomRef geom = NzPhysGeomRef()); + CollisionComponent(const CollisionComponent& collision); + ~CollisionComponent() = default; + + const NzPhysGeomRef& GetGeom() const; + + void SetGeom(NzPhysGeomRef geom); + + CollisionComponent& operator=(NzPhysGeomRef geom); + CollisionComponent& operator=(CollisionComponent&& collision) = default; + + static ComponentIndex componentIndex; + + private: + void InitializeStaticBody(); + NzPhysObject* GetStaticBody(); + + void OnAttached() override; + void OnComponentAttached(BaseComponent& component) override; + void OnComponentDetached(BaseComponent& component) override; + void OnDetached() override; + + std::unique_ptr m_staticBody; + NzPhysGeomRef m_geom; + bool m_bodyUpdated; + }; +} + +#include + +#endif // NDK_COMPONENTS_COLLISIONCOMPONENT_HPP diff --git a/SDK/include/NDK/Components/CollisionComponent.inl b/SDK/include/NDK/Components/CollisionComponent.inl new file mode 100644 index 000000000..2f748c1d6 --- /dev/null +++ b/SDK/include/NDK/Components/CollisionComponent.inl @@ -0,0 +1,40 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include +#include +#include +#include + +namespace Ndk +{ + inline CollisionComponent::CollisionComponent(NzPhysGeomRef geom) : + m_geom(std::move(geom)), + m_bodyUpdated(false) + { + } + + inline CollisionComponent::CollisionComponent(const CollisionComponent& collision) : + m_geom(collision.m_geom), + m_bodyUpdated(false) + { + } + + inline const NzPhysGeomRef& CollisionComponent::GetGeom() const + { + return m_geom; + } + + inline CollisionComponent& CollisionComponent::operator=(NzPhysGeomRef geom) + { + SetGeom(geom); + + return *this; + } + + inline NzPhysObject* CollisionComponent::GetStaticBody() + { + return m_staticBody.get(); + } +} diff --git a/SDK/include/NDK/Components/PhysicsComponent.hpp b/SDK/include/NDK/Components/PhysicsComponent.hpp new file mode 100644 index 000000000..4385735f9 --- /dev/null +++ b/SDK/include/NDK/Components/PhysicsComponent.hpp @@ -0,0 +1,72 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_COMPONENTS_PHYSICSCOMPONENT_HPP +#define NDK_COMPONENTS_PHYSICSCOMPONENT_HPP + +#include +#include +#include + +namespace Ndk +{ + class Entity; + + class NDK_API PhysicsComponent : public Component + { + friend class CollisionComponent; + friend class PhysicsSystem; + + public: + PhysicsComponent() = default; + PhysicsComponent(const PhysicsComponent& physics); + ~PhysicsComponent() = default; + + void AddForce(const NzVector3f& force, nzCoordSys coordSys = nzCoordSys_Global); + void AddForce(const NzVector3f& force, const NzVector3f& point, nzCoordSys coordSys = nzCoordSys_Global); + void AddTorque(const NzVector3f& torque, nzCoordSys coordSys = nzCoordSys_Global); + + void EnableAutoSleep(bool autoSleep); + + NzBoxf GetAABB() const; + NzVector3f GetAngularVelocity() const; + float GetGravityFactor() const; + float GetMass() const; + NzVector3f GetMassCenter(nzCoordSys coordSys = nzCoordSys_Local) const; + const NzMatrix4f& GetMatrix() const; + NzVector3f GetPosition() const; + NzQuaternionf GetRotation() const; + NzVector3f GetVelocity() const; + + bool IsAutoSleepEnabled() const; + bool IsMoveable() const; + bool IsSleeping() const; + + void SetAngularVelocity(const NzVector3f& angularVelocity); + void SetGravityFactor(float gravityFactor); + void SetMass(float mass); + void SetMassCenter(const NzVector3f& center); + void SetPosition(const NzVector3f& position); + void SetRotation(const NzQuaternionf& rotation); + void SetVelocity(const NzVector3f& velocity); + + static ComponentIndex componentIndex; + + private: + NzPhysObject& GetPhysObject(); + + void OnAttached() override; + void OnComponentAttached(BaseComponent& component) override; + void OnComponentDetached(BaseComponent& component) override; + void OnDetached() override; + + std::unique_ptr m_object; + }; +} + +#include + +#endif // NDK_COMPONENTS_PHYSICSCOMPONENT_HPP diff --git a/SDK/include/NDK/Components/PhysicsComponent.inl b/SDK/include/NDK/Components/PhysicsComponent.inl new file mode 100644 index 000000000..fec47f8f5 --- /dev/null +++ b/SDK/include/NDK/Components/PhysicsComponent.inl @@ -0,0 +1,174 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include + +namespace Ndk +{ + inline PhysicsComponent::PhysicsComponent(const PhysicsComponent& physics) + { + // Pas de copie de l'objet physique (étant donné que nous n'allons le créer qu'une fois attaché à une entité) + NazaraUnused(physics); + } + + inline void PhysicsComponent::AddForce(const NzVector3f& force, nzCoordSys coordSys) + { + NazaraAssert(m_object, "Invalid physics object"); + + m_object->AddForce(force, coordSys); + } + + inline void PhysicsComponent::AddForce(const NzVector3f& force, const NzVector3f& point, nzCoordSys coordSys) + { + NazaraAssert(m_object, "Invalid physics object"); + + m_object->AddForce(force, point, coordSys); + } + + inline void PhysicsComponent::AddTorque(const NzVector3f& torque, nzCoordSys coordSys) + { + NazaraAssert(m_object, "Invalid physics object"); + + m_object->AddForce(torque, coordSys); + } + + inline void PhysicsComponent::EnableAutoSleep(bool autoSleep) + { + NazaraAssert(m_object, "Invalid physics object"); + + m_object->EnableAutoSleep(autoSleep); + } + + inline NzBoxf PhysicsComponent::GetAABB() const + { + NazaraAssert(m_object, "Invalid physics object"); + + return m_object->GetAABB(); + } + + inline NzVector3f PhysicsComponent::GetAngularVelocity() const + { + NazaraAssert(m_object, "Invalid physics object"); + + return m_object->GetAngularVelocity(); + } + + inline float PhysicsComponent::GetGravityFactor() const + { + NazaraAssert(m_object, "Invalid physics object"); + + return m_object->GetGravityFactor(); + } + + inline float PhysicsComponent::GetMass() const + { + NazaraAssert(m_object, "Invalid physics object"); + + return m_object->GetMass(); + } + + inline NzVector3f PhysicsComponent::GetMassCenter(nzCoordSys coordSys) const + { + NazaraAssert(m_object, "Invalid physics object"); + + return m_object->GetMassCenter(coordSys); + } + + inline const NzMatrix4f& PhysicsComponent::GetMatrix() const + { + NazaraAssert(m_object, "Invalid physics object"); + + return m_object->GetMatrix(); + } + + inline NzVector3f PhysicsComponent::GetPosition() const + { + NazaraAssert(m_object, "Invalid physics object"); + + return m_object->GetPosition(); + } + + inline NzQuaternionf PhysicsComponent::GetRotation() const + { + NazaraAssert(m_object, "Invalid physics object"); + + return m_object->GetRotation(); + } + + inline NzVector3f PhysicsComponent::GetVelocity() const + { + NazaraAssert(m_object, "Invalid physics object"); + + return m_object->GetVelocity(); + } + + inline bool PhysicsComponent::IsAutoSleepEnabled() const + { + NazaraAssert(m_object, "Invalid physics object"); + + return m_object->IsAutoSleepEnabled(); + } + + inline bool PhysicsComponent::IsSleeping() const + { + NazaraAssert(m_object, "Invalid physics object"); + + return m_object->IsSleeping(); + } + + inline void PhysicsComponent::SetAngularVelocity(const NzVector3f& angularVelocity) + { + NazaraAssert(m_object, "Invalid physics object"); + + m_object->SetAngularVelocity(angularVelocity); + } + + inline void PhysicsComponent::SetGravityFactor(float gravityFactor) + { + NazaraAssert(m_object, "Invalid physics object"); + + m_object->SetGravityFactor(gravityFactor); + } + + inline void PhysicsComponent::SetMass(float mass) + { + NazaraAssert(m_object, "Invalid physics object"); + NazaraAssert(mass > 0.f, "Mass should be positive"); + + m_object->SetMass(mass); + } + + inline void PhysicsComponent::SetMassCenter(const NzVector3f& center) + { + NazaraAssert(m_object, "Invalid physics object"); + + m_object->SetMassCenter(center); + } + + inline void PhysicsComponent::SetPosition(const NzVector3f& position) + { + NazaraAssert(m_object, "Invalid physics object"); + + m_object->SetPosition(position); + } + + inline void PhysicsComponent::SetRotation(const NzQuaternionf& rotation) + { + NazaraAssert(m_object, "Invalid physics object"); + + m_object->SetRotation(rotation); + } + + inline void PhysicsComponent::SetVelocity(const NzVector3f& velocity) + { + NazaraAssert(m_object, "Invalid physics object"); + + m_object->SetVelocity(velocity); + } + + inline NzPhysObject& PhysicsComponent::GetPhysObject() + { + return *m_object.get(); + } +} diff --git a/SDK/include/NDK/Systems/PhysicsSystem.hpp b/SDK/include/NDK/Systems/PhysicsSystem.hpp new file mode 100644 index 000000000..d7a3f0ba1 --- /dev/null +++ b/SDK/include/NDK/Systems/PhysicsSystem.hpp @@ -0,0 +1,36 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_SYSTEMS_PHYSICSSYSTEM_HPP +#define NDK_SYSTEMS_PHYSICSSYSTEM_HPP + +#include +#include + +namespace Ndk +{ + class NDK_API PhysicsSystem : public System + { + public: + PhysicsSystem(); + PhysicsSystem(const PhysicsSystem& system); + ~PhysicsSystem() = default; + + NzPhysWorld& GetWorld(); + const NzPhysWorld& GetWorld() const; + + void Update(float elapsedTime); + + static SystemIndex systemIndex; + + private: + NzPhysWorld m_world; + }; +} + +#include + +#endif // NDK_SYSTEMS_PHYSICSSYSTEM_HPP diff --git a/SDK/include/NDK/Systems/PhysicsSystem.inl b/SDK/include/NDK/Systems/PhysicsSystem.inl new file mode 100644 index 000000000..78d396282 --- /dev/null +++ b/SDK/include/NDK/Systems/PhysicsSystem.inl @@ -0,0 +1,16 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +namespace Ndk +{ + inline NzPhysWorld& PhysicsSystem::GetWorld() + { + return m_world; + } + + inline const NzPhysWorld& PhysicsSystem::GetWorld() const + { + return m_world; + } +} diff --git a/SDK/include/NDK/Systems/StaticCollisionSystem.hpp b/SDK/include/NDK/Systems/StaticCollisionSystem.hpp new file mode 100644 index 000000000..edaa6b0e2 --- /dev/null +++ b/SDK/include/NDK/Systems/StaticCollisionSystem.hpp @@ -0,0 +1,29 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_SYSTEMS_STATICCOLLISIONSYSTEM_HPP +#define NDK_SYSTEMS_STATICCOLLISIONSYSTEM_HPP + +#include + +namespace Ndk +{ + class NDK_API StaticCollisionSystem : public System + { + public: + StaticCollisionSystem(); + StaticCollisionSystem(const StaticCollisionSystem& system) = default; + ~StaticCollisionSystem() = default; + + void Update(float elapsedTime); + + static SystemIndex systemIndex; + }; +} + +#include + +#endif // NDK_SYSTEMS_STATICCOLLISIONSYSTEM_HPP diff --git a/SDK/include/NDK/Systems/StaticCollisionSystem.inl b/SDK/include/NDK/Systems/StaticCollisionSystem.inl new file mode 100644 index 000000000..668f8b9e2 --- /dev/null +++ b/SDK/include/NDK/Systems/StaticCollisionSystem.inl @@ -0,0 +1,7 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +namespace Ndk +{ +} diff --git a/SDK/src/NDK/Components/CollisionComponent.cpp b/SDK/src/NDK/Components/CollisionComponent.cpp new file mode 100644 index 000000000..827a698ac --- /dev/null +++ b/SDK/src/NDK/Components/CollisionComponent.cpp @@ -0,0 +1,67 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include +#include +#include +#include +#include + +namespace Ndk +{ + void CollisionComponent::SetGeom(NzPhysGeomRef geom) + { + m_geom = std::move(geom); + + if (m_entity->HasComponent()) + { + // On met à jour la géométrie du PhysObject associé au PhysicsComponent + PhysicsComponent& physComponent = m_entity->GetComponent(); + physComponent.GetPhysObject().SetGeom(m_geom); + } + else + { + NazaraAssert(m_staticBody, "An entity without physics component should have a static body"); + m_staticBody->SetGeom(m_geom); + } + } + + void CollisionComponent::InitializeStaticBody() + { + NazaraAssert(m_entity, "Invalid entity"); + World* entityWorld = m_entity->GetWorld(); + + NazaraAssert(entityWorld, "Entity must have world"); + NazaraAssert(entityWorld->HasSystem(), "World must have a physics system"); + NzPhysWorld& physWorld = entityWorld->GetSystem().GetWorld(); + + m_staticBody.reset(new NzPhysObject(&physWorld, m_geom)); + m_staticBody->EnableAutoSleep(false); + } + + void CollisionComponent::OnAttached() + { + if (!m_entity->HasComponent()) + InitializeStaticBody(); + } + + void CollisionComponent::OnComponentAttached(BaseComponent& component) + { + if (component.GetIndex() == GetComponentIndex()) + m_staticBody.reset(); + } + + void CollisionComponent::OnComponentDetached(BaseComponent& component) + { + if (component.GetIndex() == GetComponentIndex()) + InitializeStaticBody(); + } + + void CollisionComponent::OnDetached() + { + m_staticBody.reset(); + } + + ComponentIndex CollisionComponent::componentIndex; +} diff --git a/SDK/src/NDK/Components/PhysicsComponent.cpp b/SDK/src/NDK/Components/PhysicsComponent.cpp new file mode 100644 index 000000000..d900b46d7 --- /dev/null +++ b/SDK/src/NDK/Components/PhysicsComponent.cpp @@ -0,0 +1,59 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include +#include +#include +#include +#include +#include + +namespace Ndk +{ + void PhysicsComponent::OnAttached() + { + World* entityWorld = m_entity->GetWorld(); + NazaraAssert(entityWorld->HasSystem(), "World must have a physics system"); + + NzPhysWorld& world = entityWorld->GetSystem().GetWorld(); + + NzPhysGeomRef geom; + if (m_entity->HasComponent()) + geom = m_entity->GetComponent().GetGeom(); + + NzMatrix4f matrix; + if (m_entity->HasComponent()) + matrix = m_entity->GetComponent().GetTransformMatrix(); + else + matrix.MakeIdentity(); + + m_object.reset(new NzPhysObject(&world, geom, matrix)); + m_object->SetMass(1.f); + } + + void PhysicsComponent::OnComponentAttached(BaseComponent& component) + { + if (component.GetIndex() == GetComponentIndex()) + { + NazaraAssert(m_object, "Invalid object"); + m_object->SetGeom(static_cast(component).GetGeom()); + } + } + + void PhysicsComponent::OnComponentDetached(BaseComponent& component) + { + if (component.GetIndex() == GetComponentIndex()) + { + NazaraAssert(m_object, "Invalid object"); + m_object->SetGeom(NzNullGeom::New()); + } + } + + void PhysicsComponent::OnDetached() + { + m_object.reset(); + } + + ComponentIndex PhysicsComponent::componentIndex; +} diff --git a/SDK/src/NDK/Sdk.cpp b/SDK/src/NDK/Sdk.cpp index 6d2bff6d4..6537dffe5 100644 --- a/SDK/src/NDK/Sdk.cpp +++ b/SDK/src/NDK/Sdk.cpp @@ -13,10 +13,14 @@ #include #include #include +#include #include #include +#include #include #include +#include +#include #include namespace Ndk @@ -49,12 +53,16 @@ namespace Ndk BaseSystem::Initialize(); // Composants + InitializeComponent("NdkColli"); InitializeComponent("NdkList"); InitializeComponent("NdkNode"); + InitializeComponent("NdkPhys"); InitializeComponent("NdkVeloc"); // Systèmes InitializeSystem(); + InitializeSystem(); + InitializeSystem(); InitializeSystem(); NazaraNotice("Initialized: SDK"); diff --git a/SDK/src/NDK/Systems/PhysicsSystem.cpp b/SDK/src/NDK/Systems/PhysicsSystem.cpp new file mode 100644 index 000000000..d171e1697 --- /dev/null +++ b/SDK/src/NDK/Systems/PhysicsSystem.cpp @@ -0,0 +1,40 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include +#include +#include +#include +#include + +namespace Ndk +{ + PhysicsSystem::PhysicsSystem() + { + Requires(); + } + + PhysicsSystem::PhysicsSystem(const PhysicsSystem& system) : + System(system), + m_world() + { + } + + void PhysicsSystem::Update(float elapsedTime) + { + m_world.Step(elapsedTime); + + for (const Ndk::EntityHandle& entity : GetEntities()) + { + NodeComponent& node = entity->GetComponent(); + PhysicsComponent& phys = entity->GetComponent(); + + NzPhysObject& physObj = phys.GetPhysObject(); + node.SetRotation(physObj.GetRotation(), nzCoordSys_Global); + node.SetPosition(physObj.GetPosition(), nzCoordSys_Global); + } + } + + SystemIndex PhysicsSystem::systemIndex; +} diff --git a/SDK/src/NDK/Systems/StaticCollisionSystem.cpp b/SDK/src/NDK/Systems/StaticCollisionSystem.cpp new file mode 100644 index 000000000..4ac3deb24 --- /dev/null +++ b/SDK/src/NDK/Systems/StaticCollisionSystem.cpp @@ -0,0 +1,60 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include +#include +#include +#include + +namespace Ndk +{ + StaticCollisionSystem::StaticCollisionSystem() + { + Requires(); + Excludes(); + } + + void StaticCollisionSystem::Update(float elapsedTime) + { + float invElapsedTime = 1.f / elapsedTime; + for (const Ndk::EntityHandle& entity : GetEntities()) + { + CollisionComponent& collision = entity->GetComponent(); + NodeComponent& node = entity->GetComponent(); + + NzPhysObject* physObj = collision.GetStaticBody(); + + NzQuaternionf oldRotation = physObj->GetRotation(); + NzVector3f oldPosition = physObj->GetPosition(); + NzQuaternionf newRotation = node.GetRotation(nzCoordSys_Global); + NzVector3f newPosition = node.GetPosition(nzCoordSys_Global); + + // Pour déplacer des objets statiques et assurer les collisions, il faut leur définir une vitesse + // (note importante: le moteur physique n'applique pas la vitesse sur les objets statiques) + if (newPosition != oldPosition) + { + physObj->SetPosition(newPosition); + physObj->SetVelocity((newPosition - oldPosition) * invElapsedTime); + } + else + physObj->SetVelocity(NzVector3f::Zero()); + + if (newRotation != oldRotation) + { + NzQuaternionf transition = newRotation * oldRotation.GetConjugate(); + NzEulerAnglesf angles = transition.ToEulerAngles(); + NzVector3f angularVelocity(NzToRadians(angles.pitch * invElapsedTime), + NzToRadians(angles.yaw * invElapsedTime), + NzToRadians(angles.roll * invElapsedTime)); + + physObj->SetRotation(oldRotation); + physObj->SetAngularVelocity(angularVelocity); + } + else + physObj->SetAngularVelocity(NzVector3f::Zero()); + } + } + + SystemIndex StaticCollisionSystem::systemIndex; +} diff --git a/SDK/src/NDK/Systems/VelocitySystem.cpp b/SDK/src/NDK/Systems/VelocitySystem.cpp index 415889e20..a3968a053 100644 --- a/SDK/src/NDK/Systems/VelocitySystem.cpp +++ b/SDK/src/NDK/Systems/VelocitySystem.cpp @@ -4,6 +4,7 @@ #include #include +#include #include namespace Ndk @@ -11,6 +12,7 @@ namespace Ndk VelocitySystem::VelocitySystem() { Requires(); + Excludes(); } void VelocitySystem::Update(float elapsedTime) diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index c1a91fa10..79d84ffcf 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include namespace Ndk @@ -18,6 +20,8 @@ namespace Ndk void World::AddDefaultSystems() { AddSystem(); + AddSystem(); + AddSystem(); AddSystem(); } From 3b8449ebc41a3f11630ad6ecde3a2f2bc65fcb03 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 2 May 2015 10:01:10 +0200 Subject: [PATCH 20/29] Physics/PhysObject: Improved code Former-commit-id: 48770967fb5e84931e5518fad21b0cf636e327d4 --- src/Nazara/Physics/PhysObject.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Nazara/Physics/PhysObject.cpp b/src/Nazara/Physics/PhysObject.cpp index 2e1ca8011..b33acb226 100644 --- a/src/Nazara/Physics/PhysObject.cpp +++ b/src/Nazara/Physics/PhysObject.cpp @@ -78,7 +78,7 @@ void NzPhysObject::AddForce(const NzVector3f& force, nzCoordSys coordSys) break; case nzCoordSys_Local: - m_forceAccumulator += GetRotation()*force; + m_forceAccumulator += GetRotation() * force; break; } @@ -96,8 +96,7 @@ void NzPhysObject::AddForce(const NzVector3f& force, const NzVector3f& point, nz break; case nzCoordSys_Local: - AddForce(m_matrix.Transform(force, 0.f), m_matrix.Transform(point)); - return; + return AddForce(m_matrix.Transform(force, 0.f), m_matrix.Transform(point), nzCoordSys_Global); } // On réveille le corps pour que le callback soit appelé et que les forces soient appliquées From 3f423239f57133e5f9b2a1bf1f0c6babc843f90f Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 2 May 2015 21:03:30 +0200 Subject: [PATCH 21/29] Ndk/Algorithm: Added Is[Component|System] function Former-commit-id: 946f5081cea0b8df7faf0e95cfea2a3e5dd9f7bb --- SDK/include/NDK/Algorithm.hpp | 5 +++++ SDK/include/NDK/Algorithm.inl | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/SDK/include/NDK/Algorithm.hpp b/SDK/include/NDK/Algorithm.hpp index c98e63c6c..7c8de5a31 100644 --- a/SDK/include/NDK/Algorithm.hpp +++ b/SDK/include/NDK/Algorithm.hpp @@ -11,11 +11,16 @@ namespace Ndk { + class BaseComponent; + class BaseSystem; + template ComponentId BuildComponentId(const char (&name)[N]); template constexpr ComponentIndex GetComponentIndex(); template constexpr SystemIndex GetSystemIndex(); template ComponentIndex InitializeComponent(const char (&name)[N]); template SystemIndex InitializeSystem(); + template bool IsComponent(BaseComponent& component); + template bool IsSystem(BaseSystem& system); } #include diff --git a/SDK/include/NDK/Algorithm.inl b/SDK/include/NDK/Algorithm.inl index 2f2586868..8392e0ed6 100644 --- a/SDK/include/NDK/Algorithm.inl +++ b/SDK/include/NDK/Algorithm.inl @@ -3,6 +3,8 @@ // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include +#include +#include namespace Ndk { @@ -44,4 +46,16 @@ namespace Ndk SystemType::systemIndex = SystemType::RegisterSystem(); return SystemType::systemIndex; } + + template + bool IsComponent(BaseComponent& component) + { + return component.GetIndex() == GetComponentIndex(); + } + + template + bool IsSystem(BaseSystem& system) + { + return system.GetIndex() == GetSystemIndex(); + } } From 31227ca5675e451978346d366f6d74e9a179fa1d Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 2 May 2015 21:05:33 +0200 Subject: [PATCH 22/29] Ndk/Physics: Improved code Former-commit-id: 8774d0ce7cf55a0a1793e69eda6c97ececc1b44a --- SDK/src/NDK/Components/CollisionComponent.cpp | 5 +++-- SDK/src/NDK/Components/PhysicsComponent.cpp | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/SDK/src/NDK/Components/CollisionComponent.cpp b/SDK/src/NDK/Components/CollisionComponent.cpp index 827a698ac..929b087eb 100644 --- a/SDK/src/NDK/Components/CollisionComponent.cpp +++ b/SDK/src/NDK/Components/CollisionComponent.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -48,13 +49,13 @@ namespace Ndk void CollisionComponent::OnComponentAttached(BaseComponent& component) { - if (component.GetIndex() == GetComponentIndex()) + if (IsComponent(component)) m_staticBody.reset(); } void CollisionComponent::OnComponentDetached(BaseComponent& component) { - if (component.GetIndex() == GetComponentIndex()) + if (IsComponent(component)) InitializeStaticBody(); } diff --git a/SDK/src/NDK/Components/PhysicsComponent.cpp b/SDK/src/NDK/Components/PhysicsComponent.cpp index d900b46d7..6c70dbff7 100644 --- a/SDK/src/NDK/Components/PhysicsComponent.cpp +++ b/SDK/src/NDK/Components/PhysicsComponent.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -34,7 +35,7 @@ namespace Ndk void PhysicsComponent::OnComponentAttached(BaseComponent& component) { - if (component.GetIndex() == GetComponentIndex()) + if (IsComponent(component)) { NazaraAssert(m_object, "Invalid object"); m_object->SetGeom(static_cast(component).GetGeom()); @@ -43,7 +44,7 @@ namespace Ndk void PhysicsComponent::OnComponentDetached(BaseComponent& component) { - if (component.GetIndex() == GetComponentIndex()) + if (IsComponent(component)) { NazaraAssert(m_object, "Invalid object"); m_object->SetGeom(NzNullGeom::New()); From 9bffaaaa84383ae8ab349596edaee37796311b29 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 3 May 2015 19:48:33 +0200 Subject: [PATCH 23/29] Ndk/Algorithm: Fixed headers cyclic dependency Former-commit-id: a6d4d21586ef948dd68f1d3e7dc01e8275aaac3f --- SDK/include/NDK/Algorithm.hpp | 7 ++----- SDK/include/NDK/Algorithm.inl | 10 ++++------ 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/SDK/include/NDK/Algorithm.hpp b/SDK/include/NDK/Algorithm.hpp index 7c8de5a31..ece1d5d37 100644 --- a/SDK/include/NDK/Algorithm.hpp +++ b/SDK/include/NDK/Algorithm.hpp @@ -11,16 +11,13 @@ namespace Ndk { - class BaseComponent; - class BaseSystem; - template ComponentId BuildComponentId(const char (&name)[N]); template constexpr ComponentIndex GetComponentIndex(); template constexpr SystemIndex GetSystemIndex(); template ComponentIndex InitializeComponent(const char (&name)[N]); template SystemIndex InitializeSystem(); - template bool IsComponent(BaseComponent& component); - template bool IsSystem(BaseSystem& system); + template bool IsComponent(C& component); + template bool IsSystem(S& system); } #include diff --git a/SDK/include/NDK/Algorithm.inl b/SDK/include/NDK/Algorithm.inl index 8392e0ed6..e79e3a901 100644 --- a/SDK/include/NDK/Algorithm.inl +++ b/SDK/include/NDK/Algorithm.inl @@ -3,8 +3,6 @@ // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include -#include -#include namespace Ndk { @@ -47,14 +45,14 @@ namespace Ndk return SystemType::systemIndex; } - template - bool IsComponent(BaseComponent& component) + template + bool IsComponent(C& component) { return component.GetIndex() == GetComponentIndex(); } - template - bool IsSystem(BaseSystem& system) + template + bool IsSystem(S& system) { return system.GetIndex() == GetSystemIndex(); } From 3ebf967f30523adbf8e2b53f82dfd441e8970085 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 3 May 2015 19:50:42 +0200 Subject: [PATCH 24/29] Ndk/BaseSystem: Added "one of" style requirement Former-commit-id: ce4399561f4198290d639d001a6a56665baa0714 --- SDK/include/NDK/BaseSystem.hpp | 5 +++++ SDK/include/NDK/BaseSystem.inl | 22 +++++++++++++++++++++- SDK/src/NDK/BaseSystem.cpp | 7 +++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/SDK/include/NDK/BaseSystem.hpp b/SDK/include/NDK/BaseSystem.hpp index 9204f0fe0..1c9a0aa86 100644 --- a/SDK/include/NDK/BaseSystem.hpp +++ b/SDK/include/NDK/BaseSystem.hpp @@ -51,6 +51,10 @@ namespace Ndk template void Requires(); void RequiresComponent(ComponentIndex index); + template void RequiresAny(); + template void RequiresAny(); + void RequiresAnyComponent(ComponentIndex index); + private: void AddEntity(Entity* entity); @@ -68,6 +72,7 @@ namespace Ndk NzBitset m_entityBits; NzBitset<> m_excludedComponents; mutable NzBitset<> m_filterResult; + NzBitset<> m_requiredAnyComponents; NzBitset<> m_requiredComponents; SystemIndex m_systemIndex; World* m_world; diff --git a/SDK/include/NDK/BaseSystem.inl b/SDK/include/NDK/BaseSystem.inl index 6c4ac16cd..3f1d453c6 100644 --- a/SDK/include/NDK/BaseSystem.inl +++ b/SDK/include/NDK/BaseSystem.inl @@ -87,11 +87,31 @@ namespace Ndk m_requiredComponents.UnboundedSet(index); } + template + void BaseSystem::RequiresAny() + { + static_assert(std::is_base_of(), "ComponentType is not a component"); + + RequiresAnyComponent(GetComponentIndex()); + } + + template + void BaseSystem::RequiresAny() + { + RequiresAny(); + RequiresAny(); + } + + inline void BaseSystem::RequiresAnyComponent(ComponentIndex index) + { + m_requiredAnyComponents.UnboundedSet(index); + } + inline void BaseSystem::AddEntity(Entity* entity) { NazaraAssert(entity, "Invalid entity"); - m_entities.push_back(entity->CreateHandle()); + m_entities.emplace_back(entity); m_entityBits.UnboundedSet(entity->GetId(), true); entity->RegisterSystem(m_systemIndex); diff --git a/SDK/src/NDK/BaseSystem.cpp b/SDK/src/NDK/BaseSystem.cpp index 6c60f435c..a8e951d4e 100644 --- a/SDK/src/NDK/BaseSystem.cpp +++ b/SDK/src/NDK/BaseSystem.cpp @@ -27,6 +27,13 @@ namespace Ndk if (m_filterResult.TestAny()) return false; // Au moins un component exclu est présent + // Si nous avons une liste de composants nécessaires + if (m_requiredAnyComponents.TestAny()) + { + if (!m_requiredAnyComponents.Intersects(components)) + return false; + } + return true; } From 47c5d1072bcf45d2b8a8dcd8d7ae4120cc7026fe Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 3 May 2015 19:51:56 +0200 Subject: [PATCH 25/29] Ndk/BaseSystem: Added entity validation Former-commit-id: d82a66179244ae8807f65b193ed9be2f48abffa4 --- SDK/include/NDK/BaseSystem.hpp | 3 +++ SDK/include/NDK/BaseSystem.inl | 8 ++++++++ SDK/src/NDK/BaseSystem.cpp | 6 ++++++ SDK/src/NDK/World.cpp | 23 ++++++++++++++--------- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/SDK/include/NDK/BaseSystem.hpp b/SDK/include/NDK/BaseSystem.hpp index 1c9a0aa86..2e8201c80 100644 --- a/SDK/include/NDK/BaseSystem.hpp +++ b/SDK/include/NDK/BaseSystem.hpp @@ -60,11 +60,14 @@ namespace Ndk virtual void OnEntityAdded(Entity* entity); virtual void OnEntityRemoved(Entity* entity); + virtual void OnEntityValidation(Entity* entity, bool justAdded); void RemoveEntity(Entity* entity); void SetWorld(World& world); + void ValidateEntity(Entity* entity, bool justAdded); + static bool Initialize(); static void Uninitialize(); diff --git a/SDK/include/NDK/BaseSystem.inl b/SDK/include/NDK/BaseSystem.inl index 3f1d453c6..fec06ef9a 100644 --- a/SDK/include/NDK/BaseSystem.inl +++ b/SDK/include/NDK/BaseSystem.inl @@ -136,6 +136,14 @@ namespace Ndk OnEntityRemoved(entity); // Et on appelle le callback } + inline void BaseSystem::ValidateEntity(Entity* entity, bool justAdded) + { + NazaraAssert(entity, "Invalid entity"); + NazaraAssert(HasEntity(entity), "Entity should be part of system"); + + OnEntityValidation(entity, justAdded); + } + inline void BaseSystem::SetWorld(World& world) { m_world = &world; diff --git a/SDK/src/NDK/BaseSystem.cpp b/SDK/src/NDK/BaseSystem.cpp index a8e951d4e..5aa9aac30 100644 --- a/SDK/src/NDK/BaseSystem.cpp +++ b/SDK/src/NDK/BaseSystem.cpp @@ -47,5 +47,11 @@ namespace Ndk NazaraUnused(entity); } + void BaseSystem::OnEntityValidation(Entity* entity, bool justAdded) + { + NazaraUnused(entity); + NazaraUnused(justAdded); + } + SystemIndex BaseSystem::s_nextIndex; } diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index 79d84ffcf..ef8eb01fb 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -125,25 +125,30 @@ namespace Ndk { NazaraAssert(i < m_entities.size(), "Entity index out of range"); - Entity& entity = m_entities[i].entity; + Entity* entity = &m_entities[i].entity; // Aucun intérêt de traiter une entité n'existant plus - if (entity.IsValid()) + if (entity->IsValid()) { for (auto& system : m_systems) { // L'entité est-elle enregistrée comme faisant partie du système ? - bool partOfSystem = system->HasEntity(&entity); + bool partOfSystem = system->HasEntity(entity); // Doit-elle en faire partie ? - if (system->Filters(&entity) != partOfSystem) + if (system->Filters(entity)) { - // L'entité n'est pas dans l'état dans lequel elle devrait être vis-à-vis de ce système - // si elle en fait partie, nous devons l'en enlever, et inversément + // L'entité doit faire partie du système, revalidons-là (événement système) ou ajoutons-la au système + if (!partOfSystem) + system->AddEntity(entity); + + system->ValidateEntity(entity, !partOfSystem); + } + else + { + // Elle ne doit pas en faire partie, si elle en faisait partie nous devons la retirer if (partOfSystem) - system->RemoveEntity(&entity); - else - system->AddEntity(&entity); + system->RemoveEntity(entity); } } } From 8b5deffe351c696e5e21427d1ed640e0ad79855c Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 3 May 2015 19:54:35 +0200 Subject: [PATCH 26/29] Core/Bitset: Fixed Test methods being not const Former-commit-id: 440c03a78b4dcf8ec1566c1db30989c0145b5a78 --- include/Nazara/Core/Bitset.hpp | 6 +++--- include/Nazara/Core/Bitset.inl | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/Nazara/Core/Bitset.hpp b/include/Nazara/Core/Bitset.hpp index c359181cc..bc1df0e27 100644 --- a/include/Nazara/Core/Bitset.hpp +++ b/include/Nazara/Core/Bitset.hpp @@ -63,9 +63,9 @@ class NzBitset void Swap(NzBitset& bitset); bool Test(unsigned int bit) const; - bool TestAll(); - bool TestAny(); - bool TestNone(); + bool TestAll() const; + bool TestAny() const; + bool TestNone() const; template T To() const; NzString ToString() const; diff --git a/include/Nazara/Core/Bitset.inl b/include/Nazara/Core/Bitset.inl index bcd0187ff..a02c16550 100644 --- a/include/Nazara/Core/Bitset.inl +++ b/include/Nazara/Core/Bitset.inl @@ -309,7 +309,7 @@ bool NzBitset::Test(unsigned int bit) const } template -bool NzBitset::TestAll() +bool NzBitset::TestAll() const { // Cas particulier du dernier bloc Block lastBlockMask = GetLastBlockMask(); @@ -325,7 +325,7 @@ bool NzBitset::TestAll() } template -bool NzBitset::TestAny() +bool NzBitset::TestAny() const { if (m_blocks.empty()) return false; @@ -340,7 +340,7 @@ bool NzBitset::TestAny() } template -bool NzBitset::TestNone() +bool NzBitset::TestNone() const { return !TestAny(); } From da36f95b7c8085248660e7a43588b5418e5e5cf4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 3 May 2015 19:55:16 +0200 Subject: [PATCH 27/29] Ndk/Physics: Merged StaticCollisionSystem with PhysicsSystem Former-commit-id: de2127eb967fb29f285e9ebae7c743c07ea39f8a --- SDK/include/NDK/Systems/PhysicsSystem.hpp | 4 ++ .../NDK/Systems/StaticCollisionSystem.hpp | 29 -------- .../NDK/Systems/StaticCollisionSystem.inl | 7 -- SDK/src/NDK/Sdk.cpp | 2 - SDK/src/NDK/Systems/PhysicsSystem.cpp | 69 ++++++++++++++++++- SDK/src/NDK/Systems/StaticCollisionSystem.cpp | 60 ---------------- SDK/src/NDK/World.cpp | 2 - 7 files changed, 71 insertions(+), 102 deletions(-) delete mode 100644 SDK/include/NDK/Systems/StaticCollisionSystem.hpp delete mode 100644 SDK/include/NDK/Systems/StaticCollisionSystem.inl delete mode 100644 SDK/src/NDK/Systems/StaticCollisionSystem.cpp diff --git a/SDK/include/NDK/Systems/PhysicsSystem.hpp b/SDK/include/NDK/Systems/PhysicsSystem.hpp index d7a3f0ba1..dbe3bf42b 100644 --- a/SDK/include/NDK/Systems/PhysicsSystem.hpp +++ b/SDK/include/NDK/Systems/PhysicsSystem.hpp @@ -27,6 +27,10 @@ namespace Ndk static SystemIndex systemIndex; private: + void OnEntityValidation(Entity* entity, bool justAdded) override; + + std::vector m_dynamicObjects; + std::vector m_staticObjects; NzPhysWorld m_world; }; } diff --git a/SDK/include/NDK/Systems/StaticCollisionSystem.hpp b/SDK/include/NDK/Systems/StaticCollisionSystem.hpp deleted file mode 100644 index edaa6b0e2..000000000 --- a/SDK/include/NDK/Systems/StaticCollisionSystem.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Development Kit" -// For conditions of distribution and use, see copyright notice in Prerequesites.hpp - -#pragma once - -#ifndef NDK_SYSTEMS_STATICCOLLISIONSYSTEM_HPP -#define NDK_SYSTEMS_STATICCOLLISIONSYSTEM_HPP - -#include - -namespace Ndk -{ - class NDK_API StaticCollisionSystem : public System - { - public: - StaticCollisionSystem(); - StaticCollisionSystem(const StaticCollisionSystem& system) = default; - ~StaticCollisionSystem() = default; - - void Update(float elapsedTime); - - static SystemIndex systemIndex; - }; -} - -#include - -#endif // NDK_SYSTEMS_STATICCOLLISIONSYSTEM_HPP diff --git a/SDK/include/NDK/Systems/StaticCollisionSystem.inl b/SDK/include/NDK/Systems/StaticCollisionSystem.inl deleted file mode 100644 index 668f8b9e2..000000000 --- a/SDK/include/NDK/Systems/StaticCollisionSystem.inl +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Development Kit" -// For conditions of distribution and use, see copyright notice in Prerequesites.hpp - -namespace Ndk -{ -} diff --git a/SDK/src/NDK/Sdk.cpp b/SDK/src/NDK/Sdk.cpp index 6537dffe5..456332a88 100644 --- a/SDK/src/NDK/Sdk.cpp +++ b/SDK/src/NDK/Sdk.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include namespace Ndk @@ -62,7 +61,6 @@ namespace Ndk // Systèmes InitializeSystem(); InitializeSystem(); - InitializeSystem(); InitializeSystem(); NazaraNotice("Initialized: SDK"); diff --git a/SDK/src/NDK/Systems/PhysicsSystem.cpp b/SDK/src/NDK/Systems/PhysicsSystem.cpp index d171e1697..ec7d10d5f 100644 --- a/SDK/src/NDK/Systems/PhysicsSystem.cpp +++ b/SDK/src/NDK/Systems/PhysicsSystem.cpp @@ -12,7 +12,8 @@ namespace Ndk { PhysicsSystem::PhysicsSystem() { - Requires(); + Requires(); + RequiresAny(); } PhysicsSystem::PhysicsSystem(const PhysicsSystem& system) : @@ -25,7 +26,7 @@ namespace Ndk { m_world.Step(elapsedTime); - for (const Ndk::EntityHandle& entity : GetEntities()) + for (const Ndk::EntityHandle& entity : m_dynamicObjects) { NodeComponent& node = entity->GetComponent(); PhysicsComponent& phys = entity->GetComponent(); @@ -34,6 +35,70 @@ namespace Ndk node.SetRotation(physObj.GetRotation(), nzCoordSys_Global); node.SetPosition(physObj.GetPosition(), nzCoordSys_Global); } + + float invElapsedTime = 1.f / elapsedTime; + for (const Ndk::EntityHandle& entity : m_staticObjects) + { + CollisionComponent& collision = entity->GetComponent(); + NodeComponent& node = entity->GetComponent(); + + NzPhysObject* physObj = collision.GetStaticBody(); + + NzQuaternionf oldRotation = physObj->GetRotation(); + NzVector3f oldPosition = physObj->GetPosition(); + NzQuaternionf newRotation = node.GetRotation(nzCoordSys_Global); + NzVector3f newPosition = node.GetPosition(nzCoordSys_Global); + + // Pour déplacer des objets statiques et assurer les collisions, il faut leur définir une vitesse + // (note importante: le moteur physique n'applique pas la vitesse sur les objets statiques) + if (newPosition != oldPosition) + { + physObj->SetPosition(newPosition); + physObj->SetVelocity((newPosition - oldPosition) * invElapsedTime); + } + else + physObj->SetVelocity(NzVector3f::Zero()); + + if (newRotation != oldRotation) + { + NzQuaternionf transition = newRotation * oldRotation.GetConjugate(); + NzEulerAnglesf angles = transition.ToEulerAngles(); + NzVector3f angularVelocity(NzToRadians(angles.pitch * invElapsedTime), + NzToRadians(angles.yaw * invElapsedTime), + NzToRadians(angles.roll * invElapsedTime)); + + physObj->SetRotation(oldRotation); + physObj->SetAngularVelocity(angularVelocity); + } + else + physObj->SetAngularVelocity(NzVector3f::Zero()); + } + } + + void PhysicsSystem::OnEntityValidation(Entity* entity, bool justAdded) + { + // Si l'entité ne vient pas d'être ajoutée au système, il est possible qu'elle fasse partie du mauvais tableau + if (!justAdded) + { + // On prend le tableau inverse de celui dont l'entité devrait faire partie + auto& entities = (entity->HasComponent()) ? m_staticObjects : m_dynamicObjects; + + auto it = std::find(entities.begin(), entities.end(), *entity); + if (it != entities.end()) + { + // Pour éviter de déplacer beaucoup de handles, on swap le dernier avec celui à supprimer + std::swap(*it, entities.back()); + entities.pop_back(); // On le sort du vector + } + } + + if (entity->HasComponent()) + m_dynamicObjects.emplace_back(entity); + else + { + NazaraAssert(entity->HasComponent(), "Validated entity should have component CollisionComponent"); + m_staticObjects.emplace_back(entity); + } } SystemIndex PhysicsSystem::systemIndex; diff --git a/SDK/src/NDK/Systems/StaticCollisionSystem.cpp b/SDK/src/NDK/Systems/StaticCollisionSystem.cpp deleted file mode 100644 index 4ac3deb24..000000000 --- a/SDK/src/NDK/Systems/StaticCollisionSystem.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Development Kit" -// For conditions of distribution and use, see copyright notice in Prerequesites.hpp - -#include -#include -#include -#include - -namespace Ndk -{ - StaticCollisionSystem::StaticCollisionSystem() - { - Requires(); - Excludes(); - } - - void StaticCollisionSystem::Update(float elapsedTime) - { - float invElapsedTime = 1.f / elapsedTime; - for (const Ndk::EntityHandle& entity : GetEntities()) - { - CollisionComponent& collision = entity->GetComponent(); - NodeComponent& node = entity->GetComponent(); - - NzPhysObject* physObj = collision.GetStaticBody(); - - NzQuaternionf oldRotation = physObj->GetRotation(); - NzVector3f oldPosition = physObj->GetPosition(); - NzQuaternionf newRotation = node.GetRotation(nzCoordSys_Global); - NzVector3f newPosition = node.GetPosition(nzCoordSys_Global); - - // Pour déplacer des objets statiques et assurer les collisions, il faut leur définir une vitesse - // (note importante: le moteur physique n'applique pas la vitesse sur les objets statiques) - if (newPosition != oldPosition) - { - physObj->SetPosition(newPosition); - physObj->SetVelocity((newPosition - oldPosition) * invElapsedTime); - } - else - physObj->SetVelocity(NzVector3f::Zero()); - - if (newRotation != oldRotation) - { - NzQuaternionf transition = newRotation * oldRotation.GetConjugate(); - NzEulerAnglesf angles = transition.ToEulerAngles(); - NzVector3f angularVelocity(NzToRadians(angles.pitch * invElapsedTime), - NzToRadians(angles.yaw * invElapsedTime), - NzToRadians(angles.roll * invElapsedTime)); - - physObj->SetRotation(oldRotation); - physObj->SetAngularVelocity(angularVelocity); - } - else - physObj->SetAngularVelocity(NzVector3f::Zero()); - } - } - - SystemIndex StaticCollisionSystem::systemIndex; -} diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index ef8eb01fb..98d75e6f3 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include namespace Ndk @@ -21,7 +20,6 @@ namespace Ndk { AddSystem(); AddSystem(); - AddSystem(); AddSystem(); } From 58416694d4733b10a143aace7ae855cdf5633ae5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 4 May 2015 00:25:54 +0200 Subject: [PATCH 28/29] Ndk: Added EntityList Former-commit-id: f68c3830e59f460b06e23dbacc150c17937491df --- SDK/include/NDK/EntityList.hpp | 63 ++++++++++++ SDK/include/NDK/EntityList.inl | 117 ++++++++++++++++++++++ SDK/include/NDK/Systems/PhysicsSystem.hpp | 5 +- SDK/src/NDK/Systems/PhysicsSystem.cpp | 18 +--- 4 files changed, 186 insertions(+), 17 deletions(-) create mode 100644 SDK/include/NDK/EntityList.hpp create mode 100644 SDK/include/NDK/EntityList.inl diff --git a/SDK/include/NDK/EntityList.hpp b/SDK/include/NDK/EntityList.hpp new file mode 100644 index 000000000..753189580 --- /dev/null +++ b/SDK/include/NDK/EntityList.hpp @@ -0,0 +1,63 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_ENTITYLIST_HPP +#define NDK_ENTITYLIST_HPP + +#include +#include +#include + +namespace Ndk +{ + class NDK_API EntityList + { + public: + using Container = std::vector; + + EntityList() = default; + ~EntityList() = default; + + void Clear(); + + bool Has(const Entity* entity); + bool Has(EntityId entity); + + void Insert(Entity* entity); + + void Remove(Entity* entity); + + // Interface STD + Container::iterator begin(); + Container::const_iterator begin() const; + + Container::const_iterator cbegin() const; + Container::const_iterator cend() const; + Container::const_reverse_iterator crbegin() const; + Container::const_reverse_iterator crend() const; + + bool empty() const; + + Container::iterator end(); + Container::const_iterator end() const; + + Container::reverse_iterator rbegin(); + Container::const_reverse_iterator rbegin() const; + + Container::reverse_iterator rend(); + Container::const_reverse_iterator rend() const; + + Container::size_type size() const; + + private: + std::vector m_entities; + NzBitset m_entityBits; + }; +} + +#include + +#endif // NDK_ENTITYLIST_HPP diff --git a/SDK/include/NDK/EntityList.inl b/SDK/include/NDK/EntityList.inl new file mode 100644 index 000000000..e7cd2bb3b --- /dev/null +++ b/SDK/include/NDK/EntityList.inl @@ -0,0 +1,117 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include +#include + +namespace Ndk +{ + inline void EntityList::Clear() + { + m_entities.clear(); + m_entityBits.Clear(); + } + + inline bool EntityList::Has(const Entity* entity) + { + return entity && entity->IsValid() && Has(entity->GetId()); + } + + inline bool EntityList::Has(EntityId entity) + { + return m_entityBits.UnboundedTest(entity); + } + + inline void EntityList::Insert(Entity* entity) + { + if (!Has(entity)) + { + m_entities.emplace_back(entity); + m_entityBits.UnboundedSet(entity->GetId(), true); + } + } + + inline void EntityList::Remove(Entity* entity) + { + if (Has(entity)) + { + auto it = std::find(m_entities.begin(), m_entities.end(), *entity); + NazaraAssert(it != m_entities.end(), "Entity should be part of the vector"); + + std::swap(*it, m_entities.back()); + m_entities.pop_back(); // On le sort du vector + } + } + + // Interface STD + inline EntityList::Container::iterator EntityList::begin() + { + return m_entities.begin(); + } + + inline EntityList::Container::const_iterator EntityList::begin() const + { + return m_entities.begin(); + } + + inline EntityList::Container::const_iterator EntityList::cbegin() const + { + return m_entities.cbegin(); + } + + inline EntityList::Container::const_iterator EntityList::cend() const + { + return m_entities.cend(); + } + + inline EntityList::Container::const_reverse_iterator EntityList::crbegin() const + { + return m_entities.crbegin(); + } + + inline EntityList::Container::const_reverse_iterator EntityList::crend() const + { + return m_entities.crend(); + } + + inline bool EntityList::empty() const + { + return m_entities.empty(); + } + + inline EntityList::Container::iterator EntityList::end() + { + return m_entities.end(); + } + + inline EntityList::Container::const_iterator EntityList::end() const + { + return m_entities.end(); + } + + inline EntityList::Container::reverse_iterator EntityList::rbegin() + { + return m_entities.rbegin(); + } + + inline EntityList::Container::const_reverse_iterator EntityList::rbegin() const + { + return m_entities.rbegin(); + } + + inline EntityList::Container::reverse_iterator EntityList::rend() + { + return m_entities.rend(); + } + + inline EntityList::Container::const_reverse_iterator EntityList::rend() const + { + return m_entities.rend(); + } + + inline EntityList::Container::size_type EntityList::size() const + { + return m_entities.size(); + } +} diff --git a/SDK/include/NDK/Systems/PhysicsSystem.hpp b/SDK/include/NDK/Systems/PhysicsSystem.hpp index dbe3bf42b..227ee1f9d 100644 --- a/SDK/include/NDK/Systems/PhysicsSystem.hpp +++ b/SDK/include/NDK/Systems/PhysicsSystem.hpp @@ -8,6 +8,7 @@ #define NDK_SYSTEMS_PHYSICSSYSTEM_HPP #include +#include #include namespace Ndk @@ -29,8 +30,8 @@ namespace Ndk private: void OnEntityValidation(Entity* entity, bool justAdded) override; - std::vector m_dynamicObjects; - std::vector m_staticObjects; + EntityList m_dynamicObjects; + EntityList m_staticObjects; NzPhysWorld m_world; }; } diff --git a/SDK/src/NDK/Systems/PhysicsSystem.cpp b/SDK/src/NDK/Systems/PhysicsSystem.cpp index ec7d10d5f..a54c776a2 100644 --- a/SDK/src/NDK/Systems/PhysicsSystem.cpp +++ b/SDK/src/NDK/Systems/PhysicsSystem.cpp @@ -82,23 +82,11 @@ namespace Ndk { // On prend le tableau inverse de celui dont l'entité devrait faire partie auto& entities = (entity->HasComponent()) ? m_staticObjects : m_dynamicObjects; - - auto it = std::find(entities.begin(), entities.end(), *entity); - if (it != entities.end()) - { - // Pour éviter de déplacer beaucoup de handles, on swap le dernier avec celui à supprimer - std::swap(*it, entities.back()); - entities.pop_back(); // On le sort du vector - } + entities.Remove(entity); } - if (entity->HasComponent()) - m_dynamicObjects.emplace_back(entity); - else - { - NazaraAssert(entity->HasComponent(), "Validated entity should have component CollisionComponent"); - m_staticObjects.emplace_back(entity); - } + auto& entities = (entity->HasComponent()) ? m_dynamicObjects : m_staticObjects; + entities.Insert(entity); } SystemIndex PhysicsSystem::systemIndex; From 9fa5b5bbfc205889b76c9bbc17b9ff7fb417ce81 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 4 May 2015 00:53:07 +0200 Subject: [PATCH 29/29] Ndk/Entity: Inlined IsValid() Former-commit-id: 217df236c91d7504218e1094f5a8b3f9c28d1599 --- SDK/include/NDK/Entity.inl | 5 +++++ SDK/src/NDK/Entity.cpp | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/SDK/include/NDK/Entity.inl b/SDK/include/NDK/Entity.inl index 72936bee9..c3935b0bf 100644 --- a/SDK/include/NDK/Entity.inl +++ b/SDK/include/NDK/Entity.inl @@ -80,6 +80,11 @@ namespace Ndk return HasComponent(index); } + inline bool Entity::IsValid() const + { + return m_valid; + } + template void Entity::RemoveComponent() { diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index df6199e62..e6bd09ce0 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -66,11 +66,6 @@ namespace Ndk m_world->KillEntity(this); } - bool Entity::IsValid() const - { - return m_valid; - } - void Entity::RemoveAllComponents() { for (unsigned int i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i))