Physics3D/World: Add more control on materials
This commit is contained in:
parent
9b431e54c9
commit
84a3fc1a91
|
|
@ -13,7 +13,9 @@
|
||||||
#include <Nazara/Physics3D/Config.hpp>
|
#include <Nazara/Physics3D/Config.hpp>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
class NewtonBody;
|
||||||
class NewtonJoint;
|
class NewtonJoint;
|
||||||
|
class NewtonMaterial;
|
||||||
class NewtonWorld;
|
class NewtonWorld;
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
|
|
@ -23,6 +25,7 @@ namespace Nz
|
||||||
class NAZARA_PHYSICS3D_API PhysWorld3D
|
class NAZARA_PHYSICS3D_API PhysWorld3D
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using AABBOverlapCallback = std::function<bool(const RigidBody3D& firstBody, const RigidBody3D& secondBody)>;
|
||||||
using CollisionCallback = std::function<bool(const RigidBody3D& firstBody, const RigidBody3D& secondBody)>;
|
using CollisionCallback = std::function<bool(const RigidBody3D& firstBody, const RigidBody3D& secondBody)>;
|
||||||
|
|
||||||
PhysWorld3D();
|
PhysWorld3D();
|
||||||
|
|
@ -41,7 +44,12 @@ namespace Nz
|
||||||
void SetSolverModel(unsigned int model);
|
void SetSolverModel(unsigned int model);
|
||||||
void SetStepSize(float stepSize);
|
void SetStepSize(float stepSize);
|
||||||
|
|
||||||
void SetMaterialCollisionCallback(int firstMaterial, int secondMaterial, CollisionCallback callback);
|
void SetMaterialCollisionCallback(int firstMaterial, int secondMaterial, AABBOverlapCallback aabbOverlapCallback, CollisionCallback collisionCallback);
|
||||||
|
void SetMaterialDefaultCollidable(int firstMaterial, int secondMaterial, bool collidable);
|
||||||
|
void SetMaterialDefaultElasticity(int firstMaterial, int secondMaterial, float elasticCoef);
|
||||||
|
void SetMaterialDefaultFriction(int firstMaterial, int secondMaterial, float staticFriction, float kineticFriction);
|
||||||
|
void SetMaterialDefaultSoftness(int firstMaterial, int secondMaterial, float softness);
|
||||||
|
void SetMaterialSurfaceThickness(int firstMaterial, int secondMaterial, float thickness);
|
||||||
|
|
||||||
void Step(float timestep);
|
void Step(float timestep);
|
||||||
|
|
||||||
|
|
@ -51,9 +59,11 @@ namespace Nz
|
||||||
private:
|
private:
|
||||||
struct Callback
|
struct Callback
|
||||||
{
|
{
|
||||||
|
AABBOverlapCallback aabbOverlapCallback;
|
||||||
CollisionCallback collisionCallback;
|
CollisionCallback collisionCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int OnAABBOverlap(const NewtonMaterial* const material, const NewtonBody* const body0, const NewtonBody* const body1, int threadIndex);
|
||||||
static void ProcessContact(const NewtonJoint* const contact, float timestep, int threadIndex);
|
static void ProcessContact(const NewtonJoint* const contact, float timestep, int threadIndex);
|
||||||
|
|
||||||
std::unordered_map<Nz::UInt64, std::unique_ptr<Callback>> m_callbacks;
|
std::unordered_map<Nz::UInt64, std::unique_ptr<Callback>> m_callbacks;
|
||||||
|
|
|
||||||
|
|
@ -74,14 +74,15 @@ namespace Nz
|
||||||
m_stepSize = stepSize;
|
m_stepSize = stepSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysWorld3D::SetMaterialCollisionCallback(int firstMaterial, int secondMaterial, CollisionCallback callback)
|
void PhysWorld3D::SetMaterialCollisionCallback(int firstMaterial, int secondMaterial, AABBOverlapCallback aabbOverlapCallback, CollisionCallback collisionCallback)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(Nz::UInt64) >= 2 * sizeof(int), "Oops");
|
static_assert(sizeof(Nz::UInt64) >= 2 * sizeof(int), "Oops");
|
||||||
|
|
||||||
auto callbackPtr = std::make_unique<Callback>();
|
auto callbackPtr = std::make_unique<Callback>();
|
||||||
callbackPtr->collisionCallback = std::move(callback);
|
callbackPtr->aabbOverlapCallback = std::move(aabbOverlapCallback);
|
||||||
|
callbackPtr->collisionCallback = std::move(collisionCallback);
|
||||||
|
|
||||||
NewtonMaterialSetCollisionCallback(m_world, firstMaterial, secondMaterial, callbackPtr.get(), nullptr, ProcessContact);
|
NewtonMaterialSetCollisionCallback(m_world, firstMaterial, secondMaterial, callbackPtr.get(), (callbackPtr->aabbOverlapCallback) ? OnAABBOverlap : nullptr, (callbackPtr->collisionCallback) ? ProcessContact : nullptr);
|
||||||
|
|
||||||
Nz::UInt64 firstMaterialId(firstMaterial);
|
Nz::UInt64 firstMaterialId(firstMaterial);
|
||||||
Nz::UInt64 secondMaterialId(secondMaterial);
|
Nz::UInt64 secondMaterialId(secondMaterial);
|
||||||
|
|
@ -90,6 +91,31 @@ namespace Nz
|
||||||
m_callbacks[callbackIndex] = std::move(callbackPtr);
|
m_callbacks[callbackIndex] = std::move(callbackPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysWorld3D::SetMaterialDefaultCollidable(int firstMaterial, int secondMaterial, bool collidable)
|
||||||
|
{
|
||||||
|
NewtonMaterialSetDefaultCollidable(m_world, firstMaterial, secondMaterial, collidable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysWorld3D::SetMaterialDefaultElasticity(int firstMaterial, int secondMaterial, float elasticCoef)
|
||||||
|
{
|
||||||
|
NewtonMaterialSetDefaultElasticity(m_world, firstMaterial, secondMaterial, elasticCoef);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysWorld3D::SetMaterialDefaultFriction(int firstMaterial, int secondMaterial, float staticFriction, float kineticFriction)
|
||||||
|
{
|
||||||
|
NewtonMaterialSetDefaultFriction(m_world, firstMaterial, secondMaterial, staticFriction, kineticFriction);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysWorld3D::SetMaterialDefaultSoftness(int firstMaterial, int secondMaterial, float softness)
|
||||||
|
{
|
||||||
|
NewtonMaterialSetDefaultSoftness(m_world, firstMaterial, secondMaterial, softness);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysWorld3D::SetMaterialSurfaceThickness(int firstMaterial, int secondMaterial, float thickness)
|
||||||
|
{
|
||||||
|
NewtonMaterialSetSurfaceThickness(m_world, firstMaterial, secondMaterial, thickness);
|
||||||
|
}
|
||||||
|
|
||||||
void PhysWorld3D::Step(float timestep)
|
void PhysWorld3D::Step(float timestep)
|
||||||
{
|
{
|
||||||
m_timestepAccumulator += timestep;
|
m_timestepAccumulator += timestep;
|
||||||
|
|
@ -101,6 +127,19 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PhysWorld3D::OnAABBOverlap(const NewtonMaterial* const material, const NewtonBody* const body0, const NewtonBody* const body1, int threadIndex)
|
||||||
|
{
|
||||||
|
Nz::RigidBody3D* bodyA = static_cast<Nz::RigidBody3D*>(NewtonBodyGetUserData(body0));
|
||||||
|
Nz::RigidBody3D* bodyB = static_cast<Nz::RigidBody3D*>(NewtonBodyGetUserData(body1));
|
||||||
|
assert(bodyA && bodyB);
|
||||||
|
|
||||||
|
Callback* callbackData = static_cast<Callback*>(NewtonMaterialGetMaterialPairUserData(material));
|
||||||
|
assert(callbackData);
|
||||||
|
assert(callbackData->aabbOverlapCallback);
|
||||||
|
|
||||||
|
return callbackData->aabbOverlapCallback(*bodyA, *bodyB);
|
||||||
|
}
|
||||||
|
|
||||||
void PhysWorld3D::ProcessContact(const NewtonJoint* const contactJoint, float timestep, int threadIndex)
|
void PhysWorld3D::ProcessContact(const NewtonJoint* const contactJoint, float timestep, int threadIndex)
|
||||||
{
|
{
|
||||||
Nz::RigidBody3D* bodyA = static_cast<Nz::RigidBody3D*>(NewtonBodyGetUserData(NewtonJointGetBody0(contactJoint)));
|
Nz::RigidBody3D* bodyA = static_cast<Nz::RigidBody3D*>(NewtonBodyGetUserData(NewtonJointGetBody0(contactJoint)));
|
||||||
|
|
@ -123,6 +162,7 @@ namespace Nz
|
||||||
NewtonMaterial* material = NewtonContactGetMaterial(contact);
|
NewtonMaterial* material = NewtonContactGetMaterial(contact);
|
||||||
Callback* callbackData = static_cast<Callback*>(NewtonMaterialGetMaterialPairUserData(material));
|
Callback* callbackData = static_cast<Callback*>(NewtonMaterialGetMaterialPairUserData(material));
|
||||||
assert(callbackData);
|
assert(callbackData);
|
||||||
|
assert(callbackData->collisionCallback);
|
||||||
|
|
||||||
if (!callbackData->collisionCallback(*bodyA, *bodyB))
|
if (!callbackData->collisionCallback(*bodyA, *bodyB))
|
||||||
NewtonContactJointRemoveContact(contactJoint, contact);
|
NewtonContactJointRemoveContact(contactJoint, contact);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue