Collision between characterControls

Hi,



This post may seems to speak about the same problem as the previous post ( Physics interaction between CharacterControl and RigidBodyControl? )

but, since my problem is far less complex, I took the liberty of creating a new post :slight_smile:





With the last update of JME3, I had to discard my PhysicsCharacterNode and replace it by CharacterControls.



With the PhysicsCharacterNode, the characters were colliding with each other.

With the new CharacterControls, they don’t collide.



I don’t really need to know which part of CharacterControl is colliding, I just need the two characters to stop their movements when they collide.



For now my code is as follow :

[java]

private void loadPhysicsNode( Vector3f position, Vector3f direction )

{

//


//Calculate collision shape
//
BoundingBox box = ((BoundingBox)model.getWorldBound());
float xHalfExtent = box.getXExtent();
float yHalfExtent = box.getYExtent();
float zHalfExtent = box.getZExtent();
float radius = Math.max(xHalfExtent, zHalfExtent);
float height = yHalfExtent;
System.out.println( "Height : " + height );
CapsuleCollisionShape shape = new CapsuleCollisionShape( radius, height, 1);

//
//Create physics node
//
this.physicNode = new ForceCharacterControl(shape, 0.01f );
//this.physicNode = new CharacterControl(shape, 0.01f );
this.model.addControl( physicNode );
this.physicNode.setUpAxis(1);
this.physicNode.setGravity(10.0f);
this.physicNode.setFallSpeed(0.1f);
this.physicNode.setJumpSpeed(10);
this.physicNode.setMaxSlope( FastMath.PI / 2.0f );

//
// Place it at the correct position
//
physicNode.setPhysicsLocation( position );

faceDirection( direction.getX(), direction.getZ() );
}
[...]
// Add model
rootNode.attachChild( sceneChar.getSpatial() );

// Add control
CharacterControl control = sceneChar.getPhysicsControl();
physicsSpace.add( control );
[/java]

I tried to use a ForceCharacterControl instead of a CharacterControl. ( I havn't seen the difference )
It seems I will have to implement a collision listener to detect when there is a collision.

Can I have a small example of how to do that ? :)

Thanks in advance.

PS : I'm fairly new in implementing Physics.
Until now, I focused on the GUI part of my program.
So there may be something obvious for you guys that I didn't see.

PS2 :
Is my CharacterControl instanciation correct ? :)

Edit :
I just found this post : http://hub.jmonkeyengine.org/groups/physics/forum/topic/get-collision-of-charactercontrol/
Seems like its exactly what I am looking for... :D
I will try to use it,
This post has no more value then. I will close it after it try the solution given in the other post.

Just to be sure : Is the way I instanciate my CharacterControl correct ?

ForceCharacterControl only serves for converting some force, you manualy compute & apply, into movement. Other than that, its exactly behaving like CharacterControl.



Collision between CharacterControls does not work properly, its a bug the developers are currently working on.

There has been much discussion about this issue, in this post http://hub.jmonkeyengine.org/groups/physics/forum/topic/best-practice-for-collision-between-charactercontrols/#post-118474 mattm proposed a method for manually responding to collisions between character controls



BTW: i think its better to modify the transforms of the CharacterControl after you add it to the physicsspace. Other than that, the instantiation seems fine to me



hope that helps

A late thanks nego.

I helps me in some way : I delayed the resolution of this problem :slight_smile:





Just a little Bump in order to know if there will be ( or already is ) some default collsion management between Character Controls.

Or if I have to do something like mattm has done. :slight_smile:

There is none and there never will be.

Hi,

Thanks for the answer. ( Even if that wasn’t what I hoped xD )



Since I will have to implement the collision management between mycharacter control, I decided to stop using setWalkingDirection() and move my character manually on each frame.

But it seems I have some problems using setPhysicsLocation() :





I created a simple function in my SceneCharacter class :

[java]

public void setLocation( Vector3f position )

{

Vector3f realPosition = new Vector3f( position.getX(), position.getY() + 0.5f, position.getZ() );

physicNode.setPhysicsLocation( realPosition );

}

[/java]



I have a function that retrieve the give me the position on the ground for a given x and Z.

[java]

public static Vector3f getGroundPosition( Vector3f point )

{

ViewController controller = application.getMainViewController();

MainView view = controller.getMainView();



CollisionResults results = new CollisionResults();

Vector3f origin = new Vector3f( point.getX(), point.getY() + view.getMaxHeight(), point.getZ() );

Vector3f direction = new Vector3f( 0, -1, 0 );

Ray ray = new Ray( origin, direction );

view.getBattlegroundModel().collideWith( ray, results );

if( results.size() == 0 )

{

LogManager.warn( null, "Can’t retrieve ground position for point " + point );

return null;

}



CollisionResult collision = results.getClosestCollision();

return collision.getContactPoint();

}

[/java]



The problem occurs when I do something like that :

[java]

Vector3f position = …

position = ViewManager.getGroundPosition( position );

sceneChar.setLocation( position );

[/java]

Most of the time, it goes through the ground.

For patching my problem, I used

[java]

Vector3f realPosition = new Vector3f( position.getX(), position.getY() + 0.5f, position.getZ() );

[/java]

but this 0.5f is a value I found via different tests. But I don’t understand why we need to do something like that.



I think it has something to do with :

[java]CapsuleCollisionShape shape = new CapsuleCollisionShape( radius, height, 1);[/java]

But I don’t know how :stuck_out_tongue:



It may be something trivial for most of you, but it’s giving me a headhache…

It is dangerous to use the physics controls setting the location as you do, and the reason that this is dangerous is exactly what you have seen - you have to be careful not to put the physics in a state that is ‘invalid’.

I believe your specific problem is because the bullet kinemetic character, which is the part of the chracterController that lives in physics space, has a shape that defines it. When you set the position of the shape you are getting the collision coordinate from firing a ray upwards from a particular point in the terrain and returning where it collides with your model. You then use this point to set the position of your model. But the collision point is not the centre of your object, it is the bottom of the collision shape. So you then set the centre of the object to be exactly the point on the ground; which appears to be treated by Jmonkey as underneath which is fair as the model has no real width. I would guess that simply adding 0.00001f would be enough to stop it falling but this is not a good approach.

I would strongly advise using walkDirection to avoid this problem. It is the correct way to move CharacterControllers and allows the character to step over things, jump and tunnel out of collision overlaps.

If you must use setPhysicsLocation you need to work out the centre point position; Obviously how you do this depends on how your model rotates etc. Bear in mind that you will need to do this for all items in your scene; there is nothing preventing you from setting the object buried in another using this method.



To be bluntly honest, it seems daft to me to re-do all the work that is been done, very efficiently, by the walkDirection variable in JMonkey/Bullet. Why do you not want to use this method?

Also are you aware that chracterControl does collide with everything except other characters, which is easily overcome using a ghost Control?

Hi,

you can do a workaround to make your characters collide as they used to be (not sure it’s the best solution though).

  • to each characters, add both a CharacterControl and a RigidBodyControl (with kinematics=true) but in different collision groups to prevent them colliding together, say 01 for the CharacterControl and 02 for the RigidBodyControl
  • add a PhysicsCollisionListener, and when there is a collision between the player and a npc, inverts the collision groups of the npc, CharacterControl becoming 02 and RigidBodyControl becoming 01 such that the RigidBodyControl of the npc collides with the CharacterControl of the player



    I don’t understand though why this inversion is required since the RigidBodyControl being in group 02 for both characters, they should collide. But well I have tried this and it seems working. It should also work for two npc colliding together (you need to re-invert groups when the collision is over). I haven’t explored more the idea though, for instance I guess it fails if the player and several npcs collide altogether in a collision fest!

Ok, thanks I will try this



Edit :

Sorry mattm, I didn’t see your answer.



The reason why I’m forfeiting walkDirection is as follow :



I’m doing a ‘tactical’ game, in which you don’t control one but many characters.

Character are moving thanks to Mouse click and their path are calculated via a custom algorythm ( based on Dijkstra algorythm )

The path is calculated when the move action initialize and doesn’t change except when there is a collsion that wasn’t foreseen.

When it happens, I have to go back to the last position were there were no collision and recalculate the path.



I found it easier to check before a collision happen that after it happened and reverting back.

But, it’s perhaps due to a lack of knowledge of the engine. :slight_smile:



PS : Sorry for the late answer. During this week, I will be working on another part of my project, and I consult this forum lest frequently :smiley:

PS2 : I will try to check some tutorials for having a better understanding of what ghost controls are.

normen said:
There is none and there never will be.


Why?

@burninghammer Why don’t you imagine writing something like that on your own. You will find the answer by yourself. :wink: