Building a physics ship

Hello!

I am making a spaceship game.

Problem is, I have not given much though to physics yet.

To understand my problem, you must first get a grasp of how I set this up…

I want ships that are buildable part by part. So far, I have an environment which allows me to build ships by clicking a menu item and placing parts on the grid:

The ship can be saved to disk and then loaded into another environment.

Notice the grey sphere. That is the center of mass. It is also the localTranslation of the main node holding all the parts.

When I add a part, it recalculates where the new center of mass is and moves all the parts accordingly so that the user does not notice, so all you see is the center of mass move around.

Doing it this way allows me to rotate the whole ship by rotating the main node whilst having a realistic rotation point.

Now, this being said, my idea was to simply add the main node to the physics space and prey that JME would do the rest. If you know physics than you are probably smiling at my lack of foresight. The ship will perform fine as a static kinematic object but if I try to add mass the processor starts to get annoyed. If I set kinematic to false, my ship goes to pos (0,0,0) and gets stuck in the terrain.

So my questions are:

  1. How can I make this puppy work with physics? How can I limit the physics collision object to be more simple and just take the edges of the outside of the ship?

  2. The thing sticking out in the image below is a ramp. I make it move but obviously the physics are not rotating with the spatial because I use setLocalRotation. This prevents my player from boarding the ramp and going in the ship.

  1. Should the ship use instancing or batching? I have many similar materials and many similar meshes. Can I effectively use both?

What i do then is this:
One mesh collision shape for all not moving interior
One Compound shape with simple boxes for the outline

Use two pysicspaces, one for the space, one for the inside of my ship, transport objects going trough the airlook from one to the other.

4 Likes
  1. use the Physics (SetPhysicsLocation/Rotation) instead of the spatial. It will move the spatial Accordingly

Or alternativly you could also use a hullcollisionshape for the outside, if you are willing to trade some precision for good performance.

1 Like

hullcollisionshape means “convex hull” I think. I hope you know the implications of it. You could write special code to separate your ship into several convex hull sub objects before doing that.

Since you said that you use kinematic, the center of mass should be sufficient. For dynamic physics you would also want to calculate the inertia tensor. Given the way you build ships that would be easy too.

I would treat the ramp as a single object (kinematic too, of course).

Hello, thanks for your answers,

Can you tell me what I need to do to create a mesh collision shape for the interior?

I imagined scanning the ship with rays to find the shape of the ship after it is built and creating a mesh from the points somehow.

Can you think of an easier way?

You do know the outside (where normals are pointing) of all your inside geometry and could use this,

But your idea is better and I would do it similar (in fact your idea might even be better than my usual voxel-based approach to this problem). Just start from a free space you know and probe via grids of rays in all 6 major directions (+X, -X, +Y, -Y, +Z, -Z). Of course you will want to hide doors and ramps during that step.

In both cases (no matter how you construct the inside mesh) you will probably make a greedy mesh unification after constructing the mesh (unite triangles that have almost the same normal and are connected by vertices).

1 Like

Yeah, I like your thought there Ogli

Could you point me to a class I can use for mesh construction and unification please? I have never created a complex mesh outside of blender.

I would go Empire_Phoenix way.

To create a mesh collision shape for the interior:

private RigidBodyControl physicsControl;
CollisionShape nodeShape =
                    CollisionShapeFactory.createMeshShape((Node) groupGroupNode);
            physicsControl = new RigidBodyControl(nodeShape, 0);
            physicsControl.setKinematicSpatial(false);
            physicsControl.setKinematic(false);
            setCollisionGroups(physicsControl);
            groupGroupNode.addControl(physicsControl);
            physicsSpace.add(physicsControl);

In a perfect world, you’ll make your collisionShape from a simplified mesh, but that might not be worth it.

I do a slightly different approch in my game.

My building blocks have a secondary node/mesh for the collision.
Then i can build a (not attached) ship for the collisin shape, create it as in the cod eexample above and use it instead.

I do not do this for performance reasons however, as the meshshape is pretty fast, but for gliches reasons. Eg a small rail at the bottom of sliding doors can send you bumping over them with a physical player.

1 Like

I would simply connect the dots (points where ray collision/intersection with geometry is being detected). In short: write a new piece of software. For the mesh: google “custom mesh jmonkeyengine” or use whatever Bullet (the physics engine of jME) expects as perfect input.

For the mesh unification (or mesh simplification) there is some code in the LOD generator of jME (google “lod generator jmonkeyengine”) that might get you started. But simplification is not unification (similar but not same) - you would need to alter the code in such a way that the simplification error is minimal (in terms of normals - use the dot product to find the difference and the size of the triangle to find the are of influence). Maybe I would just write my own code there too.

Depends on the geometry: If many thin or small features are included (light bulps, pipes, etc.) it might be worth the trouble - because physics engine is way slower than graphics engine.
But yeah, you could try a shot with that BFG first and if it’s too slow then use a sniper rifle to solve the problem. :chimpanzee_wink:

Yah, bullet has great performance, so depending on the requirements, optimizations might be a waste of time or could be handled later on. I think bullet will be more performant than developer made ray casts in most similar situations and less prone to bugs. I do think it’s important data to test how well it’d work with a simple createMeshShape. Not saying it’s the best for all problems though.

We discussed to use the raycasts as a pre step to generate the collision mesh which is then used by Bullet physics.

To further speed up the physics one could have a partition of the physics space (e.g. bridge, engine room, sick bay, quarters, shuttle bay, storage room are separate sub spaces).

I think it’s a bad idea to generate your ships collision shapes depending on raycasts during play time. Sure you can detach them from the physics space when not needed, but I fail to see what raycasts have to do with physics in this case… should be the position of the player instead. I’m open to being wrong though.

Completely wrong, yes. In three different aspects (“during play time” and “position of the player” and “raycast have to do with physics”). But it’s okay since @Eric_Bourque knows what is meant. And I think we all got your hint to try it the simple way first and see if it’s fast enough. :chimpanzee_smile:

1 Like

Oh ok, you meant raycasts to generate the collision shape not during game play. Ok, makes more sense :D.
I still don’t see a reason to use raycasts here but lets let it go before we start strangling each-other :D.

Ok thanks, I will try the simple way first.

I am using BetterCharacterControl to move my player around.

How do I make the character node stick to the ship? I tried the WarpTo technique but even then the rotations are all wrong.

Thats why i mentiond a secondary inside physic space above

2 Likes

When I tested this character control thingy, I used its methods to set gravity and up vector.
Simply use the vector of your ship up axis (rotate Vector3f.UNIT_Y with ship.getLocalRotation).

If you want to move the ship around while also moving inside that ship, you enter a problem that many great companies tried to solve before. I have ideas how to handle this, here is the best: have the physics space with center at (0,0,0) and the graphics space where the ship is, then do the physics calculations for moving inside the ship in the physics space, remember the position of all objects, copy the position to the graphics objects (relative to the local rotation and translation of the ship), then render the graphics in the graphics space - would require some custom code, it’s not the standard way.

I don’t know this. Have a link for it?

Oh, you can use the dark side of the force too? Just like Darth Vader or Darth Ogli ben Kenogli?

Well then I will wait until you sleep… :chimpanzee_wink: