Best practice for collision between characterControls

Is there a best practice for implementing collisions between two character control objects.



My objective is for a character control that can clash with other characters and be affected by external forces but I am going round in circles about the best way to implement this. Has anyone done this and is there an accepted best practice?

You could attach a rigidbodycontrol in kinematic mode to the characters.

I tried this and they still seem to be passing through each other. I am using this code:

[java]

//add the items to our server

Box b = new Box(Vector3f.ZERO, 1f, 1f, 1f);

final Geometry geom = new Geometry(String.valueOf(client.getPlayerID()), b);

geom.updateModelBound();



// Create a appropriate physical shape for it

CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(2f, 2f, 1);

final CharacterControl cc = new CharacterControl(capsuleShape, 0.1f);

cc.setFallSpeed(0);

cc.setGravity(0);

geom.addControl(new PlayerControl(cc));

geom.addControl(cc);



final RigidBodyControl rbc = new RigidBodyControl(10f);

geom.addControl(rbc);



Future fut = enqueue(new Callable() {

public List<String> call() throws Exception {

List<String> ss = new ArrayList<String>();

rootNode.attachChild(geom);

bulletAppState.getPhysicsSpace().add(cc);

bulletAppState.getPhysicsSpace().add(rbc);



for (Spatial s : rootNode.getChildren()) {

ss.add(s.getName());

}

return ss;

}

});

[/java]



Player control is a user defined control. BTW thank you for showing us that MonkeyZone code, it helped fantastically in helping strucutre my code and the use of controls.



Matt

After re-reading the java docs I think I also need to set setKinematic to true? Does this mean my object will not be affected by other forces, or am I misinterpreting the javadoc? Ideally I want my character to be user controlled by influence, and be influenced, by the physics going on around it.



Matt

Yeah, then it will move along with the spatial which in turn is moved by the character control so that other characters can bounce into it, but theres a problem I didnt think about… The Character will collide with the RigidBody, probably resulting in strange movement of the character. You could try and remedy that by using CollisionGroups or a CollisionGroupListener.

I’m trying to accomplish the same thing. I added this code to each CharacterControl, but it doesn’t seem to have any impact (ha, ha):



[java]RigidBodyControl rigidBody = new RigidBodyControl(1);

model.addControl(rigidBody);

rigidBody.setKinematic(true);[/java]

I think that down the line I will need to handle the logic myself anyway so I will probably just implement a collision listener and handle the character to character collisions myself. I doubt that I actually want proper physics in this case anyway so I will probably need to do this anyway.

You can use GhostControls to check for overlapping objects, that should work better than RigidBodys.

Thanks for you help. Just for completeness:



I added a ghost control and made sure only collisions between the ghosts are considered:



//add a ghost control for the collision between player characters

final GhostControl gc = new GhostControl(capsuleShape);

//dont want these colliding with anything other than each other to save efficiency

gc.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_02);

gc.removeCollideWithGroup(PhysicsCollisionObject.COLLISION_GROUP_01);

gc.addCollideWithGroup(PhysicsCollisionObject.COLLISION_GROUP_02);



If you don’t do the above you will be processing a lot of collisions between the character and the ghost, which is not efficient.



I then implemented a collision listner and handle the collisions that happen.

1 Like

I’m bumping this thread because I’d prefer to use the physics to handle collisions if possible. Of course if I set up a normal RigidBody:



[java]

Geometry brick = new Geometry(“brick”, new Box(Vector3f.ZERO, 1, 1, 1));

brick.setMaterial(monkey);

stage.getRootNode().attachChild(brick);

brick.setLocalTranslation(new Vector3f(5, 2, 0));

RigidBodyControl rigidBody = new RigidBodyControl(1);

brick.addControl(rigidBody);

stage.bulletAppState.getPhysicsSpace().add(brick);

// rigidBody.setKinematic(true);

[/java]



the CharacterControl collides with it but if I set it to kinematic and setLocalTranslation() to the CharacterControl (obviously the wrong implementation) it collides with the CharacterControl and flips out.



So if it’s not possible to use a RigidBody on the CharacterControl (which seems odd because it collides with everything else naturally) is it plausible to use a regular RigidBody like the one above and use applyForce() to move it? If so, how does one set the rotation of the improvised character upright while it’s controlled by physics? The CharacterControl.java has this:



[java]spatial.setLocalRotation(localRotationQuat);[/java]

You’d use a kinematic physics node, which is what the CharacterControl does. But if you go that way you will have to solve many more problems than with the solution @mattm suggests.

Just a quick note to say that the WalkDirection on the character controller is not actually a walk direction at all and is more a distance to move per time step. This means that you can do rudementary movement of the character automatically quite easily (such as exploding the character upwards or backwards from the collision). The underlying bullet physics object, KinematicCharacterController, actually has an apply force for duration method. This does the same thing as setting the walk direction for a set amount of time. It sets the walk direction to zero when you call it but only when you call it (not for the rest of the time it is applied for), I find it easier to do it manually using walk direction. You can get to this object via a method on the character controller, which for the minute eludes me (I dont have the code on this machine)!



Matt

What you say is correct, the walkDirection is dependent on physics framerate but you should not use the bullet object directly, the method you are talking about will only return a long number when physics is moved to native bullet.

Sorry for bumping this, but I was also wondering how CharacterControl handles collisions. Is it possible to recreate something similar to the now-deprecated PhysicsCharacterNode? My application depends heavily on collisions between character nodes.



Thanks in advance

No, its an issue that would happen with the PhysicsCharacterNode now as well.

My workaround for this issue was to use a CharacterControl for the player and RigidBodies with infinite angular damping and ApplyForce for everything else. It works because you can’t really tell the difference with AI, although it could be better.

1 Like
kidneytrader said:
My workaround for this issue was to use a CharacterControl for the player and RigidBodies with infinite angular damping and ApplyForce for everything else. It works because you can't really tell the difference with AI, although it could be better.

Oh, thats a good idea..

You could also setAngularFactor to 0f, i think this wil improve performance

nego said:
You could also setAngularFactor to 0f, i think this wil improve performance

Heh, you're right, somehow I had that in mind, I added it by request some time ago, didn't even know that method before. I think it should be in alpha-3 too.

Kinematic mode is what you are describing.