fix physics sleeping, and start adding btKinematicCharacterController to Humanoid

This commit is contained in:
floralrainfall 2023-07-21 18:39:16 -04:00
parent 553362494d
commit c8c64ac392
11 changed files with 106 additions and 22 deletions

2
Dependencies/Luau vendored

@ -1 +1 @@
Subproject commit 218159140c7d79ae745e646da721d12331f536f5 Subproject commit e25de95445f2d635a125ab463426bb7fda017093

View File

@ -2,6 +2,10 @@
#include <App/V8/Tree/Instance.hpp> #include <App/V8/Tree/Instance.hpp>
#include <App/V8/DataModel/PartInstance.hpp> #include <App/V8/DataModel/PartInstance.hpp>
#include <App/V8/World/ComPlicitNgine.hpp>
#include "BulletDynamics/Character/btKinematicCharacterController.h"
#include "LinearMath/btVector3.h"
#include "btBulletDynamicsCommon.h"
namespace RNR namespace RNR
{ {
@ -33,5 +37,7 @@ namespace RNR
float m_health; float m_health;
float m_maxHealth; float m_maxHealth;
float m_walkRotationalVelocity; float m_walkRotationalVelocity;
btKinematicCharacterController* m_characterController;
btPairCachingGhostObject* m_playerGhostObject;
}; };
} }

View File

@ -18,6 +18,7 @@ namespace RNR
Ogre::Vector3 relativePositionTo(PVInstance* point); Ogre::Vector3 relativePositionTo(PVInstance* point);
virtual std::string getClassName() { return "PVInstance"; } virtual std::string getClassName() { return "PVInstance"; }
Ogre::Vector3 getRelativePosition(PVInstance* other) { return other->getPosition() - getPosition(); }
Ogre::Vector3 getPosition() { return m_cframe.getPosition(); } Ogre::Vector3 getPosition() { return m_cframe.getPosition(); }
Ogre::Matrix3 getRotation() { return m_cframe.getRotation(); } Ogre::Matrix3 getRotation() { return m_cframe.getRotation(); }
}; };

View File

@ -20,6 +20,9 @@ namespace RNR
World* m_world; World* m_world;
std::map<PartInstance*, btRigidBody*> m_physicsParts; std::map<PartInstance*, btRigidBody*> m_physicsParts;
int m_sleepingObjects;
int m_activeObjects;
void thread(); void thread();
public: public:
ComPlicitNgine(World* world); ComPlicitNgine(World* world);
@ -35,6 +38,10 @@ namespace RNR
btRigidBody* getBody(PartInstance* part) { return m_physicsParts[part]; }; btRigidBody* getBody(PartInstance* part) { return m_physicsParts[part]; };
void registerPhysicsPart(PartInstance* partRegistered); void registerPhysicsPart(PartInstance* partRegistered);
void updatePhysicsPart(PartInstance* partUpdate);
void deletePhysicsPart(PartInstance* partDelete); void deletePhysicsPart(PartInstance* partDelete);
int getSleepingObjects() { return m_sleepingObjects; }
int getActiveObjects() { return m_activeObjects; }
}; };
} }

View File

@ -76,6 +76,6 @@ namespace RNR
Ogre::SceneManager* getOgreSceneManager() { return m_ogreSceneManager; } Ogre::SceneManager* getOgreSceneManager() { return m_ogreSceneManager; }
bool getPhysicsShouldBeRunningPleaseStopIfItIsStillRunning() { return m_runPhysics; } bool getPhysicsShouldBeRunningPleaseStopIfItIsStillRunning() { return m_runPhysics; }
Lock physicsIterateLock; Lock dynamicWorldLock;
}; };
} }

View File

@ -125,6 +125,7 @@ namespace RNR
{ {
Workspace* workspace = m_world->getWorkspace(); Workspace* workspace = m_world->getWorkspace();
btDiscreteDynamicsWorld* dynamicsWorld = m_world->getDynamicsWorld(); btDiscreteDynamicsWorld* dynamicsWorld = m_world->getDynamicsWorld();
ComPlicitNgine* ngine = m_world->getComPlicitNgine();
char debugtext[512]; char debugtext[512];
char render_debugtext[255]; char render_debugtext[255];
@ -137,11 +138,11 @@ namespace RNR
snprintf(render_debugtext, 255, "using BATCH_STATIC_GEOMETRY\nGeom Regions: %i", workspace->m_geom->getRegions().size()); snprintf(render_debugtext, 255, "using BATCH_STATIC_GEOMETRY\nGeom Regions: %i", workspace->m_geom->getRegions().size());
break; break;
} }
snprintf(debugtext, 512, "Render\nLast DT = %f\n%s\n\nPhysics\nDT = %f\n%i objects, %i constraints\nRunService: running = %s, paused = %s", snprintf(debugtext, 512, "Render\nLast DT = %f\n%s\n\nPhysics\nDT = %f\n%i objects (%i active, %i sleeping), %i constraints\nRunService: running = %s, paused = %s",
m_world->getLastDelta(), m_world->getLastDelta(),
render_debugtext, render_debugtext,
m_world->getLastPhysicsDelta(), m_world->getLastPhysicsDelta(),
dynamicsWorld->getNumCollisionObjects(), dynamicsWorld->getNumConstraints(), dynamicsWorld->getNumCollisionObjects(), ngine->getActiveObjects(), ngine->getSleepingObjects(), dynamicsWorld->getNumConstraints(),
m_world->getRunService()->getRunning() ? "true" : "false", m_world->getRunService()->getRunning() ? "true" : "false",
m_world->getRunService()->getPaused() ? "true" : "false"); m_world->getRunService()->getPaused() ? "true" : "false");
m_debugText->setCaption(debugtext); m_debugText->setCaption(debugtext);

View File

@ -2,6 +2,9 @@
#include <App/V8/World/World.hpp> #include <App/V8/World/World.hpp>
#include <App/V8/World/Weld.hpp> #include <App/V8/World/Weld.hpp>
#include <App/InputManager.hpp> #include <App/InputManager.hpp>
#include "btBulletCollisionCommon.h"
#include "BulletCollision/CollisionDispatch/btGhostObject.h"
#include <Helpers/Bullet.hpp>
namespace RNR namespace RNR
{ {
@ -11,6 +14,15 @@ namespace RNR
m_maxHealth = 100.f; m_maxHealth = 100.f;
m_health = 100.f; m_health = 100.f;
btBoxShape* playerShape = new btBoxShape(btVector3(1,2,0.5));
m_playerGhostObject = new btPairCachingGhostObject();
world->getDynamicsWorld()->getPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
m_playerGhostObject->setCollisionShape(playerShape);
m_playerGhostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
m_characterController = new btKinematicCharacterController(m_playerGhostObject, playerShape, 0.5, btVector3(0.0, 1.0, 0.0));
} }
Humanoid::~Humanoid() Humanoid::~Humanoid()
@ -32,6 +44,18 @@ namespace RNR
headWeld->create(); headWeld->create();
headWeld->setParent(getTorso()); headWeld->setParent(getTorso());
} }
if(getTorso())
{
btTransform ghostTransform;
ghostTransform.setIdentity();
ghostTransform.setOrigin(Bullet::v3ToBullet(getTorso()->getPosition()));
ghostTransform.setRotation(Bullet::qtToBullet(getTorso()->getRotation()));
m_playerGhostObject->setWorldTransform(ghostTransform);
world->getDynamicsWorld()->addCollisionObject(m_playerGhostObject, btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter|btBroadphaseProxy::DefaultFilter);
world->getDynamicsWorld()->addAction(m_characterController);
}
} }
void Humanoid::checkForJointDeath() void Humanoid::checkForJointDeath()
@ -120,9 +144,11 @@ namespace RNR
if(inputManager->isKeyDown('W')) if(inputManager->isKeyDown('W'))
forward = 16; forward = 16;
Ogre::Vector3 move = Ogre::Vector3(0, 0, -forward); Ogre::Vector3 move = Ogre::Vector3(0, 0, forward);
move = direction * move; move = direction * move;
move *= world->getLastDelta(); move *= world->getComPlicitNgine()->getLastPhysicsDelta();
m_characterController->playerStep(world->getDynamicsWorld(), forward);
bool move_valid = true; bool move_valid = true;
@ -136,13 +162,14 @@ namespace RNR
PartInstance* bp = dynamic_cast<PartInstance*>(child); PartInstance* bp = dynamic_cast<PartInstance*>(child);
if(bp) if(bp)
{ {
Ogre::Vector3 bp_p = bp->getPosition(); Ogre::Vector3 bp_p = bp->getRelativePosition(getTorso());
bp_p += move;
bp->getCFrame().setPosition(bp_p); bp->getCFrame().setPosition(bp_p + Bullet::v3ToOgre(m_characterController->getGhostObject()->getWorldTransform().getOrigin()));
Ogre::Matrix3 new_rotation_matrix; Ogre::Matrix3 new_rotation_matrix;
new_direction.ToRotationMatrix(new_rotation_matrix); new_direction.ToRotationMatrix(new_rotation_matrix);
bp->getCFrame().setRotation(new_rotation_matrix); bp->getCFrame().setRotation(new_rotation_matrix);
bp->updateMatrix(); bp->updateMatrix();
world->getComPlicitNgine()->updatePhysicsPart(bp);
world->getWorkspace()->setDirty(); world->getWorkspace()->setDirty();
} }
} }

