Handling Ammo Kinematic Character Controller

Yo @JohnK and @trevordev … I need your help with handling the ammo.js kinematic character controller.

I got it to create but when i call setWalkDirection or jump nothing happens…

Am i supposed to some how tick some kind of character controller update function

Or

Am i supposed to on every frame, somehow get the position of the Ghost Object which should be the guy getting moved around in the physics world. So am i supposed to be manually updating the physical babylon mesh representation of that game object… or What ???

Can one you guys please Help Me :slight_smile:

FYI… Here what i got going so far:

const worldMin:any = Ammo.btVector3(-1000,-1000,-1000);
const worldMax:any = Ammo.btVector3(1000,1000,1000);
this.m_overlappingPairCache = new Ammo.btAxisSweep3(worldMin, worldMax);

const collisionShape:any = this._abstractMesh.physicsImpostor.physicsBody.getCollisionShape();
const startTransform:any = new Ammo.btTransform();
startTransform.setIdentity();
startTransform.setOrigin(new Ammo.btVector3(0.0, 0.0, 0.0));

this.m_ghostObject = new Ammo.btPairCachingGhostObject();
this.m_ghostObject.setWorldTransform(startTransform);
this.m_overlappingPairCache.getOverlappingPairCache().setInternalGhostPairCallback(new Ammo.btGhostPairCallback());

this.m_ghostObject.setCollisionShape(collisionShape);
this.m_ghostObject.setCollisionFlags(BABYLON.CollisionFlags.CF_CHARACTER_OBJECT);

const stepHeight:number = 0.35;
this.m_character = new Ammo.btKinematicCharacterController(this.m_ghostObject, collisionShape, stepHeight);

// NOTE: DOES NOTHING
this.m_character.setWalkDirection(new Ammo.btVector3(0,0,10));

Sorry but reading your posts about Ammo.js you have surpassed my knowledge. All I did was was a re-working of some three.js code. Hopefully trevordev can help.

Do you have a playground/fiddle setup (Like this one https://jsfiddle.net/t0xwbgLa/)? Are you already calling world.stepSimulation(1/60, 10); to move other things? Yea the physics world and babylon world are separate so when rendering you need to copy pos/rot of objects in the physics world

I figured it out… to update the Babylon object position from a ghost pair cache object… I register after step function on impostor and set the motion state world transform from ghost object get world transform… now works

Problem is … I did all that and finally got kinematic character controller to work to find out it kinda sucks compared to a good dynamic character controller

Plus if you put more than 1 btKinematicCharacterController in scene… it just kills the frame rate.

But implementing a good dynamic character controller performs way better… so I am going with a dynamic character controller instead

1 Like

Yo @trevordev … Bro… I can be such a DUMBASS sometimes…

It turns out the whole time i was still setting a Babylon Physics Impostor on when try to create a Kinematic Character Controller… That is why was so slow and could not put more than one chracter controller in the scene… The Ghost Objects and Kinematic Character Controller that get manually added to the physics world was fighting with the original Babylon physics imposter (btRigidBody)

I fixed that and it runs kinda sweet … Using Native Bullet Ghost Objects Is The SHIZZ NIT

Especially for collision detection… has is own overlapping pair cache you can iterate all its contact points…

According To Bullet Guys:
The best way to determine if collisions happened between existing objects in the world, is to iterate over all contact manifolds. This should be done during a simulation tick (substep) callback, because contacts might be added and removed during several substeps of a single stepSimulation call.

Check Out Ghost Object Collision in this link

Anyways… Back to the Kinematic Character Controller… Which is supposed to use much less resouces NOT using rigidbodies nd it has its own bullet kinematic gravity and is grounded detection … I am in love with the native Ammo Physics API…

Cant wait to try out the Vehicle Physics Stuff :slight_smile:

3 Likes

@MackeyK24 do have any info regarding how the btKinematicCharacterController class is meant to be used? I have an issue atm where my characters physics collision mesh (a cylinder) is affected by gravity (which I want), but always falls over on its side whenever the ground is uneven. This in turn causes the visual mesh of the game character to fall over as well. My first thought was to try to limit rotation to only the y-axis via:

physicsImpostor.executeNativeFunction((_, physicsBody) => {
    physicsBody.setAngularFactor(new this._game.Ammo.btVector3(0, 1, 0))
})

// OR

physicsBody.setAngularFactor(new this._game.Ammo.btVector3(0, 0, 0))

But neither of these approaches works, and I’m guessing it has to do with the ammo impostor being of either the kinematic or dynamic type of rigid body. I’m hoping that perhaps this third class of rigid body, the btKinematicCharacterController class can perhaps allow me the solution that I want: constrained axis angular rotation, but still be affected by gravity. Do you know if I can achieve this?

Dunno About this._game.Ammo.btVector3 you have…

FYI… this is how i constrain rigidbody physics nodes

                        if (body.setLinearFactor) {
                            const freeze_pos_x:number = (freeze.positionx != null && freeze.positionx === true) ? 0 : 1;
                            const freeze_pos_y:number = (freeze.positiony != null && freeze.positiony === true) ? 0 : 1;
                            const freeze_pos_z:number = (freeze.positionz != null && freeze.positionz === true) ? 0 : 1;
                            if (BABYLON.RigidbodyPhysics.TempAmmoVector == null) BABYLON.RigidbodyPhysics.TempAmmoVector = new Ammo.btVector3(0, 0, 0);
                            BABYLON.RigidbodyPhysics.TempAmmoVector.setValue(freeze_pos_x, freeze_pos_y, freeze_pos_z);
                            body.setLinearFactor(BABYLON.RigidbodyPhysics.TempAmmoVector);
                        } else {
                            BABYLON.Tools.Warn("Physics engine set linear factor not supported for: " + entity.name);
                        }
                        if (body.setAngularFactor) {
                            const freeze_rot_x:number = (freeze.rotationx != null && freeze.rotationx === true) ? 0 : 1;
                            const freeze_rot_y:number = (freeze.rotationy != null && freeze.rotationy === true) ? 0 : 1;
                            const freeze_rot_z:number = (freeze.rotationz != null && freeze.rotationz === true) ? 0 : 1;
                            if (BABYLON.RigidbodyPhysics.TempAmmoVector == null) BABYLON.RigidbodyPhysics.TempAmmoVector = new Ammo.btVector3(0, 0, 0);
                            BABYLON.RigidbodyPhysics.TempAmmoVector.setValue(freeze_rot_x, freeze_rot_y, freeze_rot_z);
                            body.setAngularFactor(BABYLON.RigidbodyPhysics.TempAmmoVector);
                        } else {
                            BABYLON.Tools.Warn("Physics engine set angular factor not supported for: " + entity.name);
                        }

You can ignore it or think of it as just a normal Ammo.btVector3, it’s just the way I pass around the reference to Ammo after it’s been initialized in my code atm.

Does that actually work for you? Using the setAngularFactor method has no effect for me. I’ll have to do some digging

Yep, works great when I use regular rigid body physics on like a capsule that I don’t want to topple over…I freeze the X and Z and just allow rotate around the Y axis