Despite using the ammo.js library quite a bit in my project I still don’t know what these methods do: Ammo.wrapPointer, Ammo.getPointer , ammoObject.getUserPointer and ammoObject.getUserIndex
I sort of see how Ammo.getPointer works in conjunction with Ammo.wrapPointer:
I was also wondering if there was any identifying information I can stick on a particular ammo class instance if I wanted to be able to identify it later such as during an onHit callback.
Update: I did find this medium article:
Ammo.js on the other hand, deriving from its parent project bullet, also has a way to add the reference of a user object to a physics object. That mean we can also have our physics objects bear reference to their corresponding three.js object. This is achieved using the setUserPointer() and getUserPointer() methods of btCollisionObject ( parent class of btRigidBody ). With this we are able to retrieve our three.js objects if we have the physics objects at hand.
@MackeyK24 On aside, do you know how to detect collisions between a kinematic character controller and a rigid body? The normal methods don’t seem to be doing for me via:
export const setupContactPairResultCallback = (Ammo) => {
const cbContactPairResult = new Ammo.ConcreteContactResultCallback()
//@ts-ignore
cbContactPairResult.hasContact = false
/*
for each contact point search:
cbContactPairResult = callback object (results) for contactPairTest
addSingleResult = method to search for colission between the 2 defined objects
cp = contact point
colObjWrap, colObj1Wrap = wrappers to retrieve participating object in collision
*/
cbContactPairResult.addSingleResult = function(cp, colObj0Wrap, partId0, index0, colObj1Wrap, partId1, index1) {
//@ts-ignore
const contactPoint = Ammo.wrapPointer(cp, ammoInstance.btManifoldPoint)
const distance = contactPoint.getDistance()
console.log("here, distance: ", distance)
if (distance > 0) return 0; /* theres no contact */
//@ts-ignore
cbContactPairResult.hasContact = true
return 1
}
return cbContactPairResult
}
const cb = setupContactPairResultCallback()
const testBody = new Ammo.btRigidBody() /* assume it's scaled and positioned correctly */
physicsWorld.contactPairTest(testBody , player.controller.getGhostObject(), cb) // nothing happens
What does your btKinematicCharacterController setup look like… Make sure your ghost and character are setup right
this.m_ghostObject = new Ammo.btPairCachingGhostObject();
this.m_ghostObject.setWorldTransform(this.m_startTransform);
this.m_ghostObject.setCollisionShape(this.m_ghostShape);
this.m_ghostObject.setCollisionFlags(BABYLON.CollisionFlags.CF_CHARACTER_OBJECT);
this.m_ghostObject.setActivationState(4)
this.m_ghostObject.activate(true);
// Create kinematic character controller
this.m_character = new Ammo.btKinematicCharacterController(this.m_ghostObject, this.m_ghostShape, this._stepOffset);
this.m_character.setUseGhostSweepTest(true);
this.m_character.setUpInterpolate(true);
this.m_character.setGravity(BABYLON.System.Gravity3G);
this.m_character.setMaxSlope(BABYLON.Tools.ToRadians(this._slopeLimit + 1));
// Add ghost object and character to world
world.addCollisionObject(this.m_ghostObject, BABYLON.CollisionFilters.CharacterFilter, BABYLON.CollisionFilters.AllFilter);
world.addAction(this.m_character);
I dont use the addSingleResult callback method… I poll for character controller collisions using m_ghostObject.getNumOverlappingObjects and m_ghostObject.getOverlappingObject in my update loop of my character controller class.
let contacts:number = this.m_ghostObject.getNumOverlappingObjects();
if (contacts > this._maxCollisions) contacts = this._maxCollisions;
if (contacts > 0) {
for (let index = 0; index < contacts; index++) {
const contactObject:any = this.m_ghostObject.getOverlappingObject(index);
if (contactObject != null) {
const contactBody:any = Ammo.castObject(contactObject, Ammo.btCollisionObject);
if (contactBody != null && contactBody.entity != null && contactBody.isActive()) {
// Is In Contact With Entity Object
}
}
}
}