Better boat handling
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
#include <Jolt/Physics/Collision/Shape/MutableCompoundShape.h>
|
||||
#include <Jolt/Physics/Collision/Shape/HeightFieldShape.h>
|
||||
#include <Jolt/Physics/Collision/Shape/OffsetCenterOfMassShape.h>
|
||||
#include <Jolt/Physics/Collision/ContactListener.h>
|
||||
#include <Jolt/Physics/Body/BodyCreationSettings.h>
|
||||
#include <Jolt/Physics/Body/BodyActivationListener.h>
|
||||
#include <Jolt/Renderer/DebugRendererSimple.h>
|
||||
@@ -156,6 +157,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
// An example contact listener
|
||||
class MyContactListener : public JPH::ContactListener {
|
||||
public:
|
||||
@@ -209,6 +211,7 @@ public:
|
||||
std::cout << "A body went to sleep" << std::endl;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
class MyCollector : public JPH::CollideShapeBodyCollector {
|
||||
public:
|
||||
MyCollector(JPH::PhysicsSystem *inSystem,
|
||||
@@ -453,6 +456,56 @@ JPH::ShapeRefC CompoundShapeBuilder::build()
|
||||
JPH::ShapeSettings::ShapeResult result = shapeSettings.Create();
|
||||
return result.Get();
|
||||
}
|
||||
ContactListener::ContactListener()
|
||||
: JPH::ContactListener()
|
||||
, dispatch(nullptr)
|
||||
{
|
||||
}
|
||||
JPH::ValidateResult ContactListener::OnContactValidate(
|
||||
const JPH::Body &inBody1, const JPH::Body &inBody2,
|
||||
JPH::RVec3Arg inBaseOffset,
|
||||
const JPH::CollideShapeResult &inCollisionResult)
|
||||
{
|
||||
return JPH::ValidateResult::AcceptAllContactsForThisBodyPair;
|
||||
}
|
||||
void ContactListener::OnContactAdded(const JPH::Body &inBody1,
|
||||
const JPH::Body &inBody2,
|
||||
const JPH::ContactManifold &inManifold,
|
||||
JPH::ContactSettings &ioSettings)
|
||||
{
|
||||
reports.push_back({ true, inBody1.GetID(), inBody2.GetID(), inManifold,
|
||||
ioSettings });
|
||||
}
|
||||
void ContactListener::OnContactPersisted(const JPH::Body &inBody1,
|
||||
const JPH::Body &inBody2,
|
||||
const JPH::ContactManifold &inManifold,
|
||||
JPH::ContactSettings &ioSettings)
|
||||
{
|
||||
}
|
||||
void ContactListener::OnContactRemoved(const JPH::SubShapeIDPair &inSubShapePair)
|
||||
{
|
||||
reports.push_back({ false, inSubShapePair.GetBody1ID(),
|
||||
inSubShapePair.GetBody2ID(), JPH::ContactManifold(),
|
||||
JPH::ContactSettings() });
|
||||
}
|
||||
void ContactListener::update()
|
||||
{
|
||||
for (auto contact : reports) {
|
||||
bool handled = false;
|
||||
if (listeners.find(contact.id1) != listeners.end()) {
|
||||
listeners[contact.id1](contact);
|
||||
handled = true;
|
||||
}
|
||||
if (listeners.find(contact.id2) != listeners.end()) {
|
||||
listeners[contact.id2](contact);
|
||||
handled = true;
|
||||
}
|
||||
if (!handled && dispatch) {
|
||||
dispatch(contact);
|
||||
}
|
||||
}
|
||||
reports.clear();
|
||||
}
|
||||
}
|
||||
|
||||
class Physics {
|
||||
@@ -498,29 +551,9 @@ public:
|
||||
virtual void OnBodyDeactivated(const JPH::BodyID &inBodyID,
|
||||
JPH::uint64 inBodyUserData) = 0;
|
||||
};
|
||||
class ContactListener : public JPH::ContactListener {
|
||||
public:
|
||||
virtual JPH::ValidateResult OnContactValidate(
|
||||
const JPH::Body &inBody1, const JPH::Body &inBody2,
|
||||
JPH::RVec3Arg inBaseOffset,
|
||||
const JPH::CollideShapeResult &inCollisionResult) = 0;
|
||||
virtual void
|
||||
OnContactAdded(const JPH::Body &inBody1,
|
||||
const JPH::Body &inBody2,
|
||||
const JPH::ContactManifold &inManifold,
|
||||
JPH::ContactSettings &ioSettings) = 0;
|
||||
virtual void
|
||||
OnContactPersisted(const JPH::Body &inBody1,
|
||||
const JPH::Body &inBody2,
|
||||
const JPH::ContactManifold &inManifold,
|
||||
JPH::ContactSettings &ioSettings) = 0;
|
||||
|
||||
virtual void
|
||||
OnContactRemoved(const JPH::SubShapeIDPair &inSubShapePair) = 0;
|
||||
};
|
||||
Physics(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
ActivationListener *activationListener = nullptr,
|
||||
ContactListener *contactListener = nullptr)
|
||||
JPH::ContactListener *contactListener = nullptr)
|
||||
: temp_allocator(10 * 1024 * 1024)
|
||||
, job_system(JPH::cMaxPhysicsJobs, JPH::cMaxPhysicsBarriers,
|
||||
std::thread::hardware_concurrency() - 1)
|
||||
@@ -740,8 +773,10 @@ public:
|
||||
node->_setDerivedPosition(JoltPhysics::convert(p));
|
||||
node->_setDerivedOrientation(JoltPhysics::convert(q));
|
||||
}
|
||||
for (JPH::Character *ch : characters)
|
||||
ch->PostSimulation(0.1f);
|
||||
for (JPH::Character *ch : characters) {
|
||||
if (body_interface.IsAdded(ch->GetBodyID()))
|
||||
ch->PostSimulation(0.1f);
|
||||
}
|
||||
|
||||
if (debugDraw)
|
||||
physics_system.DrawBodies(
|
||||
@@ -873,7 +908,7 @@ public:
|
||||
if (shape->GetType() == JPH::EShapeType::HeightField) {
|
||||
JPH::BodyInterface &body_interface =
|
||||
physics_system.GetBodyInterface();
|
||||
body_interface.SetFriction(id, 0.7f);
|
||||
body_interface.SetFriction(id, 1.0f);
|
||||
}
|
||||
id2node[id] = node;
|
||||
node2id[node] = id;
|
||||
@@ -1385,6 +1420,21 @@ public:
|
||||
physics_system.GetBodyInterface().GetLinearVelocity(
|
||||
id));
|
||||
}
|
||||
Ogre::Vector3 getAngularVelocity(JPH::BodyID id)
|
||||
{
|
||||
return JoltPhysics::convert(
|
||||
physics_system.GetBodyInterface().GetAngularVelocity(
|
||||
id));
|
||||
}
|
||||
float getFriction(JPH::BodyID id)
|
||||
{
|
||||
return physics_system.GetBodyInterface().GetFriction(id);
|
||||
}
|
||||
void setFriction(JPH::BodyID id, float friction)
|
||||
{
|
||||
return physics_system.GetBodyInterface().SetFriction(id,
|
||||
friction);
|
||||
}
|
||||
void broadphaseQuery(float dt, const Ogre::Vector3 &position,
|
||||
std::set<JPH::BodyID> &inWater)
|
||||
{
|
||||
@@ -1434,7 +1484,7 @@ JoltPhysicsWrapper::JoltPhysicsWrapper(Ogre::SceneManager *scnMgr,
|
||||
JPH::Trace = TraceImpl;
|
||||
JPH_IF_ENABLE_ASSERTS(JPH::AssertFailed = AssertFailedImpl;)
|
||||
|
||||
phys = new Physics(scnMgr, cameraNode);
|
||||
phys = new Physics(scnMgr, cameraNode, nullptr, &contacts);
|
||||
}
|
||||
|
||||
JoltPhysicsWrapper::~JoltPhysicsWrapper()
|
||||
@@ -1446,6 +1496,7 @@ JoltPhysicsWrapper::~JoltPhysicsWrapper()
|
||||
void JoltPhysicsWrapper::update(float dt)
|
||||
{
|
||||
phys->update(dt);
|
||||
contacts.update();
|
||||
}
|
||||
|
||||
void JoltPhysicsWrapper::addBody(const JPH::BodyID &body,
|
||||
@@ -1629,6 +1680,10 @@ void JoltPhysicsWrapper::setPosition(JPH::BodyID id,
|
||||
{
|
||||
return phys->setPosition(id, position, activate);
|
||||
}
|
||||
Ogre::Quaternion JoltPhysicsWrapper::getRotation(JPH::BodyID id)
|
||||
{
|
||||
return phys->getRotation(id);
|
||||
}
|
||||
void JoltPhysicsWrapper::setRotation(JPH::BodyID id,
|
||||
const Ogre::Quaternion &rotation,
|
||||
bool activate)
|
||||
@@ -1651,10 +1706,41 @@ Ogre::Vector3 JoltPhysicsWrapper::getLinearVelocity(JPH::BodyID id)
|
||||
{
|
||||
return phys->getLinearVelocity(id);
|
||||
}
|
||||
Ogre::Vector3 JoltPhysicsWrapper::getAngularVelocity(JPH::BodyID id)
|
||||
{
|
||||
return phys->getAngularVelocity(id);
|
||||
}
|
||||
float JoltPhysicsWrapper::getFriction(JPH::BodyID id)
|
||||
{
|
||||
return phys->getFriction(id);
|
||||
}
|
||||
void JoltPhysicsWrapper::setFriction(JPH::BodyID id, float friction)
|
||||
{
|
||||
phys->setFriction(id, friction);
|
||||
}
|
||||
void JoltPhysicsWrapper::addAngularImpulse(const JPH::BodyID &id,
|
||||
const Ogre::Vector3 &impulse)
|
||||
{
|
||||
return phys->addAngularImpulse(id, impulse);
|
||||
}
|
||||
void JoltPhysicsWrapper::setDispatch(
|
||||
std::function<
|
||||
void(const JoltPhysics::ContactListener::ContactReport &report)>
|
||||
dispatcher)
|
||||
{
|
||||
contacts.setDispatch(dispatcher);
|
||||
}
|
||||
void JoltPhysicsWrapper::addContactListener(
|
||||
const JPH::BodyID &id,
|
||||
std::function<
|
||||
void(const JoltPhysics::ContactListener::ContactReport &report)>
|
||||
listener)
|
||||
{
|
||||
contacts.addListener(id, listener);
|
||||
}
|
||||
void JoltPhysicsWrapper::removeContactListener(const JPH::BodyID &id)
|
||||
{
|
||||
contacts.removeListener(id);
|
||||
}
|
||||
template <>
|
||||
JoltPhysicsWrapper *Ogre::Singleton<JoltPhysicsWrapper>::msSingleton = 0;
|
||||
JoltPhysicsWrapper *Ogre::Singleton<JoltPhysicsWrapper>::msSingleton = 0;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <Jolt/Physics/Collision/Shape/Shape.h>
|
||||
#include <Jolt/Physics/Collision/Shape/StaticCompoundShape.h>
|
||||
#include <Jolt/Physics/Collision/ObjectLayer.h>
|
||||
#include <Jolt/Physics/Collision/ContactListener.h>
|
||||
#include <Jolt/Physics/Collision/BroadPhase/BroadPhaseLayer.h>
|
||||
#include <Jolt/Physics/Body/BodyCreationSettings.h>
|
||||
#include <Jolt/Physics/EActivation.h>
|
||||
@@ -13,6 +14,9 @@ void physics();
|
||||
namespace JPH
|
||||
{
|
||||
class CharacterBase;
|
||||
class ContactManifold;
|
||||
class ContactSettings;
|
||||
class SubShapeIDPair;
|
||||
}
|
||||
// Layer that objects can be in, determines which other objects it can collide with
|
||||
// Typically you at least want to have 1 layer for moving bodies and 1 layer for static bodies, but you can have more
|
||||
@@ -50,10 +54,58 @@ struct CompoundShapeBuilder {
|
||||
const Ogre::Quaternion &rotation);
|
||||
JPH::ShapeRefC build();
|
||||
};
|
||||
class ContactListener : public JPH::ContactListener {
|
||||
public:
|
||||
struct ContactReport {
|
||||
bool entered;
|
||||
JPH::BodyID id1, id2;
|
||||
JPH::ContactManifold manifold;
|
||||
JPH::ContactSettings settings;
|
||||
};
|
||||
|
||||
private:
|
||||
std::list<ContactReport> reports;
|
||||
std::function<void(const ContactReport &report)> dispatch;
|
||||
std::map<JPH::BodyID, std::function<void(const ContactReport &report)> >
|
||||
listeners;
|
||||
|
||||
public:
|
||||
ContactListener();
|
||||
JPH::ValidateResult OnContactValidate(
|
||||
const JPH::Body &inBody1, const JPH::Body &inBody2,
|
||||
JPH::RVec3Arg inBaseOffset,
|
||||
const JPH::CollideShapeResult &inCollisionResult) override;
|
||||
void OnContactAdded(const JPH::Body &inBody1, const JPH::Body &inBody2,
|
||||
const JPH::ContactManifold &inManifold,
|
||||
JPH::ContactSettings &ioSettings) override;
|
||||
void OnContactPersisted(const JPH::Body &inBody1,
|
||||
const JPH::Body &inBody2,
|
||||
const JPH::ContactManifold &inManifold,
|
||||
JPH::ContactSettings &ioSettings) override;
|
||||
void
|
||||
OnContactRemoved(const JPH::SubShapeIDPair &inSubShapePair) override;
|
||||
void setDispatch(const std::function<void(const ContactReport &report)>
|
||||
dispatcher)
|
||||
{
|
||||
dispatch = dispatcher;
|
||||
}
|
||||
void addListener(
|
||||
const JPH::BodyID &id,
|
||||
const std::function<void(const ContactReport &report)> listener)
|
||||
{
|
||||
listeners[id] = listener;
|
||||
}
|
||||
void removeListener(const JPH::BodyID &id)
|
||||
{
|
||||
listeners.erase(id);
|
||||
}
|
||||
void update();
|
||||
};
|
||||
}
|
||||
|
||||
class JoltPhysicsWrapper : public Ogre::Singleton<JoltPhysicsWrapper> {
|
||||
public:
|
||||
JoltPhysics::ContactListener contacts;
|
||||
JoltPhysicsWrapper(Ogre::SceneManager *scnMgr,
|
||||
Ogre::SceneNode *cameraNode);
|
||||
~JoltPhysicsWrapper();
|
||||
@@ -128,6 +180,7 @@ public:
|
||||
Ogre::Vector3 getPosition(JPH::BodyID id);
|
||||
void setPosition(JPH::BodyID id, const Ogre::Vector3 &position,
|
||||
bool activate = true);
|
||||
Ogre::Quaternion getRotation(JPH::BodyID id);
|
||||
void setRotation(JPH::BodyID id, const Ogre::Quaternion &rotation,
|
||||
bool activate = true);
|
||||
void getPositionAndRotation(JPH::BodyID id, Ogre::Vector3 &position,
|
||||
@@ -137,7 +190,19 @@ public:
|
||||
const Ogre::Quaternion &rotation,
|
||||
bool activate = true);
|
||||
Ogre::Vector3 getLinearVelocity(JPH::BodyID id);
|
||||
Ogre::Vector3 getAngularVelocity(JPH::BodyID id);
|
||||
float getFriction(JPH::BodyID id);
|
||||
void setFriction(JPH::BodyID id, float friction);
|
||||
void addAngularImpulse(const JPH::BodyID &id,
|
||||
const Ogre::Vector3 &impulse);
|
||||
void setDispatch(std::function<void(const JoltPhysics::ContactListener::
|
||||
ContactReport &report)>
|
||||
dispatcher);
|
||||
void addContactListener(
|
||||
const JPH::BodyID &id,
|
||||
const std::function<void(const JoltPhysics::ContactListener::
|
||||
ContactReport &report)>
|
||||
listener);
|
||||
void removeContactListener(const JPH::BodyID &id);
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user