Updated physics module (Still experimental)
Former-commit-id: 4852b7cf6eca5ba3177397586877fe3d3c39dbd9
This commit is contained in:
parent
050f9c2eb7
commit
0e3a4fa90b
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue