Custom CollisionShape

I have a model, but as it is quite ‘strange’, I want to set a collision shape for it which gets the model’s shape.



[java]green = (Node) assetManager.loadModel(“Models/Animation/Animation…j3o”);

green.setLocalScale(0.1f);

CollisionShape modelShape = CollisionShapeFactory.createMeshShape(green);

RigidBodyControl rigidControl = new RigidBodyControl(modelShape, 0);

green.addControl(rigidControl);

bulletAppState.getPhysicsSpace().add(rigidControl);[/java]



What can I do to make this happen?

You can use CompoundCollisionShape, if you want to group many collisionshapes together, else you’ll have to do it as you already stated

What did I state? I don’t really want to use CompoundCollisionShape and would like to hear alternatives. Is there any collision shape which gets the model’s shape? I saw something about HullCollisionShape, but I didn’t understand much.

What didn’t you understand about HullCollisionShape? The name says all Hull. There’s a test about it with the HoverTank model, it’s cool ^^. But it’s a dynamic shape, then the performance is slower than CompoundCollisionShape, in other hand it’s very easy to use.

This should get the models shape?

[java]CollisionShape modelShape = CollisionShapeFactory.createMeshShape(green);[/java]



alternatively just do:

[java]green.addControl(new RigidBodyControl(0)); //adds collision shape based on mesh[/java]

Btw he’s already using the compound collision shape, because if you call createMeshShape() for a node, it creates a compound shape. Just look at the source code :



[java]

/**

  • This type of collision shape is mesh-accurate and meant for immovable "world objects".
  • Examples include terrain, houses or whole shooter levels.<br/>
  • Objects with "mesh" type collision shape will not collide with each other.<br/>
  • Creates a HeightfieldCollisionShape if the supplied spatial is a TerrainQuad.
  • @return A MeshCollisionShape or a CompoundCollisionShape with MeshCollisionShapes as children if the supplied spatial is a Node. A HeightieldCollisionShape if a TerrainQuad was supplied.

    */

    public static CollisionShape createMeshShape(Spatial spatial) {

    if (spatial instanceof TerrainQuad) {

    TerrainQuad terrain = (TerrainQuad) spatial;

    return new HeightfieldCollisionShape(terrain.getHeightMap(), terrain.getLocalScale());

    } else if (spatial instanceof TerrainPatch) {

    TerrainPatch terrain = (TerrainPatch) spatial;

    return new HeightfieldCollisionShape(terrain.getHeightMap(), terrain.getLocalScale());

    } else if (spatial instanceof Geometry) {

    return createSingleMeshShape((Geometry) spatial, spatial);

    } else if (spatial instanceof Node) {

    return createMeshCompoundShape((Node) spatial);

    } else {

    throw new IllegalArgumentException("Supplied spatial must either be Node or Geometry!");

    }

    }

    [/java]

This code doesn’t work:

[java]green = (Node) assetManager.loadModel(“Models/Animation/Animation…j3o”);

green.setLocalScale(0.1f);

CollisionShape modelShape = CollisionShapeFactory.createMeshShape(green);

RigidBodyControl rigidControl = new RigidBodyControl(modelShape, 0);

green.addControl(rigidControl);

bulletAppState.getPhysicsSpace().add(rigidControl);[/java]



It ends up like this : http://tinypic.com/r/671dfs/5

@glaucomardano said:
Btw he's already using the compound collision shape


I meant a CompoundCollisionShape of simple objects to mask the scene

green (the model) is a moving model - the character, not a scene.

it should have a non-zero mass, and you need to use simple collision shapes

I tried the following:

[java]green = (Node) assetManager.loadModel("Models/Animation/Animation…j3o");

green.setLocalScale(0.1f);

CollisionShape modelShape = CollisionShapeFactory.createMeshShape(green);

RigidBodyControl rigidControl = new RigidBodyControl(modelShape, 0);

green.addControl(rigidControl);

bulletAppState.getPhysicsSpace().add(rigidControl);



player = new CharacterControl(modelShape, 0.1f);

player.setPhysicsLocation(new Vector3f(3, 10, -0.5f));[/java]



but it gives the following exception:



SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

java.lang.UnsupportedOperationException: Kinematic character nodes cannot have mesh collision shapes



What am I doing wrong?

@wezrule said:
I meant a CompoundCollisionShape of simple objects to mask the scene


Hmm. Yeah. It would give a nice performance. memonick, I didn't understand what the screen shot means ;P.
Then, or use hull shape(dynamic) or compound shape with primitive meshes (e.g.: sphere for the head, cube for the body...etc.). Creating a compound collision shape with primitive objects in sdk is my dream . I tried to create a plugin a year ago, but without success xD.
What am I doing wrong?


java.lang.UnsupportedOperationException: Kinematic character nodes cannot have mesh collision shapes


xD

Hmm… seems like I will have to create my own compoundCollisionShapes. Thanks for your help!

Just one last question…How can I see the collision shapes?

[java]bulletAppState.getPhysicsSpace().enableDebug(assetManager);[/java]



The above code only shows me the wireframes of models.



Oh, and can I use a capsuleCollisionShape with CompoundCollisionShape?

About the debug, that should work. Maybe the shapes aren’t in the right place. About the capsule shape, I don’t, neber tried it before, but I know that compound shape if for combining simple shapes, but you’re welcome to have a try with the capsule one ;P.


CompoundCollisionShape.java

A CompoundCollisionShape allows combining multiple base shapes
to generate a more sophisticated shape.

don’t use mesh shapes for dynamic objects, use hull shapes, they are generated using the factory’s createDynamicMeshShape() method, check the physics tutorials, they explain most of this stuff (hull/mesh/dynamic/static/mass etc)

1 Like

I managed to add a capsule shape. However, the debug doesn’t show the collision shape :confused:



Is there anything wrong with this code?





[java] bulletAppState.getPhysicsSpace().enableDebug(assetManager);[/java]

If theres no spatial that the control is attached to you will not see anything.

How do I attach it?