Kinematic object?

SteveDeFacto
Posts: 31
Joined: Sat Jul 23, 2011 4:24 pm

Kinematic object?

Post by SteveDeFacto »

I created a Kinematic object with these set:

Code: Select all

body->setCollisionFlags( cmesh->actor->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
body->setActivationState( DISABLE_DEACTIVATION );
And I move it like this:

Code: Select all

btTransform newTrans;
body->getMotionState()->getWorldTransform(newTrans);
newTrans.getOrigin() += (btVector3(0, -0.01f, 0));
body->getMotionState()->setWorldTransform(newTrans);
I expected it to stop when it hit the ground or an object but it continues to fall. How can I make it stop falling when it hits something?
User avatar
dphil
Posts: 237
Joined: Tue Jun 29, 2010 10:27 pm

Re: Kinematic object?

Post by dphil »

I'm not positive, but I think operating on the motion state directly is discouraged. And actually the motion state's transform setter is called by Bullet (and should not be called by you) to update your own data (graphics, for example), so depending on how you implemented it, it likely isn't updating any Bullet internals, hence no recognition of the rigid body actually moving. Instead, change the object's position via:

Code: Select all

btTransform newTrans = body->getWorldTransform();
newTrans.getOrigin() += (btVector3(0, -0.01f, 0));
body->setWorldTransform(newTrans);
And see if that works. See http://bulletphysics.org/mediawiki-1.5. ... tionStates for more details on motion states.
SteveDeFacto
Posts: 31
Joined: Sat Jul 23, 2011 4:24 pm

Re: Kinematic object?

Post by SteveDeFacto »

dphil wrote:I'm not positive, but I think operating on the motion state directly is discouraged. And actually the motion state's transform setter is called by Bullet (and should not be called by you) to update your own data (graphics, for example), so depending on how you implemented it, it likely isn't updating any Bullet internals, hence no recognition of the rigid body actually moving. Instead, change the object's position via:

Code: Select all

btTransform newTrans = body->getWorldTransform();
newTrans.getOrigin() += (btVector3(0, -0.01f, 0));
body->setWorldTransform(newTrans);
And see if that works. See http://bulletphysics.org/mediawiki-1.5. ... tionStates for more details on motion states.
I originally did that but when I do it like that the kinematic object does not move at all.
Flix
Posts: 456
Joined: Tue Dec 25, 2007 1:06 pm

Re: Kinematic object?

Post by Flix »

No, actually it should be correct to use the motion state to move kinematic objects.

The issue is probably that kinematic objects can't collide with other kinematic or static objects, they collide with dynamic objects only.

Thus kinematic objects are supposed to be moved in an "absolute" way (I mean: like standalone bodies in the vacuum).

You may consider using dynamic objects moved by some kind of contraint/motor (or manually by setting impulses/forces or velocities to them) if you want them to collide with static or kinematic objects.

An exception to this rule is using a btGhostObject and resolving collisions manually (that is what the charachter controller is supposed to do: it extends the btPairCachingGhostObject class and has a method for resolving the collisions manually; this way it can collide with both static and dynamic objects). I'm not very familiar with it so I can't give you further info about it.
User avatar
dphil
Posts: 237
Joined: Tue Jun 29, 2010 10:27 pm

Re: Kinematic object?

Post by dphil »

I guess it's only dynamic bodies that the directly manipulating the motion state transforms is discouraged for then(?). I haven't used kinematic bodies; I just assumed it was the same. But looking more into it it seems using the motion state is indeed correct for them. Good to know.
SteveDeFacto
Posts: 31
Joined: Sat Jul 23, 2011 4:24 pm

Re: Kinematic object?

Post by SteveDeFacto »

Flix wrote:No, actually it should be correct to use the motion state to move kinematic objects.

The issue is probably that kinematic objects can't collide with other kinematic or static objects, they collide with dynamic objects only.

Thus kinematic objects are supposed to be moved in an "absolute" way (I mean: like standalone bodies in the vacuum).

You may consider using dynamic objects moved by some kind of contraint/motor (or manually by setting impulses/forces or velocities to them) if you want them to collide with static or kinematic objects.

An exception to this rule is using a btGhostObject and resolving collisions manually (that is what the charachter controller is supposed to do: it extends the btPairCachingGhostObject class and has a method for resolving the collisions manually; this way it can collide with both static and dynamic objects). I'm not very familiar with it so I can't give you further info about it.
I don't think this is completely right. I think the Kinematic object can effect dynamic objects but it is not effected by them. It will fall through a dynamic object just like a static one and this is the same for a ghost object. I think the only way to use a kinematic object as a controller would be to manually control it's collision response. I've given up on them and instead moved to a rigid body with a constraint to control it's position. This is working very well as a character controller! The only problem I'm having is that m_normalWorldOnB does not return the right results all of the time which allows me to sort of walk up slopes which I should not be able to do...
MaxDZ8
Posts: 149
Joined: Fri Jun 24, 2011 8:53 am

Re: Kinematic object?

Post by MaxDZ8 »

For what it counts, the bullet manual reads:
  • there will be only one-way interaction: dynamic objects will be pushed away but there is no influence from dynamics objects.
The degree of interaction with dynamic objects is, in my opinion, a bit lazy. I suppose bullet is assuming the objects "stay still" and warp around rather than move. It seems to me the impulse transmitted to touched object is way less intense than it should. But perhaps Bullet is not the right place to take care of this.
The only problem I'm having is that m_normalWorldOnB does not return the right results all of the time which allows me to sort of walk up slopes which I should not be able to do...
This worries me. Perhaps this returns the normal suggested by bullet to resolve compenetration instead? Do you mind to elaborate a bit in case you have got more info?

Since I am also trying to figure out a way to move kinematic objects (this time I will do it right!) I think it might be a good idea to write my current line of thinking there.

Context: a platformer (in the late 80s it would have been isometric).
Goal: move a collision object according to player input.
Features: must absolutely support walking up slopes. Must also be able to step up stairs.
In the future: jump and inertial frames.
Key concept: "movement intent". When the player hits "left" he has a rough expectation of what it will happen. The idea is to express this as a vector and "consume" as much of this vector as possible.

I was thinking about querying contact points for first, then select one of those to be used as a reference.
Then I was thinking about rotating (in terms of "pitch" only) the "intention vector" so it always slides on the touched volume (assumed planar), but if the normals are not the ones I expect then I'm screwed.
Then I would sweep a GhostObject and get all the intersections which are coming from different volumes from the ones intended by the above volumes (but I'm not sure of the details here, I need to look at the contact point info, perhaps preventive generation will make this more involved).
I will move the player mesh and volume to the closest intersection passing the above test.

Then, if there's still movement available, I would try to sweep up the GhostObject again and proceed similarly to figure out if I am trying to "step up".

This is mostly copied in concept from btKinematicCharacterController. I'm not sure I need to "push down" the object after the movement however, I would just leave it to gravity in the next tick.

Suggestions are welcome.