I am facing a challenge with implementing collision detection between a first-person camera character and a glTF model.
I think problem is const numManifolds = dispatcher.getNumManifolds(); numManifolds will return 0
Is there anything better than Ammo.js for physics? Can someone help me where is the problem in my code? My GLTF model consists of walls, floor and ceiling
Here is my codes (not all codes)
function initPhysicsUniverse() {
var collisionConfiguration = new Ammo.btDefaultCollisionConfiguration();
var dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration);
var broadphase = new Ammo.btDbvtBroadphase();
var solver = new Ammo.btSequentialImpulseConstraintSolver();
physicsWorld = new Ammo.btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
physicsWorld.setGravity(new Ammo.btVector3(0, -10, 0));
}
function initAmmoJsKinematicCharacterController() {
const radius = 1;
const height = 3;
let transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(1, 3, 1));
transform.setRotation(new Ammo.btQuaternion(1, 1, 1, 1));
let shape = new Ammo.btCapsuleShape(radius, height);
shape.setMargin(0.05);
bodyCapsuleShape = new Ammo.btPairCachingGhostObject();
bodyCapsuleShape.setWorldTransform(transform);
bodyCapsuleShape.setCollisionShape(shape);
bodyCapsuleShape.setCollisionFlags(flags.CF_CHARACTER_OBJECT);
bodyCapsuleShape.activate(true);
kinematicCharacterController = new Ammo.btKinematicCharacterController(bodyCapsuleShape, shape, 0.35, 1);
kinematicCharacterController.setUseGhostSweepTest(true);
kinematicCharacterController.setUpInterpolate();
kinematicCharacterController.setGravity(GRAVITY);
kinematicCharacterController.setMaxSlope(Math.PI / 3);
kinematicCharacterController.canJump(true);
kinematicCharacterController.setJumpSpeed(GRAVITY / 3);
kinematicCharacterController.setMaxJumpHeight(100);
let userData_ = new Ammo.btVector3(0, 0, 0);
const userData = { name: "player" };
userData_.userData = userData;
bodyCapsuleShape.setUserPointer(userData_);
tmpVec3_ = new Ammo.btVector3(0, 0, 0);
physicsWorld.addCollisionObject(bodyCapsuleShape);
physicsWorld.addAction(kinematicCharacterController);
physicsWorld.getBroadphase().getOverlappingPairCache().setInternalGhostPairCallback(new Ammo.btGhostPairCallback())
}
function addGltfToScene() {
scene_.add(gltfModel.scene);
gltfModel.scene.traverse(element => {
if (element.isMesh) {
createGltfRigidBodyAsBox(element, element.position, element.quaternion, element.scale);
}
})
}
function createGltfRigidBodyAsBox(model, position, quaternion, size) {
let transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(position.x, position.y, position.z));
transform.setRotation(new Ammo.btQuaternion(quaternion.x, quaternion.y, quaternion.z, quaternion.w));
let motionState = new Ammo.btDefaultMotionState(transform);
let btSize = new Ammo.btVector3(size.x, size.y, size.z);
let shape = new Ammo.btBoxShape(btSize);
shape.setMargin(0.05);
let inertia = new Ammo.btVector3(0, 0, 0);
shape.calculateLocalInertia(0, inertia);
let info = new Ammo.btRigidBodyConstructionInfo(10, motionState, shape, inertia);
let rigidBody = new Ammo.btRigidBody(info);
const userData = { name: model.name };
var userData_ = new Ammo.btVector3(0, 0, 0);
userData_.userData = userData;
rigidBody.setUserPointer(userData_);
rigidBody.setActivationState(4);
rigidBody.setCollisionFlags(2);
model.userData.physicsBody = rigidBody;
physicsWorld.addRigidBody(rigidBody);
/*Ammo.destroy(btSize);*/
}
function updatePhysicsUniverse(timeElapsedS) {
physicsWorld.stepSimulation(timeElapsedS, 10);
}