Page 1 of 1

Manual collision response for kinematic objects

Posted: Wed May 12, 2021 12:58 pm
by Karoon2
Hey guys, I just started using bullet (BulletSharp for C#) and I really like it! The automatic collisions response is awesome. But now, I want to add some custom character behaviour and need your help:

I have a kinematic character object (box shape) that gets created with the following settings:

Code: Select all

// ...
_rigidBody.ActivationState = ActivationState.ActiveTag | ActivationState.DisableDeactivation;
_rigidBody.CollisionFlags = CollisionFlags.CharacterObject | CollisionFlags.KinematicObject;

// create ghost object for it:
_ghostObject = new GhostObject();
_ghostObject.CollisionShape = _rigidBody.CollisionShape;
_ghostObject.WorldTransform = _rigidBody.WorldTransform;
I then add both the _rigidBody and the _ghostObject to my current world.

I move my object around with this method:

Code: Select all

public void MoveKinematic(float x, float y, float z)
	BulletSharp.Math.Matrix newTransform = _rigidBody.MotionState.WorldTransform;
	newTransform.Origin += new BulletSharp.Math.Vector3(x, y, z);
	_rigidBody.MotionState.WorldTransform = newTransform;

	// update the ghost's position as well:
	if (HasGhostObject)
		_ghostObject.WorldTransform = newTransform;
My problem now is this:
I use the ghost object to detect collisions with other objects:

Code: Select all

// the ghost always collides with the kinematic object
//(since they share the same shape and world transform).
// thus, count must be > 1 whenever the ghost collides with an object other than the player object:
if (_ghostObject.OverlappingPairs.Count > 1)
	AlignedCollisionObjectArray collisions = GetGhostObject().OverlappingPairs;
	foreach(CollisionObject b in collisions)
		// TODO: Undo the collision by moving the player object back by a bit
This kind of works but my kinematic object does not stop when it hits a different object. It kind of moves slightly into it (before the colliding object responds to my kinematic player object).
What I would like my kinematic player object to behave like is:
  • Check for collisions (ok, works)
  • Check by how much it is "inside" another object (minimum translation vector in order to undo the collision)
  • Move itself out of the colliding object
Is that possible and is my approach even viable? Any help would be hugely appreciated! Thanks in advance!

Re: Manual collision response for kinematic objects

Posted: Thu May 13, 2021 3:48 am
by drleviathan
The way to do this is to "sweep" the kinematic object from oldTransform to newTransform and to stop at first hit, else teleport to newTransform. This is how the btKinematicCharacterController works, as I recall, although it does a series of sweeps each frame so that it can walk up and down slopes and small steps. Perhaps you could fork btKinematicCharacterController to make MyKinematicCharacterController and then tweak its behavior to suit your needs.

Re: Manual collision response for kinematic objects

Posted: Fri May 14, 2021 5:14 pm
by Karoon2
Thank you very much for your quick reply! I will try that class. I thought using this controller was discouraged (at least I read something like that in several threads).
Maybe this will do. Thanks again!

Re: Manual collision response for kinematic objects

Posted: Sat May 15, 2021 3:41 pm
by drleviathan
Yeah... as I recall the btKinematicCharacterController has some bugs or shortcomings, but maybe it will work for your case and if not it could provide a good starting point or example. In particular it demonstrates how to sweep forward to find first touch.

Some things to worry about, depending on the game content: can the controller get "stuck" in a tight spot (e.g. when floor and roof squeeze together)? Does it "fall" correctly when walking off an edge? etc.