Updated physics module (Still experimental)

Former-commit-id: 4852b7cf6eca5ba3177397586877fe3d3c39dbd9
This commit is contained in:
Lynix 2013-06-24 13:33:54 +02:00
parent 050f9c2eb7
commit 0e3a4fa90b
6 changed files with 296 additions and 74 deletions

View File

@ -8,14 +8,16 @@
#define NAZARA_GEOM_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/PrimitiveList.hpp>
#include <Nazara/Core/NonCopyable.hpp>
#include <Nazara/Math/Cube.hpp>
#include <Nazara/Math/Box.hpp>
#include <Nazara/Math/Quaternion.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Physics/Enums.hpp>
///TODO: CollisionModifier
///TODO: HeightfieldGeom
///TODO: PlaneGeom ?
///TODO: SceneGeom
///TODO: TreeGeom
@ -28,8 +30,8 @@ class NAZARA_API NzBaseGeom : NzNonCopyable
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 NzBoxf ComputeAABB(const NzVector3f& translation, const NzQuaternionf& rotation, const NzVector3f& scale) const;
virtual NzBoxf ComputeAABB(const NzMatrix4f& offsetMatrix = NzMatrix4f::Identity()) const;
virtual void ComputeInertialMatrix(NzVector3f* inertia, NzVector3f* center) const;
virtual float ComputeVolume() const;
@ -38,6 +40,8 @@ class NAZARA_API NzBaseGeom : NzNonCopyable
NzPhysWorld* GetWorld() const;
static NzBaseGeom* Build(NzPhysWorld* physWorld, const NzPrimitiveList& list);
protected:
NewtonCollision* m_collision;
NzPhysWorld* m_world;
@ -46,7 +50,8 @@ class NAZARA_API NzBaseGeom : NzNonCopyable
class NAZARA_API NzBoxGeom : public NzBaseGeom
{
public:
NzBoxGeom(NzPhysWorld* physWorld, const NzVector3f& lengths, const NzVector3f& translation = NzVector3f::Zero(), const NzQuaternionf& rotation = NzQuaternionf::Identity());
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());
NzVector3f GetLengths() const;
nzGeomType GetType() const override;
@ -58,7 +63,8 @@ class NAZARA_API NzBoxGeom : public NzBaseGeom
class NAZARA_API NzCapsuleGeom : public NzBaseGeom
{
public:
NzCapsuleGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation = NzVector3f::Zero(), const NzQuaternionf& rotation = NzQuaternionf::Identity());
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());
float GetLength() const;
float GetRadius() const;
@ -72,7 +78,7 @@ class NAZARA_API NzCapsuleGeom : public NzBaseGeom
class NAZARA_API NzCompoundGeom : public NzBaseGeom
{
public:
NzCompoundGeom(NzPhysWorld* physWorld, NzBaseGeom* geoms, unsigned int geomCount);
NzCompoundGeom(NzPhysWorld* physWorld, NzBaseGeom** geoms, unsigned int geomCount);
nzGeomType GetType() const override;
};
@ -80,7 +86,8 @@ class NAZARA_API NzCompoundGeom : public NzBaseGeom
class NAZARA_API NzConeGeom : public NzBaseGeom
{
public:
NzConeGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation = NzVector3f::Zero(), const NzQuaternionf& rotation = NzQuaternionf::Identity());
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());
float GetLength() const;
float GetRadius() const;
@ -94,7 +101,8 @@ class NAZARA_API NzConeGeom : public NzBaseGeom
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());
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;
};
@ -102,7 +110,8 @@ class NAZARA_API NzConvexHullGeom : public NzBaseGeom
class NAZARA_API NzCylinderGeom : public NzBaseGeom
{
public:
NzCylinderGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation = NzVector3f::Zero(), const NzQuaternionf& rotation = NzQuaternionf::Identity());
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());
float GetLength() const;
float GetRadius() const;
@ -124,8 +133,8 @@ class NAZARA_API NzNullGeom : public NzBaseGeom
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());
NzSphereGeom(NzPhysWorld* physWorld, float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity());
NzSphereGeom(NzPhysWorld* physWorld, float radius, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity());
NzVector3f GetRadius() const;
nzGeomType GetType() const override;

View File

