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

View File

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

View File

@ -20,6 +20,9 @@ namespace RNR
World* m_world;
std::map<PartInstance*, btRigidBody*> m_physicsParts;
int m_sleepingObjects;
int m_activeObjects;
void thread();
public:
ComPlicitNgine(World* world);
@ -35,6 +38,10 @@ namespace RNR
btRigidBody* getBody(PartInstance* part) { return m_physicsParts[part]; };
void registerPhysicsPart(PartInstance* partRegistered);
void updatePhysicsPart(PartInstance* partUpdate);
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; }
bool getPhysicsShouldBeRunningPleaseStopIfItIsStillRunning() { return m_runPhysics; }
Lock physicsIterateLock;
Lock dynamicWorldLock;
};
}

View File

@ -125,6 +125,7 @@ namespace RNR
{
Workspace* workspace = m_world->getWorkspace();
btDiscreteDynamicsWorld* dynamicsWorld = m_world->getDynamicsWorld();
ComPlicitNgine* ngine = m_world->getComPlicitNgine();
char debugtext[512];
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());
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(),
render_debugtext,
m_world->getLastPhysicsDelta(),
dynamicsWorld->getNumCollisionObjects(), dynamicsWorld->getNumConstraints(),
dynamicsWorld->getNumCollisionObjects(), ngine->getActiveObjects(), ngine->getSleepingObjects(), dynamicsWorld->getNumConstraints(),
m_world->getRunService()->getRunning() ? "true" : "false",
m_world->getRunService()->getPaused() ? "true" : "false");
m_debugText->setCaption(debugtext);

View File

@ -2,6 +2,9 @@
#include <App/V8/World/World.hpp>
#include <App/V8/World/Weld.hpp>
#include <App/InputManager.hpp>
#include "btBulletCollisionCommon.h"
#include "BulletCollision/CollisionDispatch/btGhostObject.h"
#include <Helpers/Bullet.hpp>
namespace RNR
{
@ -11,6 +14,15 @@ namespace RNR
m_maxHealth = 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()
@ -32,6 +44,18 @@ namespace RNR
headWeld->create();
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()
@ -120,9 +144,11 @@ namespace RNR
if(inputManager->isKeyDown('W'))
forward = 16;
Ogre::Vector3 move = Ogre::Vector3(0, 0, -forward);
Ogre::Vector3 move = Ogre::Vector3(0, 0, forward);
move = direction * move;
move *= world->getLastDelta();
move *= world->getComPlicitNgine()->getLastPhysicsDelta();
m_characterController->playerStep(world->getDynamicsWorld(), forward);
bool move_valid = true;
@ -136,13 +162,14 @@ namespace RNR
PartInstance* bp = dynamic_cast<PartInstance*>(child);
if(bp)
{
Ogre::Vector3 bp_p = bp->getPosition();
bp_p += move;
bp->getCFrame().setPosition(bp_p);
Ogre::Vector3 bp_p = bp->getRelativePosition(getTorso());
bp->getCFrame().setPosition(bp_p + Bullet::v3ToOgre(m_characterController->getGhostObject()->getWorldTransform().getOrigin()));
Ogre::Matrix3 new_rotation_matrix;
new_direction.ToRotationMatrix(new_rotation_matrix);
bp->getCFrame().setRotation(new_rotation_matrix);
bp->updateMatrix();
world->getComPlicitNgine()->updatePhysicsPart(bp);
world->getWorkspace()->setDirty();
}
}

View File

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

View File

@ -25,9 +25,17 @@ namespace RNR
void Weld::create()
{
if(!m_aBody || !m_bBody)
{
printf("Weld::create: invalid body\n");
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()

View File

@ -53,6 +53,14 @@ namespace RNR
Camera* start_cam = new Camera();
start_cam->setParent(m_workspace);
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()
@ -166,7 +174,9 @@ namespace RNR
if(m_runService && m_runService->getRunning() && !m_runService->getPaused())
{
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();
}
return 0.0;

View File

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