From 8014f67eb8b842c5b17a523bb5454e330399b43a Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 23 May 2013 23:16:36 +0200 Subject: [PATCH 1/2] Added Physics module Former-commit-id: acc3ffe119ebfae9c0199eb878a621325c28844a --- include/Nazara/Physics.hpp | 39 +++++ include/Nazara/Physics/Config.hpp | 38 ++++ include/Nazara/Physics/Debug.hpp | 11 ++ include/Nazara/Physics/DebugOff.hpp | 8 + include/Nazara/Physics/Enums.hpp | 27 +++ include/Nazara/Physics/Geom.hpp | 137 +++++++++++++++ include/Nazara/Physics/PhysObject.hpp | 53 ++++++ include/Nazara/Physics/PhysWorld.hpp | 39 +++++ include/Nazara/Physics/Physics.hpp | 31 ++++ src/Nazara/Physics/Debug/Leaks.cpp | 29 ++++ src/Nazara/Physics/Geom.cpp | 240 ++++++++++++++++++++++++++ src/Nazara/Physics/PhysObject.cpp | 157 +++++++++++++++++ src/Nazara/Physics/PhysWorld.cpp | 53 ++++++ src/Nazara/Physics/Physics.cpp | 64 +++++++ 14 files changed, 926 insertions(+) create mode 100644 include/Nazara/Physics.hpp create mode 100644 include/Nazara/Physics/Config.hpp create mode 100644 include/Nazara/Physics/Debug.hpp create mode 100644 include/Nazara/Physics/DebugOff.hpp create mode 100644 include/Nazara/Physics/Enums.hpp create mode 100644 include/Nazara/Physics/Geom.hpp create mode 100644 include/Nazara/Physics/PhysObject.hpp create mode 100644 include/Nazara/Physics/PhysWorld.hpp create mode 100644 include/Nazara/Physics/Physics.hpp create mode 100644 src/Nazara/Physics/Debug/Leaks.cpp create mode 100644 src/Nazara/Physics/Geom.cpp create mode 100644 src/Nazara/Physics/PhysObject.cpp create mode 100644 src/Nazara/Physics/PhysWorld.cpp create mode 100644 src/Nazara/Physics/Physics.cpp diff --git a/include/Nazara/Physics.hpp b/include/Nazara/Physics.hpp new file mode 100644 index 000000000..d107c467b --- /dev/null +++ b/include/Nazara/Physics.hpp @@ -0,0 +1,39 @@ +// This file was automatically generated on 21 May 2013 at 13:57:27 + +/* + Nazara Engine - Physics module + + Copyright (C) 2013 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#pragma once + +#ifndef NAZARA_GLOBAL_PHYSICS_HPP +#define NAZARA_GLOBAL_PHYSICS_HPP + +#include +#include +#include +#include +#include +#include + +#endif // NAZARA_GLOBAL_PHYSICS_HPP diff --git a/include/Nazara/Physics/Config.hpp b/include/Nazara/Physics/Config.hpp new file mode 100644 index 000000000..4ff4decfc --- /dev/null +++ b/include/Nazara/Physics/Config.hpp @@ -0,0 +1,38 @@ +/* + Nazara Engine - Physics module + + Copyright (C) 2013 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#pragma once + +#ifndef NAZARA_CONFIG_PHYSICS_HPP +#define NAZARA_CONFIG_PHYSICS_HPP + +/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci + +// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution) +#define NAZARA_PHYSICS_MEMORYLEAKTRACKER 0 + +// Active les tests de sécurité basés sur le code (Conseillé pour le développement) +#define NAZARA_PHYSICS_SAFE 1 + +#endif // NAZARA_CONFIG_PHYSICS_HPP diff --git a/include/Nazara/Physics/Debug.hpp b/include/Nazara/Physics/Debug.hpp new file mode 100644 index 000000000..c1f071713 --- /dev/null +++ b/include/Nazara/Physics/Debug.hpp @@ -0,0 +1,11 @@ +// Copyright (C) 2013 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 +#if NAZARA_PHYSICS_MEMORYLEAKTRACKER || defined(NAZARA_DEBUG) + #include + + #define delete NzMemoryManager::NextFree(__FILE__, __LINE__), delete + #define new new(__FILE__, __LINE__) +#endif diff --git a/include/Nazara/Physics/DebugOff.hpp b/include/Nazara/Physics/DebugOff.hpp new file mode 100644 index 000000000..66a7d9f7b --- /dev/null +++ b/include/Nazara/Physics/DebugOff.hpp @@ -0,0 +1,8 @@ +// Copyright (C) 2013 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 + +#if NAZARA_PHYSICS_MEMORYLEAKTRACKER || defined(NAZARA_DEBUG) + #undef delete + #undef new +#endif diff --git a/include/Nazara/Physics/Enums.hpp b/include/Nazara/Physics/Enums.hpp new file mode 100644 index 000000000..3f507f9ef --- /dev/null +++ b/include/Nazara/Physics/Enums.hpp @@ -0,0 +1,27 @@ +// Copyright (C) 2013 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 + +#pragma once + +#ifndef NAZARA_ENUMS_PHYSICS_HPP +#define NAZARA_ENUMS_PHYSICS_HPP + +enum nzGeomType +{ + nzGeomType_Box, + nzGeomType_Capsule, + nzGeomType_Cone, + nzGeomType_Compound, + nzGeomType_ConvexHull, + nzGeomType_Cylinder, + nzGeomType_Heightfield, + nzGeomType_Null, + nzGeomType_Scene, + nzGeomType_Sphere, + nzGeomType_Tree, + + nzGeomType_Max = nzGeomType_Tree +}; + +#endif // NAZARA_ENUMS_PHYSICS_HPP diff --git a/include/Nazara/Physics/Geom.hpp b/include/Nazara/Physics/Geom.hpp new file mode 100644 index 000000000..cff4d13e7 --- /dev/null +++ b/include/Nazara/Physics/Geom.hpp @@ -0,0 +1,137 @@ +// Copyright (C) 2013 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 + +#pragma once + +#ifndef NAZARA_GEOM_HPP +#define NAZARA_GEOM_HPP + +#include +#include +#include +#include +#include +#include + +///TODO: CollisionModifier +///TODO: HeightfieldGeom +///TODO: SceneGeom +///TODO: TreeGeom + +class NzPhysWorld; +struct NewtonCollision; + +class NAZARA_API NzBaseGeom : NzNonCopyable +{ + public: + NzBaseGeom(NzPhysWorld* physWorld); + virtual ~NzBaseGeom(); + + virtual NzCubef ComputeAABB(const NzVector3f& translation, const NzQuaternionf& rotation, const NzVector3f& scale) const; + virtual NzCubef ComputeAABB(const NzMatrix4f& offsetMatrix = NzMatrix4f::Identity()) const; + virtual void ComputeInertialMatrix(NzVector3f* inertia, NzVector3f* center) const; + virtual float ComputeVolume() const; + + NewtonCollision* GetHandle() const; + virtual nzGeomType GetType() const = 0; + + NzPhysWorld* GetWorld() const; + + protected: + NewtonCollision* m_collision; + NzPhysWorld* m_world; +}; + +class NAZARA_API NzBoxGeom : public NzBaseGeom +{ + public: + NzBoxGeom(NzPhysWorld* physWorld, const NzVector3f& lengths, const NzVector3f& translation = NzVector3f::Zero(), const NzQuaternionf& rotation = NzQuaternionf::Identity()); + + NzVector3f GetLengths() const; + nzGeomType GetType() const override; + + private: + NzVector3f m_lengths; +}; + +class NAZARA_API NzCapsuleGeom : public NzBaseGeom +{ + public: + NzCapsuleGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation = NzVector3f::Zero(), const NzQuaternionf& rotation = NzQuaternionf::Identity()); + + float GetLength() const; + float GetRadius() const; + nzGeomType GetType() const override; + + private: + float m_length; + float m_radius; +}; + +class NAZARA_API NzCompoundGeom : public NzBaseGeom +{ + public: + NzCompoundGeom(NzPhysWorld* physWorld, NzBaseGeom* geoms, unsigned int geomCount); + + nzGeomType GetType() const override; +}; + +class NAZARA_API NzConeGeom : public NzBaseGeom +{ + public: + NzConeGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation = NzVector3f::Zero(), const NzQuaternionf& rotation = NzQuaternionf::Identity()); + + float GetLength() const; + float GetRadius() const; + nzGeomType GetType() const override; + + private: + float m_length; + float m_radius; +}; + +class NAZARA_API NzConvexHullGeom : public NzBaseGeom +{ + public: + NzConvexHullGeom(NzPhysWorld* physWorld, const NzVector3f* vertices, unsigned int vertexCount, unsigned int stride = sizeof(NzVector3f), float tolerance = 0.2f, const NzVector3f& translation = NzVector3f::Zero(), const NzQuaternionf& rotation = NzQuaternionf::Identity()); + + nzGeomType GetType() const override; +}; + +class NAZARA_API NzCylinderGeom : public NzBaseGeom +{ + public: + NzCylinderGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation = NzVector3f::Zero(), const NzQuaternionf& rotation = NzQuaternionf::Identity()); + + float GetLength() const; + float GetRadius() const; + nzGeomType GetType() const override; + + private: + float m_length; + float m_radius; +}; + +class NAZARA_API NzNullGeom : public NzBaseGeom +{ + public: + NzNullGeom(NzPhysWorld* physWorld); + + nzGeomType GetType() const override; +}; + +class NAZARA_API NzSphereGeom : public NzBaseGeom +{ + public: + NzSphereGeom(NzPhysWorld* physWorld, const NzVector3f& radius, const NzVector3f& translation = NzVector3f::Zero()); + NzSphereGeom(NzPhysWorld* physWorld, float radius, const NzVector3f& translation = NzVector3f::Zero()); + + NzVector3f GetRadius() const; + nzGeomType GetType() const override; + + private: + NzVector3f m_radius; +}; + +#endif // NAZARA_PHYSWORLD_HPP diff --git a/include/Nazara/Physics/PhysObject.hpp b/include/Nazara/Physics/PhysObject.hpp new file mode 100644 index 000000000..ced439967 --- /dev/null +++ b/include/Nazara/Physics/PhysObject.hpp @@ -0,0 +1,53 @@ +// Copyright (C) 2013 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 + +#pragma once + +#ifndef NAZARA_PHYSOBJECT_HPP +#define NAZARA_PHYSOBJECT_HPP + +#include +#include +#include +#include +#include + +class NzBaseGeom; +class NzPhysWorld; +struct NewtonBody; + +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(); + + float GetGravityFactor() const; + float GetMass() const; + NzVector3f GetMassCenter() const; + NzVector3f GetPosition() const; + NzQuaternionf GetRotation() const; + NzVector3f GetVelocity() const; + + bool IsMoveable() const; + + void SetMass(float mass); + void SetMassCenter(NzVector3f center); + + private: + static void ForceAndTorqueCallback(const NewtonBody* body, float timeStep, int threadIndex); + static void TransformCallback(const NewtonBody* body, const float* matrix, int threadIndex); + + NzMatrix4f m_matrix; + NzVector3f m_forceAccumulator; + NewtonBody* m_body; + const NzBaseGeom* m_geom; + NzPhysWorld* m_world; + bool m_ownsGeom; + float m_gravityFactor; + float m_mass; +}; + +#endif // NAZARA_PHYSOBJECT_HPP diff --git a/include/Nazara/Physics/PhysWorld.hpp b/include/Nazara/Physics/PhysWorld.hpp new file mode 100644 index 000000000..eac0982a9 --- /dev/null +++ b/include/Nazara/Physics/PhysWorld.hpp @@ -0,0 +1,39 @@ +// Copyright (C) 2013 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 + +#pragma once + +#ifndef NAZARA_PHYSWORLD_HPP +#define NAZARA_PHYSWORLD_HPP + +#include +#include +#include +#include + +struct NewtonWorld; + +class NAZARA_API NzPhysWorld : NzNonCopyable +{ + public: + NzPhysWorld(); + ~NzPhysWorld(); + + NzVector3f GetGravity() const; + NewtonWorld* GetHandle() const; + unsigned int GetMemoryUsed() const; + + void SetGravity(const NzVector3f& gravity); + void SetSize(const NzCubef& cube); + void SetSize(const NzVector3f& min, const NzVector3f& max); + void SetSolverModel(unsigned int model); + + void Update(float timestep); + + private: + NzVector3f m_gravity; + NewtonWorld* m_world; +}; + +#endif // NAZARA_PHYSWORLD_HPP diff --git a/include/Nazara/Physics/Physics.hpp b/include/Nazara/Physics/Physics.hpp new file mode 100644 index 000000000..6c1e2548f --- /dev/null +++ b/include/Nazara/Physics/Physics.hpp @@ -0,0 +1,31 @@ +// Copyright (C) 2013 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 + +#pragma once + +#ifndef NAZARA_PHYSICS_HPP +#define NAZARA_PHYSICS_HPP + +#include +#include + +class NAZARA_API NzPhysics +{ + public: + NzPhysics() = delete; + ~NzPhysics() = delete; + + static unsigned int GetMemoryUsed(); + + static bool Initialize(); + + static bool IsInitialized(); + + static void Uninitialize(); + + private: + static unsigned int s_moduleReferenceCounter; +}; + +#endif // NAZARA_PHYSICS_HPP diff --git a/src/Nazara/Physics/Debug/Leaks.cpp b/src/Nazara/Physics/Debug/Leaks.cpp new file mode 100644 index 000000000..a4c5aeb18 --- /dev/null +++ b/src/Nazara/Physics/Debug/Leaks.cpp @@ -0,0 +1,29 @@ +// Copyright (C) 2013 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 +#if NAZARA_PHYSICS_MEMORYLEAKTRACKER || defined(NAZARA_DEBUG) +#include +#include + +void* operator new(std::size_t size) +{ + return NzMemoryManager::Allocate(size, false); +} + +void* operator new[](std::size_t size) +{ + return NzMemoryManager::Allocate(size, true); +} + +void operator delete(void* pointer) noexcept +{ + NzMemoryManager::Free(pointer, false); +} + +void operator delete[](void* pointer) noexcept +{ + NzMemoryManager::Free(pointer, true); +} +#endif diff --git a/src/Nazara/Physics/Geom.cpp b/src/Nazara/Physics/Geom.cpp new file mode 100644 index 000000000..71aa0bda6 --- /dev/null +++ b/src/Nazara/Physics/Geom.cpp @@ -0,0 +1,240 @@ +// Copyright (C) 2013 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 +#include +#include +#include + +NzBaseGeom::NzBaseGeom(NzPhysWorld* physWorld) : +m_world(physWorld) +{ +} + +NzBaseGeom::~NzBaseGeom() +{ + NewtonReleaseCollision(m_world->GetHandle(), m_collision); +} + +NzCubef NzBaseGeom::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 NzCubef(scale*min, scale*max); +} + +NzCubef NzBaseGeom::ComputeAABB(const NzMatrix4f& offsetMatrix) const +{ + NzVector3f min, max; + NewtonCollisionCalculateAABB(m_collision, offsetMatrix, min, max); + + return NzCubef(min, max); +} + +void NzBaseGeom::ComputeInertialMatrix(NzVector3f* inertia, NzVector3f* center) const +{ + float inertiaMatrix[3]; + float origin[3]; + + NewtonConvexCollisionCalculateInertialMatrix(m_collision, inertiaMatrix, origin); + + if (inertia) + inertia->Set(inertiaMatrix); + + if (center) + center->Set(origin); +} + +float NzBaseGeom::ComputeVolume() const +{ + return NewtonConvexCollisionCalculateVolume(m_collision); +} + +NewtonCollision* NzBaseGeom::GetHandle() const +{ + return m_collision; +} + +NzPhysWorld* NzBaseGeom::GetWorld() const +{ + return m_world; +} + +/********************************** BoxGeom **********************************/ + +NzBoxGeom::NzBoxGeom(NzPhysWorld* physWorld, const NzVector3f& lengths, const NzVector3f& translation, const NzQuaternionf& rotation) : +NzBaseGeom(physWorld), +m_lengths(lengths) +{ + m_collision = NewtonCreateBox(physWorld->GetHandle(), lengths.x, lengths.y, lengths.z, 0, NzMatrix4f::Transform(translation, rotation)); +} + +NzVector3f NzBoxGeom::GetLengths() const +{ + return m_lengths; +} + +nzGeomType NzBoxGeom::GetType() const +{ + return nzGeomType_Box; +} + +/******************************** CapsuleGeom ********************************/ + +NzCapsuleGeom::NzCapsuleGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) : +NzBaseGeom(physWorld), +m_length(length), +m_radius(radius) +{ + m_collision = NewtonCreateCapsule(physWorld->GetHandle(), radius, length, 0, NzMatrix4f::Transform(translation, rotation)); +} + +float NzCapsuleGeom::GetLength() const +{ + return m_length; +} + +float NzCapsuleGeom::GetRadius() const +{ + return m_radius; +} + +nzGeomType NzCapsuleGeom::GetType() const +{ + return nzGeomType_Capsule; +} + +/******************************* CompoundGeom ********************************/ + +NzCompoundGeom::NzCompoundGeom(NzPhysWorld* physWorld, NzBaseGeom* geoms, unsigned int geomCount) : +NzBaseGeom(physWorld) +{ + std::vector collisions; + collisions.reserve(geomCount); + + for (unsigned int i = 0; i < geomCount; ++i) + { + if (geoms[i].GetType() == nzGeomType_Compound) + { + NewtonCollisionInfoRecord info; + NewtonCollisionGetInfo(geoms[i].GetHandle(), &info); + + unsigned int count = info.m_compoundCollision.m_chidrenCount; + for (unsigned int j = 0; j < count; ++j) + collisions.push_back(info.m_compoundCollision.m_chidren[j]); + } + else + collisions.push_back(geoms[i].GetHandle()); + } + + m_collision = NewtonCreateCompoundCollision(physWorld->GetHandle(), collisions.size(), &collisions[0], 0); +} + +nzGeomType NzCompoundGeom::GetType() const +{ + return nzGeomType_Compound; +} + +/********************************* ConeGeom **********************************/ + +NzConeGeom::NzConeGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) : +NzBaseGeom(physWorld), +m_length(length), +m_radius(radius) +{ + m_collision = NewtonCreateCone(physWorld->GetHandle(), radius, length, 0, NzMatrix4f::Transform(translation, rotation)); +} + +float NzConeGeom::GetLength() const +{ + return m_length; +} + +float NzConeGeom::GetRadius() const +{ + return m_radius; +} + +nzGeomType NzConeGeom::GetType() const +{ + return nzGeomType_Cone; +} + +/****************************** ConvexHullGeom *******************************/ + +NzConvexHullGeom::NzConvexHullGeom(NzPhysWorld* physWorld, const NzVector3f* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const NzVector3f& translation, const NzQuaternionf& rotation) : +NzBaseGeom(physWorld) +{ + m_collision = NewtonCreateConvexHull(physWorld->GetHandle(), vertexCount, reinterpret_cast(vertices), stride, tolerance, 0, NzMatrix4f::Transform(translation, rotation)); +} + +nzGeomType NzConvexHullGeom::GetType() const +{ + return nzGeomType_Compound; +} + +/******************************* CylinderGeom ********************************/ + +NzCylinderGeom::NzCylinderGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) : +NzBaseGeom(physWorld), +m_length(length), +m_radius(radius) +{ + m_collision = NewtonCreateCylinder(physWorld->GetHandle(), radius, length, 0, NzMatrix4f::Transform(translation, rotation)); +} + +float NzCylinderGeom::GetLength() const +{ + return m_length; +} + +float NzCylinderGeom::GetRadius() const +{ + return m_radius; +} + +nzGeomType NzCylinderGeom::GetType() const +{ + return nzGeomType_Cylinder; +} + +/********************************* NullGeom **********************************/ + +NzNullGeom::NzNullGeom(NzPhysWorld* physWorld) : +NzBaseGeom(physWorld) +{ + m_collision = NewtonCreateNull(physWorld->GetHandle()); +} + +nzGeomType NzNullGeom::GetType() const +{ + return nzGeomType_Null; +} + +/******************************** SphereGeom *********************************/ + +NzSphereGeom::NzSphereGeom(NzPhysWorld* physWorld, const NzVector3f& radius, const NzVector3f& translation) : +NzBaseGeom(physWorld), +m_radius(radius) +{ + m_collision = NewtonCreateSphere(physWorld->GetHandle(), radius.x, radius.y, radius.z, 0, NzMatrix4f::Translate(translation)); +} + +NzSphereGeom::NzSphereGeom(NzPhysWorld* physWorld, float radius, const NzVector3f& translation) : +NzSphereGeom(physWorld, NzVector3f(radius), translation) +{ +} + +NzVector3f NzSphereGeom::GetRadius() const +{ + return m_radius; +} + +nzGeomType NzSphereGeom::GetType() const +{ + return nzGeomType_Sphere; +} diff --git a/src/Nazara/Physics/PhysObject.cpp b/src/Nazara/Physics/PhysObject.cpp new file mode 100644 index 000000000..aab4ed368 --- /dev/null +++ b/src/Nazara/Physics/PhysObject.cpp @@ -0,0 +1,157 @@ +// Copyright (C) 2013 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 +#include +#include +#include +#include + +NzPhysObject::NzPhysObject(NzPhysWorld* world, const NzMatrix4f& mat) : +m_matrix(mat), +m_forceAccumulator(NzVector3f::Zero()), +m_world(world), +m_ownsGeom(true), +m_gravityFactor(1.f), +m_mass(0.f) +{ + #if NAZARA_PHYSICS_SAFE + if (!world) + NazaraError("Invalid physics world"); ///TODO: Unexcepted + #endif + + m_geom = new NzNullGeom(world); + m_body = NewtonCreateBody(world->GetHandle(), m_geom->GetHandle(), mat); + NewtonBodySetUserData(m_body, this); +} + +NzPhysObject::NzPhysObject(NzPhysWorld* world, const NzBaseGeom* geom, const NzMatrix4f& mat) : +m_matrix(mat), +m_forceAccumulator(NzVector3f::Zero()), +m_geom(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 + + m_body = NewtonCreateBody(world->GetHandle(), geom->GetHandle(), mat); + NewtonBodySetUserData(m_body, this); +} + +NzPhysObject::~NzPhysObject() +{ + NewtonDestroyBody(m_world->GetHandle(), m_body); + + if (m_ownsGeom) + delete m_geom; +} + +float NzPhysObject::GetGravityFactor() const +{ + return m_gravityFactor; +} + +float NzPhysObject::GetMass() const +{ + return m_mass; +} + +NzVector3f NzPhysObject::GetMassCenter() const +{ + NzVector3f center; + NewtonBodyGetCentreOfMass(m_body, center); + + return center; +} + +NzVector3f NzPhysObject::GetPosition() const +{ + return m_matrix.GetTranslation(); +} + +NzQuaternionf NzPhysObject::GetRotation() const +{ + return m_matrix.GetRotation(); +} + +NzVector3f NzPhysObject::GetVelocity() const +{ + NzVector3f velocity; + NewtonBodyGetVelocity(m_body, velocity); + + return velocity; +} + +bool NzPhysObject::IsMoveable() const +{ + return m_mass > 0.f; +} + +void NzPhysObject::SetMass(float mass) +{ + if (m_mass > 0.f) + { + float Ix, Iy, Iz; + NewtonBodyGetMassMatrix(m_body, &m_mass, &Ix, &Iy, &Iz); + float scale = mass/m_mass; + NewtonBodySetMassMatrix(m_body, mass, Ix*scale, Iy*scale, Iz*scale); + } + else if (mass > 0.f) + { + NzVector3f inertia, origin; + m_geom->ComputeInertialMatrix(&inertia, &origin); + + NewtonBodySetCentreOfMass(m_body, &origin.x); + NewtonBodySetMassMatrix(m_body, mass, inertia.x*mass, inertia.y*mass, inertia.z*mass); + NewtonBodySetForceAndTorqueCallback(m_body, &ForceAndTorqueCallback); + NewtonBodySetTransformCallback(m_body, &TransformCallback); + } + + m_mass = mass; +} + +void NzPhysObject::SetMassCenter(NzVector3f center) +{ + if (m_mass > 0.f) + NewtonBodySetCentreOfMass(m_body, center); +} + +void NzPhysObject::ForceAndTorqueCallback(const NewtonBody* body, float timeStep, int threadIndex) +{ + NazaraUnused(timeStep); + NazaraUnused(threadIndex); + + NzPhysObject* me = static_cast(NewtonBodyGetUserData(body)); + + if (!NzNumberEquals(me->m_gravityFactor, 0.f)) + me->m_forceAccumulator += me->m_world->GetGravity() * me->m_gravityFactor * me->m_mass; + + /*for (std::set::iterator it = me->m_listeners.begin(); it != me->m_listeners.end(); ++it) + (*it)->PhysObjectApplyForce(me);*/ + + NewtonBodySetForce(body, me->m_forceAccumulator); + me->m_forceAccumulator.Set(0.f); + + /*NewtonBodyAddTorque(body, &me->m_torqueAccumulator.x); + me->m_torqueAccumulator = 0.f;*/ + + ///TODO: Implanter la force gyroscopique? +} + +void NzPhysObject::TransformCallback(const NewtonBody* body, const float* matrix, int threadIndex) +{ + NazaraUnused(threadIndex); + + NzPhysObject* me = static_cast(NewtonBodyGetUserData(body)); + me->m_matrix.Set(matrix); + + /*for (std::set::iterator it = me->m_listeners.begin(); it != me->m_listeners.end(); ++it) + (*it)->PhysObjectOnUpdate(me);*/ +} diff --git a/src/Nazara/Physics/PhysWorld.cpp b/src/Nazara/Physics/PhysWorld.cpp new file mode 100644 index 000000000..c89724894 --- /dev/null +++ b/src/Nazara/Physics/PhysWorld.cpp @@ -0,0 +1,53 @@ +// Copyright (C) 2013 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 +#include + +NzPhysWorld::NzPhysWorld() +{ + m_world = NewtonCreate(); + NewtonWorldSetUserData(m_world, this); +} + +NzPhysWorld::~NzPhysWorld() +{ + NewtonDestroy(m_world); +} + +NzVector3f NzPhysWorld::GetGravity() const +{ + return m_gravity; +} + +NewtonWorld* NzPhysWorld::GetHandle() const +{ + return m_world; +} + +void NzPhysWorld::SetGravity(const NzVector3f& gravity) +{ + m_gravity = gravity; +} + +void NzPhysWorld::SetSize(const NzCubef& cube) +{ + NewtonSetWorldSize(m_world, cube.GetPosition(), cube.GetPosition()+cube.GetSize()); +} + +void NzPhysWorld::SetSize(const NzVector3f& min, const NzVector3f& max) +{ + NewtonSetWorldSize(m_world, min, max); +} + +void NzPhysWorld::SetSolverModel(unsigned int model) +{ + NewtonSetSolverModel(m_world, model); +} + +void NzPhysWorld::Update(float timestep) +{ + NewtonUpdate(m_world, timestep); +} diff --git a/src/Nazara/Physics/Physics.cpp b/src/Nazara/Physics/Physics.cpp new file mode 100644 index 000000000..76b46d34b --- /dev/null +++ b/src/Nazara/Physics/Physics.cpp @@ -0,0 +1,64 @@ +// Copyright (C) 2013 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 +#include +#include +#include +#include +#include + +unsigned int NzPhysics::GetMemoryUsed() +{ + return NewtonGetMemoryUsed(); +} + +bool NzPhysics::Initialize() +{ + if (s_moduleReferenceCounter++ != 0) + return true; // Déjà initialisé + + // Initialisation des dépendances + if (!NzCore::Initialize()) + { + NazaraError("Failed to initialize core module"); + Uninitialize(); + + return false; + } + + // Initialisation du module + + NazaraNotice("Initialized: Physics module"); + + return true; +} + +bool NzPhysics::IsInitialized() +{ + return s_moduleReferenceCounter != 0; +} + +void NzPhysics::Uninitialize() +{ + if (s_moduleReferenceCounter != 1) + { + // Le module est soit encore utilisé, soit pas initialisé + if (s_moduleReferenceCounter > 1) + s_moduleReferenceCounter--; + + return; + } + + // Libération du module + s_moduleReferenceCounter = 0; + + NazaraNotice("Uninitialized: Physics module"); + + // Libération des dépendances + NzCore::Uninitialize(); +} + +unsigned int NzPhysics::s_moduleReferenceCounter = 0; From 1fba4eaddb60092999729fd7ce7bfb5fc9ee136e Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 26 May 2013 23:07:24 +0200 Subject: [PATCH 2/2] Added build file Former-commit-id: cdf061966451f28f5785692232340aeadf6192f4 --- build/scripts/module/physics.lua | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 build/scripts/module/physics.lua diff --git a/build/scripts/module/physics.lua b/build/scripts/module/physics.lua new file mode 100644 index 000000000..edc301b66 --- /dev/null +++ b/build/scripts/module/physics.lua @@ -0,0 +1,39 @@ +if (not _OPTIONS["united"]) then + project "NazaraPhysics" +end + +files +{ + "../include/Nazara/Physics/**.hpp", + "../include/Nazara/Physics/**.inl", + "../src/Nazara/Physics/**.hpp", + "../src/Nazara/Physics/**.cpp" +} + +if (os.is("windows")) then + excludes { "../src/Nazara/Physics/Posix/*.hpp", "../src/Nazara/Physics/Posix/*.cpp" } +else + excludes { "../src/Nazara/Physics/Win32/*.hpp", "../src/Nazara/Physics/Win32/*.cpp" } +end + +if (_OPTIONS["united"]) then + excludes "../src/Nazara/Physics/Debug/Leaks.cpp" +else + configuration "DebugStatic" + links "NazaraCore-s-d" + + configuration "ReleaseStatic" + links "NazaraCore-s" + + configuration "DebugDLL" + links "NazaraCore-d" + + configuration "ReleaseDLL" + links "NazaraCore" +end + +configuration "Debug*" + links "newton_d" + +configuration "Release*" + links "newton"