@ -1,4 +1,4 @@
// Copyright (C) 2013 Jérôme Leclercq
// 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
@ -8,6 +8,7 @@
#define NAZARA_PHYSOBJECT_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Enums.hpp>
#include <Nazara/Core/NonCopyable.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Math/Quaternion.hpp>
@ -24,24 +25,40 @@ class NAZARA_API NzPhysObject : NzNonCopyable
NzPhysObject(NzPhysWorld* world, const NzBaseGeom* geom, const NzMatrix4f& mat = NzMatrix4f::Identity());
~NzPhysObject();
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);
NzVector3f GetAngularVelocity() const;
float GetGravityFactor() const;
NewtonBody* GetHandle() const;
float GetMass() const;
NzVector3f GetMassCenter() 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 SetGravityFactor(float gravityFactor);
void SetMass(float mass);
void SetMassCenter(NzVector3f center);
void SetMassCenter(const NzVector3f& center);
void SetPosition(const NzVector3f& position);
void SetRotation(const NzQuaternionf& rotation);
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;
NzVector3f m_forceAccumulator;
NzVector3f m_torqueAccumulator;
NewtonBody* m_body;
const NzBaseGeom* m_geom;
NzPhysWorld* m_world;

View File

@ -1,4 +1,4 @@
// Copyright (C) 2013 Jérôme Leclercq
// 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
@ -22,18 +22,19 @@ class NAZARA_API NzPhysWorld : NzNonCopyable
NzVector3f GetGravity() const;
NewtonWorld* GetHandle() const;
unsigned int GetMemoryUsed() const;
float GetStepSize() const;
void SetGravity(const NzVector3f& gravity);
void SetSize(const NzBoxf& box);
void SetSize(const NzVector3f& min, const NzVector3f& max);
void SetSolverModel(unsigned int model);
void SetStepSize(float stepSize);
void Update(float timestep);
void Step(float timestep);
private:
NzVector3f m_gravity;
NewtonWorld* m_world;
float m_stepSize;
float m_timestepAccumulator;
};
#endif // NAZARA_PHYSWORLD_HPP

View File

@ -8,6 +8,28 @@
#include <memory>
#include <Nazara/Physics/Debug.hpp>
namespace
{
NzBaseGeom* CreateGeomFromPrimitive(NzPhysWorld* physWorld, const NzPrimitive& primitive)
{
switch (primitive.type)
{
case nzPrimitiveType_Box:
return new NzBoxGeom(physWorld, primitive.box.lengths, primitive.matrix);
case nzPrimitiveType_Plane:
return new NzBoxGeom(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());
}
NazaraError("Primitive type not handled (0x" + NzString::Number(primitive.type, 16) + ')');
return nullptr;
}
}
NzBaseGeom::NzBaseGeom(NzPhysWorld* physWorld) :
m_world(physWorld)
{
@ -15,24 +37,24 @@ m_world(physWorld)
NzBaseGeom::~NzBaseGeom()
{
NewtonReleaseCollision(m_world->GetHandle(), m_collision);
NewtonDestroyCollision(m_collision);
}
NzCubef NzBaseGeom::ComputeAABB(const NzVector3f& translation, const NzQuaternionf& rotation, const NzVector3f& scale) const
NzBoxf 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);
return NzBoxf(scale*min, scale*max);
}
NzCubef NzBaseGeom::ComputeAABB(const NzMatrix4f& offsetMatrix) const
NzBoxf NzBaseGeom::ComputeAABB(const NzMatrix4f& offsetMatrix) const
{
NzVector3f min, max;
NewtonCollisionCalculateAABB(m_collision, offsetMatrix, min, max);
return NzCubef(min, max);
return NzBoxf(min, max);
}
void NzBaseGeom::ComputeInertialMatrix(NzVector3f* inertia, NzVector3f* center) const
@ -64,13 +86,43 @@ NzPhysWorld* NzBaseGeom::GetWorld() const
return m_world;
}
NzBaseGeom* NzBaseGeom::Build(NzPhysWorld* physWorld, const NzPrimitiveList& list)
{
unsigned int primitiveCount = list.GetSize();
#if NAZARA_PHYSICS_SAFE
if (primitiveCount == 0)
{
NazaraError("PrimitiveList must have at least one primitive");
return nullptr;
}
#endif
if (primitiveCount > 1)
{
std::vector<NzBaseGeom*> geoms(primitiveCount);
for (unsigned int i = 0; i < primitiveCount; ++i)
geoms[i] = CreateGeomFromPrimitive(physWorld, list.GetPrimitive(i));
return new NzCompoundGeom(physWorld, &geoms[0], primitiveCount);
}
else
return CreateGeomFromPrimitive(physWorld, list.GetPrimitive(0));
}
/********************************** BoxGeom **********************************/
NzBoxGeom::NzBoxGeom(NzPhysWorld* physWorld, const NzVector3f& lengths, const NzVector3f& translation, const NzQuaternionf& rotation) :
NzBoxGeom::NzBoxGeom(NzPhysWorld* physWorld, const NzVector3f& lengths, const NzMatrix4f& transformMatrix) :
NzBaseGeom(physWorld),
m_lengths(lengths)
{
m_collision = NewtonCreateBox(physWorld->GetHandle(), lengths.x, lengths.y, lengths.z, 0, NzMatrix4f::Transform(translation, rotation));
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))
{
}
NzVector3f NzBoxGeom::GetLengths() const
@ -85,12 +137,17 @@ nzGeomType NzBoxGeom::GetType() const
/******************************** CapsuleGeom ********************************/
NzCapsuleGeom::NzCapsuleGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) :
NzCapsuleGeom::NzCapsuleGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix) :
NzBaseGeom(physWorld),
m_length(length),
m_radius(radius)
{
m_collision = NewtonCreateCapsule(physWorld->GetHandle(), radius, length, 0, NzMatrix4f::Transform(translation, rotation));
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))
{
}
float NzCapsuleGeom::GetLength() const
@ -110,28 +167,21 @@ nzGeomType NzCapsuleGeom::GetType() const
/******************************* CompoundGeom ********************************/
NzCompoundGeom::NzCompoundGeom(NzPhysWorld* physWorld, NzBaseGeom* geoms, unsigned int geomCount) :
NzCompoundGeom::NzCompoundGeom(NzPhysWorld* physWorld, NzBaseGeom** geoms, unsigned int geomCount) :
NzBaseGeom(physWorld)
{
std::vector<NewtonCollision*> collisions;
collisions.reserve(geomCount);
m_collision = NewtonCreateCompoundCollision(physWorld->GetHandle(), 0);
NewtonCompoundCollisionBeginAddRemove(m_collision);
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]);
}
if (geoms[i]->GetType() == nzGeomType_Compound)
NazaraError("Cannot add compound geoms to other compound geoms");
else
collisions.push_back(geoms[i].GetHandle());
NewtonCompoundCollisionAddSubCollision(m_collision, geoms[i]->GetHandle());
}
m_collision = NewtonCreateCompoundCollision(physWorld->GetHandle(), collisions.size(), &collisions[0], 0);
NewtonCompoundCollisionEndAddRemove(m_collision);
}
nzGeomType NzCompoundGeom::GetType() const
@ -141,12 +191,17 @@ nzGeomType NzCompoundGeom::GetType() const
/********************************* ConeGeom **********************************/
NzConeGeom::NzConeGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) :
NzConeGeom::NzConeGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix) :
NzBaseGeom(physWorld),
m_length(length),
m_radius(radius)
{
m_collision = NewtonCreateCone(physWorld->GetHandle(), radius, length, 0, NzMatrix4f::Transform(translation, rotation));
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))
{
}
float NzConeGeom::GetLength() const
@ -166,10 +221,15 @@ nzGeomType NzConeGeom::GetType() const
/****************************** ConvexHullGeom *******************************/
NzConvexHullGeom::NzConvexHullGeom(NzPhysWorld* physWorld, const NzVector3f* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const NzVector3f& translation, const NzQuaternionf& rotation) :
NzConvexHullGeom::NzConvexHullGeom(NzPhysWorld* physWorld, const void* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const NzMatrix4f& transformMatrix) :
NzBaseGeom(physWorld)
{
m_collision = NewtonCreateConvexHull(physWorld->GetHandle(), vertexCount, reinterpret_cast<const float*>(vertices), stride, tolerance, 0, NzMatrix4f::Transform(translation, rotation));
m_collision = NewtonCreateConvexHull(physWorld->GetHandle(), vertexCount, reinterpret_cast<const float*>(vertices), stride, tolerance, 0, transformMatrix);
}
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))
{
}
nzGeomType NzConvexHullGeom::GetType() const
@ -179,12 +239,17 @@ nzGeomType NzConvexHullGeom::GetType() const
/******************************* CylinderGeom ********************************/
NzCylinderGeom::NzCylinderGeom(NzPhysWorld* physWorld, float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) :
NzCylinderGeom::NzCylinderGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix) :
NzBaseGeom(physWorld),
m_length(length),
m_radius(radius)
{
m_collision = NewtonCreateCylinder(physWorld->GetHandle(), radius, length, 0, NzMatrix4f::Transform(translation, rotation));
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))
{
}
float NzCylinderGeom::GetLength() const
@ -217,15 +282,15 @@ nzGeomType NzNullGeom::GetType() const
/******************************** SphereGeom *********************************/
NzSphereGeom::NzSphereGeom(NzPhysWorld* physWorld, const NzVector3f& radius, const NzVector3f& translation) :
NzSphereGeom::NzSphereGeom(NzPhysWorld* physWorld, float radius, const NzMatrix4f& transformMatrix) :
NzBaseGeom(physWorld),
m_radius(radius)
{
m_collision = NewtonCreateSphere(physWorld->GetHandle(), radius.x, radius.y, radius.z, 0, NzMatrix4f::Translate(translation));
m_collision = NewtonCreateSphere(physWorld->GetHandle(), radius, 0, transformMatrix);
}
NzSphereGeom::NzSphereGeom(NzPhysWorld* physWorld, float radius, const NzVector3f& translation) :
NzSphereGeom(physWorld, NzVector3f(radius), translation)
NzSphereGeom::NzSphereGeom(NzPhysWorld* physWorld, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) :
NzSphereGeom(physWorld, radius, NzMatrix4f::Transform(translation, rotation))
{
}

View File

@ -1,4 +1,4 @@
// Copyright (C) 2013 Jérôme Leclercq
// 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
@ -12,6 +12,7 @@
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),
@ -23,13 +24,14 @@ m_mass(0.f)
#endif
m_geom = new NzNullGeom(world);
m_body = NewtonCreateBody(world->GetHandle(), m_geom->GetHandle(), mat);
m_body = NewtonCreateDynamicBody(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_torqueAccumulator(NzVector3f::Zero()),
m_geom(geom),
m_world(world),
m_ownsGeom(false),
@ -41,7 +43,7 @@ m_mass(0.f)
NazaraError("Invalid physics world"); ///TODO: Unexcepted
#endif
m_body = NewtonCreateBody(world->GetHandle(), geom->GetHandle(), mat);
m_body = NewtonCreateDynamicBody(world->GetHandle(), geom->GetHandle(), mat);
NewtonBodySetUserData(m_body, this);
}
@ -53,24 +55,109 @@ NzPhysObject::~NzPhysObject()
delete m_geom;
}
void NzPhysObject::AddForce(const NzVector3f& force, nzCoordSys coordSys)
{
switch (coordSys)
{
case nzCoordSys_Global:
m_forceAccumulator += force;
break;
case nzCoordSys_Local:
m_forceAccumulator += GetRotation()*force;
break;
}
// On réveille le corps pour que le callback soit appelé et que les forces soient appliquées
NewtonBodySetSleepState(m_body, 0);
}
void NzPhysObject::AddForce(const NzVector3f& force, const NzVector3f& point, nzCoordSys coordSys)
{
switch (coordSys)
{
case nzCoordSys_Global:
m_forceAccumulator += force;
m_torqueAccumulator += NzVector3f::CrossProduct(point - GetMassCenter(nzCoordSys_Global), force);
break;
case nzCoordSys_Local:
AddForce(m_matrix.Transform(force, 0.f), m_matrix.Transform(point));
return;
}
// On réveille le corps pour que le callback soit appelé et que les forces soient appliquées
NewtonBodySetSleepState(m_body, 0);
}
void NzPhysObject::AddTorque(const NzVector3f& torque, nzCoordSys coordSys)
{
switch (coordSys)
{
case nzCoordSys_Global:
m_torqueAccumulator += torque;
break;
case nzCoordSys_Local:
m_torqueAccumulator += m_matrix.Transform(torque, 0.f);
break;
}
// On réveille le corps pour que le callback soit appelé et que les forces soient appliquées
NewtonBodySetSleepState(m_body, 0);
}
void NzPhysObject::EnableAutoSleep(bool autoSleep)
{
NewtonBodySetAutoSleep(m_body, autoSleep);
}
NzVector3f NzPhysObject::GetAngularVelocity() const
{
NzVector3f angularVelocity;
NewtonBodyGetOmega(m_body, angularVelocity);
return angularVelocity;
}
float NzPhysObject::GetGravityFactor() const
{
return m_gravityFactor;
}
NewtonBody* NzPhysObject::GetHandle() const
{
return m_body;
}
float NzPhysObject::GetMass() const
{
return m_mass;
}
NzVector3f NzPhysObject::GetMassCenter() const
NzVector3f NzPhysObject::GetMassCenter(nzCoordSys coordSys) const
{
NzVector3f center;
NewtonBodyGetCentreOfMass(m_body, center);
switch (coordSys)
{
case nzCoordSys_Global:
center = m_matrix.Transform(center);
break;
case nzCoordSys_Local:
break; // Aucune opération à effectuer sur le centre de rotation
}
return center;
}
const NzMatrix4f& NzPhysObject::GetMatrix() const
{
return m_matrix;
}
NzVector3f NzPhysObject::GetPosition() const
{
return m_matrix.GetTranslation();
@ -89,11 +176,26 @@ NzVector3f NzPhysObject::GetVelocity() const
return velocity;
}
bool NzPhysObject::IsAutoSleepEnabled() const
{
return NewtonBodyGetAutoSleep(m_body) != 0;
}
bool NzPhysObject::IsMoveable() const
{
return m_mass > 0.f;
}
bool NzPhysObject::IsSleeping() const
{
return NewtonBodyGetSleepState(m_body) != 0;
}
void NzPhysObject::SetGravityFactor(float gravityFactor)
{
m_gravityFactor = gravityFactor;
}
void NzPhysObject::SetMass(float mass)
{
if (m_mass > 0.f)
@ -117,12 +219,31 @@ void NzPhysObject::SetMass(float mass)
m_mass = mass;
}
void NzPhysObject::SetMassCenter(NzVector3f center)
void NzPhysObject::SetMassCenter(const NzVector3f& center)
{
if (m_mass > 0.f)
NewtonBodySetCentreOfMass(m_body, center);
}
void NzPhysObject::SetPosition(const NzVector3f& position)
{
m_matrix.SetTranslation(position);
UpdateBody();
}
void NzPhysObject::SetRotation(const NzQuaternionf& rotation)
{
m_matrix.SetRotation(rotation);
UpdateBody();
}
void NzPhysObject::UpdateBody()
{
NewtonBodySetMatrix(m_body, m_matrix);
/*for (std::set<PhysObjectListener*>::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it)
(*it)->PhysObjectOnUpdate(this);*/
}
void NzPhysObject::ForceAndTorqueCallback(const NewtonBody* body, float timeStep, int threadIndex)
{
NazaraUnused(timeStep);
@ -137,10 +258,10 @@ void NzPhysObject::ForceAndTorqueCallback(const NewtonBody* body, float timeStep
(*it)->PhysObjectApplyForce(me);*/
NewtonBodySetForce(body, me->m_forceAccumulator);
me->m_forceAccumulator.Set(0.f);
NewtonBodySetTorque(body, me->m_torqueAccumulator);
/*NewtonBodyAddTorque(body, &me->m_torqueAccumulator.x);
me->m_torqueAccumulator = 0.f;*/
me->m_torqueAccumulator.Set(0.f);
me->m_forceAccumulator.Set(0.f);
///TODO: Implanter la force gyroscopique?
}

View File

@ -1,4 +1,4 @@
// Copyright (C) 2013 Jérôme Leclercq
// 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
@ -6,7 +6,10 @@
#include <Newton/Newton.h>
#include <Nazara/Physics/Debug.hpp>
NzPhysWorld::NzPhysWorld()
NzPhysWorld::NzPhysWorld() :
m_gravity(NzVector3f::Zero()),
m_stepSize(0.005f),
m_timestepAccumulator(0.f)
{
m_world = NewtonCreate();
NewtonWorldSetUserData(m_world, this);
@ -27,27 +30,33 @@ NewtonWorld* NzPhysWorld::GetHandle() const
return m_world;
}
float NzPhysWorld::GetStepSize() const
{
return m_stepSize;
}
void NzPhysWorld::SetGravity(const NzVector3f& gravity)
{
m_gravity = gravity;
}
void NzPhysWorld::SetSize(const NzBoxf& box)
{
NewtonSetWorldSize(m_world, box.GetPosition(), box.GetPosition()+box.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)
void NzPhysWorld::SetStepSize(float stepSize)
{
NewtonUpdate(m_world, timestep);
m_stepSize = stepSize;
}
void NzPhysWorld::Step(float timestep)
{
m_timestepAccumulator += timestep;
while (m_timestepAccumulator >= m_stepSize)
{
NewtonUpdate(m_world, m_stepSize);
m_timestepAccumulator -= m_stepSize;
}
}