View File

@ -16,6 +16,9 @@ namespace RNR
m_lastPhysicsDelta = delta; m_lastPhysicsDelta = delta;
m_physicsTime = time; m_physicsTime = time;
if(m_lastPhysicsDelta == 0)
std::this_thread::sleep_for(std::chrono::milliseconds(1));
m_world->preStep(); m_world->preStep();
m_world->step(delta); m_world->step(delta);
@ -43,20 +46,25 @@ namespace RNR
for(int j = m_dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--) for(int j = m_dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--)
{ {
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[j]; btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[j];
if(!obj->isActive()) if(obj->getActivationState() != ACTIVE_TAG)
continue; continue;
PartInstance* part = (PartInstance*)obj->getUserPointer(); PartInstance* part = (PartInstance*)obj->getUserPointer();
part->updateMatrix(); if(part)
{
part->updateMatrix();
}
} }
} }
void ComPlicitNgine::updateTree() void ComPlicitNgine::updateTree()
{ {
m_activeObjects = 0;
m_sleepingObjects = 0;
for(int j = m_dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--) for(int j = m_dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--)
{ {
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[j]; btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[j];
if(!obj->isActive()) if(obj->getActivationState() != ACTIVE_TAG) { m_sleepingObjects++; continue; }
continue; m_activeObjects++;
btRigidBody* body = btRigidBody::upcast(obj); btRigidBody* body = btRigidBody::upcast(obj);
btTransform trans; btTransform trans;
if(body && body->getMotionState()) if(body && body->getMotionState())
@ -68,11 +76,14 @@ namespace RNR
trans = obj->getWorldTransform(); trans = obj->getWorldTransform();
} }
PartInstance* part = (PartInstance*)obj->getUserPointer(); PartInstance* part = (PartInstance*)obj->getUserPointer();
part->getCFrame().setPosition(Bullet::v3ToOgre(trans.getOrigin())); if(part)
Ogre::Matrix3 partRot; {
Ogre::Quaternion transOgre = Bullet::qtToOgre(trans.getRotation()); part->getCFrame().setPosition(Bullet::v3ToOgre(trans.getOrigin()));
transOgre.ToRotationMatrix(partRot); Ogre::Matrix3 partRot;
part->getCFrame().setRotation(partRot); Ogre::Quaternion transOgre = Bullet::qtToOgre(trans.getRotation());
transOgre.ToRotationMatrix(partRot);
part->getCFrame().setRotation(partRot);
}
} }
} }
@ -99,13 +110,25 @@ namespace RNR
btRigidBody* body = new btRigidBody(rbInfo); btRigidBody* body = new btRigidBody(rbInfo);
body->setUserPointer(partRegistered); body->setUserPointer(partRegistered);
m_world->physicsIterateLock.lock(); m_world->dynamicWorldLock.lock();
m_dynamicsWorld->addRigidBody(body); m_dynamicsWorld->addRigidBody(body);
m_world->physicsIterateLock.unlock(); m_world->dynamicWorldLock.unlock();
m_physicsParts[partRegistered] = body; m_physicsParts[partRegistered] = body;
} }
void ComPlicitNgine::updatePhysicsPart(PartInstance* partUpdate)
{
btRigidBody* toUpdate = m_physicsParts[partUpdate];
if(toUpdate)
{
btTransform& bodytf = toUpdate->getWorldTransform();
bodytf.setIdentity();
bodytf.setOrigin(Bullet::v3ToBullet(partUpdate->getPosition()));
bodytf.setRotation(Bullet::qtToBullet(partUpdate->getRotation()));
}
}
void ComPlicitNgine::deletePhysicsPart(PartInstance* partDelete) void ComPlicitNgine::deletePhysicsPart(PartInstance* partDelete)
{ {
btRigidBody* toDelete = m_physicsParts[partDelete]; btRigidBody* toDelete = m_physicsParts[partDelete];

View File

@ -25,9 +25,17 @@ namespace RNR
void Weld::create() void Weld::create()
{ {
if(!m_aBody || !m_bBody) if(!m_aBody || !m_bBody)
{
printf("Weld::create: invalid body\n");
return; return;
}
m_constraint = new btFixedConstraint(*m_aBody, *m_bBody, m_aBody->getWorldTransform(), m_bBody->getWorldTransform()); btTransform frameInA, frameInB;
frameInA = btTransform::getIdentity();
frameInB = btTransform::getIdentity();
m_constraint = new btFixedConstraint(*m_aBody, *m_bBody, frameInA, frameInB);
printf("Weld::create: welded\n");
} }
void Weld::destroy() void Weld::destroy()

View File

@ -53,6 +53,14 @@ namespace RNR
Camera* start_cam = new Camera(); Camera* start_cam = new Camera();
start_cam->setParent(m_workspace); start_cam->setParent(m_workspace);
m_workspace->setCurrentCamera(start_cam); m_workspace->setCurrentCamera(start_cam);
PartInstance* baseplate = new PartInstance();
baseplate->setName("Baseplate");
baseplate->getCFrame().setPosition(Ogre::Vector3(0, -64, 0));
baseplate->setSize(Ogre::Vector3(512, 1, 512));
baseplate->setBrickColor(2);
baseplate->setAnchored(true);
baseplate->setParent(m_workspace);
} }
World::~World() World::~World()
@ -166,7 +174,9 @@ namespace RNR
if(m_runService && m_runService->getRunning() && !m_runService->getPaused()) if(m_runService && m_runService->getRunning() && !m_runService->getPaused())
{ {
m_runService->step(timestep); m_runService->step(timestep);
m_dynamicsWorld->stepSimulation(timestep, 1); dynamicWorldLock.lock();
m_dynamicsWorld->stepSimulation(std::max(timestep, 0.000001f), 1);
dynamicWorldLock.unlock();
m_ngine->updateTree(); m_ngine->updateTree();
} }
return 0.0; return 0.0;

View File

@ -49,6 +49,7 @@ namespace RNR
torso->getCFrame().setPosition(Ogre::Vector3(0, 0, 0)); torso->getCFrame().setPosition(Ogre::Vector3(0, 0, 0));
torso->updateMatrix(); torso->updateMatrix();
torso->setParent(m_character); torso->setParent(m_character);
torso->setAnchored(true);
Humanoid* character_humanoid = new Humanoid(); Humanoid* character_humanoid = new Humanoid();
character_humanoid->setParent(m_character); character_humanoid->setParent(m_character);