converted to Jolt physics

This commit is contained in:
2025-11-23 02:00:31 +03:00
parent 3f0484e87c
commit cd82fb0eed
52 changed files with 4302 additions and 1458 deletions

View File

@@ -7,9 +7,6 @@
#include "Ogre.h"
#include "OgreApplicationContext.h"
#include "Bullet/OgreBullet.h"
#include "BulletCollision/CollisionDispatch/btGhostObject.h"
#include "LinearMath/btTransform.h"
#include "OgrePageManager.h"
#include "Procedural.h"
@@ -22,11 +19,8 @@ using Real = Ogre::Real;
using Math = Ogre::Math;
class WorldData {
std::unique_ptr<Ogre::Bullet::DynamicsWorld> mDynWorld;
std::unique_ptr<Ogre::Bullet::DebugDrawer> mDbgDraw;
std::unique_ptr<Ogre::Root> mRoot;
std::unique_ptr<Ogre::SceneManager> mScnMgr;
std::unique_ptr<btDynamicsWorld> mbtWorld;
std::unique_ptr<Ogre::PageManager> mPageManager;
Ogre::PagedWorld *mPagedWorld;
@@ -62,13 +56,8 @@ private:
DummyPageProvider mDummyPageProvider;
WorldData(Ogre::Root *root, Ogre::SceneManager *scnMgr)
: mDynWorld(new Ogre::Bullet::DynamicsWorld(
Ogre::Vector3(0, -9.8, 0)))
, mDbgDraw(new Ogre::Bullet::DebugDrawer(
scnMgr->getRootSceneNode(), mDynWorld->getBtWorld()))
, mRoot(root)
: mRoot(root)
, mScnMgr(scnMgr)
, mbtWorld(mDynWorld->getBtWorld())
, mPageManager(nullptr)
, mPagedWorld(nullptr)
{
@@ -100,94 +89,8 @@ public:
void createTrimesh(Ogre::Entity *entity)
{
}
btPairCachingGhostObject *addGhostObject(Ogre::Entity *ent,
btCollisionShape *shape,
int group = 1,
int mask = 0xFFFF)
{
btDynamicsWorld *world = mDynWorld->getBtWorld();
Ogre::SceneNode *node = ent->getParentSceneNode();
btPairCachingGhostObject *ghost =
new btPairCachingGhostObject();
ghost->setCollisionShape(shape);
ghost->setCollisionFlags(
ghost->getCollisionFlags() |
btCollisionObject::CF_NO_CONTACT_RESPONSE |
btCollisionObject::CF_CHARACTER_OBJECT);
getWorld()->attachCollisionObject(ghost, ent, group, mask);
#if 0
getBtWorld()
->getBroadphase()->getOverlappingPairCache()
->setInternalGhostPairCallback(new btGhostPairCallback());
ghost->setUserPointer(new EntityCollisionListener{ent, nullptr});
#endif
return ghost;
}
btRigidBody *addRigidBody(float mass, Ogre::Entity *ent,
Ogre::Bullet::ColliderType ct, int group = 1,
int mask = 0xFFFF)
{
btDynamicsWorld *world = mDynWorld->getBtWorld();
Ogre::SceneNode *node = ent->getParentSceneNode();
Ogre::Bullet::RigidBodyState *state =
new Ogre::Bullet::RigidBodyState(node);
btCollisionShape *cs;
btCollisionShape *shape;
btVector3 inertia(0, 0, 0);
switch (ct) {
case Ogre::Bullet::CT_TRIMESH: {
cs = Ogre::Bullet::createTrimeshCollider(ent);
if (mass != 0)
cs->calculateLocalInertia(mass, inertia);
} break;
case Ogre::Bullet::CT_CAPSULE: {
cs = new btCompoundShape(false);
btScalar height = 1.0f;
btScalar radius = 0.3f;
shape = new btCapsuleShape(radius,
2 * height - 2 * radius);
btTransform transform;
transform.setIdentity();
transform.setOrigin(btVector3(0, 1, 0));
static_cast<btCompoundShape *>(cs)->addChildShape(
transform, shape);
btScalar masses[1] = { mass };
btTransform principal;
static_cast<btCompoundShape *>(cs)
->calculatePrincipalAxisTransform(
masses, principal, inertia);
} break;
default:
assert(false);
break;
}
btRigidBody *body = new btRigidBody(mass, state, cs, inertia);
getWorld()->attachRigidBody(body, ent, nullptr, group, mask);
#if 0
body->setUserPointer(new EntityCollisionListener{ent, nullptr});
// btRigidBody *body = mDynWorld->addRigidBody(0, ent, Ogre::Bullet::CT_TRIMESH);
#endif
return body;
}
btRigidBody *addKinematicRigidBody(float mass, Ogre::Entity *ent,
Ogre::Bullet::ColliderType ct,
int group = 1, int mask = 0xFFFF)
{
return mDynWorld->addKinematicRigidBody(ent, ct, group, mask);
}
btDynamicsWorld *getBtWorld()
{
return mDynWorld->getBtWorld();
}
Ogre::Bullet::DynamicsWorld *getWorld()
{
return mDynWorld.get();
}
void update(float delta)
{
WorldData::get_singleton()->getBtWorld()->stepSimulation(delta,
10);
mDbgDraw->update();
}
void initPagedWorld(Ogre::Camera *camera)
{
@@ -201,8 +104,6 @@ public:
WorldData *WorldData::singleton = nullptr;
class MainWorld : public Ogre::FrameListener {
btRigidBody *mFloorBody;
public:
void setup()
{
@@ -220,13 +121,6 @@ public:
WorldData::get_singleton()->getSceneManager();
Ogre::Entity *floor = scnMgr->createEntity("Floor", "floor");
scnMgr->getRootSceneNode()->attachObject(floor);
mFloorBody = WorldData::get_singleton()->addRigidBody(
0, floor, Ogre::Bullet::CT_TRIMESH);
}
btRigidBody *addCharacter(Ogre::Entity *ent, float mass)
{
return WorldData::get_singleton()->addKinematicRigidBody(
mass, ent, Ogre::Bullet::CT_COMPOUND);
}
bool frameStarted(const Ogre::FrameEvent &evt) override;
};
@@ -266,8 +160,6 @@ class CharacterController : public OgreBites::InputListener,
Ogre::Vector3 rootMotion;
Ogre::Quaternion rootRotation;
// btRigidBody *mRigidBody;
btCompoundShape *mCollisionShape;
btPairCachingGhostObject *mGhostObject;
public:
CharacterController(Ogre::SceneNode *camNode, Ogre::Camera *cam,
@@ -316,35 +208,6 @@ private:
recoverResult *recover_result,
const std::set<btCollisionObject *> &exclude);
#endif
inline btQuaternion convert(const Ogre::Quaternion &q)
{
return btQuaternion(q.x, q.y, q.z, q.w);
}
inline btVector3 convert(const Ogre::Vector3 &v)
{
return btVector3(v.x, v.y, v.z);
}
inline btTransform convert(const Ogre::Quaternion &q,
const Ogre::Vector3 &v)
{
btQuaternion mq = convert(q);
btVector3 mv = convert(v);
return btTransform(mq, mv);
}
inline Ogre::Quaternion convert(const btQuaternion &q)
{
return Ogre::Quaternion(q.w(), q.x(), q.y(), q.z());
}
inline Ogre::Vector3 convert(const btVector3 &v)
{
return Ogre::Vector3(v.x(), v.y(), v.z());
}
inline void convert(const btTransform &from, Ogre::Quaternion &q,
Ogre::Vector3 &v)
{
q = convert(from.getRotation());
v = convert(from.getOrigin());
}
};
CharacterController::CharacterController(Ogre::SceneNode *camNode,
Ogre::Camera *cam,
@@ -358,8 +221,6 @@ CharacterController::CharacterController(Ogre::SceneNode *camNode,
, mAnimID(ANIM_NONE)
, mRunning(false)
, world(world)
, mCollisionShape(nullptr)
, mGhostObject(nullptr)
{
setupBody();
setupCamera();
@@ -374,72 +235,6 @@ void CharacterController::setupBody()
mBodyNode = mScnMgr->getRootSceneNode()->createChildSceneNode();
mBodyNode->attachObject(mBodyEnt);
mSkeleton = mBodyEnt->getSkeleton();
// mRigidBody = world->addCharacter(mBodyEnt, 0);
// mCollisionShape = static_cast<btCompoundShape *>(mRigidBody->getCollisionShape());
mGhostObject = new btPairCachingGhostObject();
mCollisionShape = new btCompoundShape(false);
mGhostObject->setCollisionShape(mCollisionShape);
{
btVector3 inertia(0, 0, 0);
// mCollisionShape = new btCompoundShape();
btScalar height = 1.0f;
btScalar radius = 0.3f;
btCapsuleShape *shape =
new btCapsuleShape(radius, 2 * height - 2 * radius);
btTransform transform;
transform.setIdentity();
transform.setOrigin(btVector3(0, 1, 0));
static_cast<btCompoundShape *>(mCollisionShape)
->addChildShape(transform, shape);
btScalar masses[1] = { 0 };
btTransform principal;
static_cast<btCompoundShape *>(mCollisionShape)
->calculatePrincipalAxisTransform(masses, principal,
inertia);
}
mGhostObject->setCollisionFlags(
btCollisionObject::CF_KINEMATIC_OBJECT |
btCollisionObject::CF_NO_CONTACT_RESPONSE);
mGhostObject->setActivationState(DISABLE_DEACTIVATION);
Ogre::Bullet::KinematicMotionSimple *controller =
new Ogre::Bullet::KinematicMotionSimple(mGhostObject,
mBodyNode);
WorldData::get_singleton()->getWorld()->attachCollisionObject(
mGhostObject, mBodyEnt, btBroadphaseProxy::AllFilter,
btBroadphaseProxy::AllFilter);
WorldData::get_singleton()->getBtWorld()->addAction(controller);
assert(mCollisionShape);
#if 0
if (mRigidBody->getMass() == 0) {
#if 0
mRigidBody->setCollisionFlags(mRigidBody->getCollisionFlags()
| btCollisionObject::CF_KINEMATIC_OBJECT
| btCollisionObject::CF_NO_CONTACT_RESPONSE
);
#endif
#if 0
mGhostObject->setWorldTransform(mRigidBody->getWorldTransform());
WorldData::get_singleton()->getBtWorld()
->getBroadphase()->getOverlappingPairCache()
->setInternalGhostPairCallback(new btGhostPairCallback());
#endif
}
#endif
#if 0
mRigidBody->setActivationState(DISABLE_DEACTIVATION);
#endif
#if 0
{
Ogre::Entity *e2 = mScnMgr->createEntity("normal-male.glb");
Ogre::SceneNode *e2node = mScnMgr->getRootSceneNode()->createChildSceneNode();
e2node->attachObject(e2);
mGhostObject = WorldData::get_singleton()->addGhostObject(e2, mCollisionShape);
mController = new btKinematicCharacterController(mGhostObject, mCollisionShape, 0.5f);
WorldData::get_singleton()->getBtWorld()->addAction(mController);
}
#endif
assert(mSkeleton->hasBone("Root"));
mRootBone = mSkeleton->getBone("Root");
assert(mRootBone);
@@ -740,8 +535,6 @@ void CharacterController::updateRootMotion(Real delta)
Ogre::Vector3 velocity = rot * boneMotion / delta;
velocity += gravity * delta;
Ogre::Vector3 rotMotion = velocity * delta;
btTransform from(convert(mBodyNode->getOrientation()),
convert(mBodyNode->getPosition()));
mBodyNode->setPosition(mBodyNode->getPosition() + rotMotion);
// WorldData::get_singleton()->getWorld()->testBodyMotion(mRigidBody, from, Ogre::Bullet::convert(rotMotion), true,
// nullptr, false, std::set<btCollisionObject *>());