Simple player repulsion, level collision and raytrace shoot.

User avatar
Narann
Posts: 7
Joined: Sun Feb 02, 2014 5:57 pm

Simple player repulsion, level collision and raytrace shoot.

Post by Narann »

Hi Bullet community,

I'm working on a game on my spare time. I have few things working but now it's time for player/player, player/level, ray shoot/player intersection and repulsion. So nothing highly "physical dynamics" actually.

I've choosed Bullet because it seems to deal with all of that (specially with capsule shapes for players) without all the highly dynamic stuff (using btCollisionWorld, btCollisionObject).

So I have:
- Players represented by btCollisionObject with a btCapsuleShape.
- A level (actually a simple static collision geometry).
- Players shoot using a simple ray (no physical balistics).

But now I'm a little lost. The documentation is not very big and even if I've looked at thoose many demos and tutorials, I'm not confident if I'm using Bullet in the good way (if there is one).

For now, I'm only on Player/Player repulsion.

I've used the btCollisionWorld->contactTest() with an overrided ContactResultCallback but I think it's a little tricky:

The struct:

Code: Select all

struct PlayerContactResultCallback : public btCollisionWorld::ContactResultCallback {

    PlayerContactResultCallback( btCollisionObject &player_collision_obj )
    : btCollisionWorld::ContactResultCallback(),
        m_player_collision_obj( player_collision_obj ) ,
        hit( false ) ,
        distance( 0.0 ) {
    }
    btCollisionObject& m_player_collision_obj;
    bool hit;
    float distance;

    virtual btScalar addSingleResult( btManifoldPoint& cp,
                            const btCollisionObjectWrapper* colObj0, int partId0, int index0,
                            const btCollisionObjectWrapper* colObj1, int partId1, int index1)
    {
        if( colObj0->m_collisionObject == &m_player_collision_obj)  {
            hit = true;
            distance = (float) cp.getDistance();
            std::printf( "collide dist: %f\n", distance);
        }
    return 0; // Return what actually?
    }
};
And in my gameworld->update()

Code: Select all

// move the capsule collider to the player position
btTransform world_transform = btTransform();
btVector3 pos = btVector3();
pos.setX( myPlayer->position().X );
pos.setY( myPlayer->position().Y );
pos.setZ( myPlayer->position().Z );
world_transform.setOrigin( pos );
m_player_collider_objects[ i ]->setWorldTransform( world_transform );

// set the player velocity to the capsule to anticipate collision
btVector3 btVelocity = btVector3();
btVelocity.setX( player_velocity.X );
btVelocity.setY( player_velocity.Y );
btVelocity.setZ( player_velocity.Z );
m_player_collider_objects[ i ]->setInterpolationLinearVelocity( btVelocity );

PlayerContactResultCallback resultCallback = PlayerContactResultCallback( *m_player_collider_objects[ i ] );

m_bt_collision_world->contactTest( m_player_collider_objects[ i ] , resultCallback);
if( resultCallback.hit ) {
    float repulsion = (float) resultCallback.distance;
    player_velocity.setLength( player_velocity.getLength() - repulsion );
}
Of course, it's doesn't "work" as I except (player doesn't repulse, they just shake). The "collide dist" message work so the collision "is recognized" but I'm sure I'm wrong in the way I'm doing this.

I'm sure I'm doing thinks bad.

If you had to deal my three simple repulsion (player/player, player/level, ray shoot/(player and level)) what are the firsts classes and methods you are thinking about?

How would you do that?

A big thanks in advance to you guys! :)
xexuxjy
Posts: 225
Joined: Wed Jan 07, 2009 11:43 am
Location: London

Re: Simple player repulsion, level collision and raytrace sh

Post by xexuxjy »

How are you setting up the rigidBodies for your players? From the code it looks like you're trying to 'override' the results of the physics by forcing your own values back over the calculated ones. You probably should update your player position based on the capsules position rather than the other way round. Similar situation with velocity. One quick test would be to update your PlayerContactResultCallback to just apply an impulse force to one (or both) of the colliding objects to handle the separation.
User avatar
Narann
Posts: 7
Joined: Sun Feb 02, 2014 5:57 pm

Re: Simple player repulsion, level collision and raytrace sh

Post by Narann »

Thanks for the answer. I appreciate. :)
xexuxjy wrote:How are you setting up the rigidBodies for your players?
Arf! Of course this is the only thing I forgot to give, sorry. :(

I don't have the code now but I don't use RigidBody/Dynamics. From memory, code is like this:

Code: Select all

myBtCollisionObject->setShape( myBtCapsuleShape );
btCollisionWorld->addCollisionObject( myBtCollisionObject )
xexuxjy wrote:From the code it looks like you're trying to 'override' the results of the physics by forcing your own values back over the calculated ones.
Where am I doing this? There is no physics in my code (I use btCollisionWorld). What I'm "trying" to do is get the repulsion vector and apply it to the Player.

Am I wrong doing so? What would be the "good" way?
xexuxjy wrote:You probably should update your player position based on the capsules position rather than the other way round.
But as there is no dynamics, the capsule position is the one I setted. :(
xexuxjy wrote:One quick test would be to update your PlayerContactResultCallback to just apply an impulse force to one (or both) of the colliding objects to handle the separation.
Ow! And after I apply the capsule values to my players! This really seems "the good way". I will try that.

So the point would be to: "Do" the repulsion move inside the callback, then apply the capsule position values to your Player entity. Am I right? :)

Sorry for my noob question. Bullet seems very powerfull but it's hard to get the valid entry point when you needs are specifics. :)

Thanks in advance!
xexuxjy
Posts: 225
Joined: Wed Jan 07, 2009 11:43 am
Location: London

Re: Simple player repulsion, level collision and raytrace sh

Post by xexuxjy »

Ah ok, sorry didn't notice the bit about lack of dynamics. The above comment on an impulse force probably not that helpful then.
Looking again I'm not sure that just modifiying the length of the player velocity vector in yout callback vector will do what you want(in fact I'm a little surprised you can modify the length of the velocity vector directly like that)
Capturing the manifold point(s) and then reflecting/bouncing the players velocity / position based on the contact normal of the collision might be a better option, though it's going to lead to a very 'abrupt' stop/change to the players motion.
User avatar
Narann
Posts: 7
Joined: Sun Feb 02, 2014 5:57 pm

Re: Simple player repulsion, level collision and raytrace sh

Post by Narann »

xexuxjy wrote:Ah ok, sorry didn't notice the bit about lack of dynamics. The above comment on an impulse force probably not that helpful then.
No problem, thanks for taking time to help me. :)
xexuxjy wrote:Looking again I'm not sure that just modifiying the length of the player velocity vector in yout callback vector will do what you want(in fact I'm a little surprised you can modify the length of the velocity vector directly like that)
I don't modify the player velocity in the callback. The callback just get the "hit" and the "distance". I just get this in the main game loop and modify the player velocity accordingly. After many investigations I think it's bad. So I choose to "cut" my main loop in two part. First part I compute player vector velocity. Then I compute and apply the repulsion using this way, then I move the player.
xexuxjy wrote:Capturing the manifold point(s) and then reflecting/bouncing the players velocity / position based on the contact normal of the collision might be a better option, though it's going to lead to a very 'abrupt' stop/change to the players motion.
I think I will just apply a "repulsion vector" based on the contact distance. More players are inside each others more they repulse each other.

I guess I'm on the good way. Thanks a lot! :)