Tutorial: GE2 to/from Unity RigidBody Physics

Tutorial: GE2 to/from Unity RigidBody Physics

GE2 provides a self-contained system for gravitational evolution (and also Kepler and other determinsistic propagators). It has a simple collision detections system. In cases where there is a short duration collision between scene objects with complicated geometries it can be useful to make use of the Unity collision resolution system. An example of this is provided by the sample scenes in the advanced tutorials folder: GE2_to_UnityRigidBody. This section describes the implementation presented there.

The “big picture” for this approach is:

  • use of Unity colliders and RigidBodies must take place in a scene display

  • GE2 must stop evolving the body affected (remove from GE2)

  • Unity physics must take over the evolution and each FixedUpdate will apply a gravitational force

  • once the collision has concluded the body can stop evolving with Unity and move back to GE2

  • continued rotational evolution using Unity physics can be acheived by using RigidBody contraints

This approach has some consequences:

  • it assumes the body collision will be resolved in a specific GSDisplay component because the colliders must be attached to GSDisplayBody components

  • for simplicity we will assume the Unity gravitational field is due to a single mass that the body is orbiting

  • we want a body with zero gravitational mass to have a specific mass for collision purposes (so rigidBody mass and GSBody mass can be different)

  • the evolution cadence of GE2 needs to match the physics evolution of Unity, this affects the scaling of the fixed update rigid body force

What the Demo does

The demo places two ships close to each other in orbit around a central mass. To allow a “close in” view of the ships it makes use of a camera that is tied to the body that will remain under GE2 control. Initially the two ships evolve using KEPLER propagators. The close approach of the two ship is detected by using the GE2 collision system and adding a GSCollider to each body with the collision mode set to TRIGGER. This will result in a physics event callback being sent to any registered listeners. A controller, ToFromRigidBodyController registers itself to receive these callbacks and then activates a RigidBodyOrbit script on each ship.

The RigidBodyOrbit script manages the switch between GE2 and rigid body physics. When the ship is in rigid body evolution mode it applies an appropriatly scaled gravitation force from the central body on each FixedUpdate cycle.

[LINK to video]

How the Demo works

The class RigidBodyOrbit does the GE2/Unity handover for a single GSBody. The steps taken are summarized below. There is one subtle point in the code: requests for information from GE2 by default give values in the default units (world space units) indicated in the GSController. The Unity RigidBody physics is done in the display space and there is a conversion factor between distances and velocities. In addition in the Unity force calculation in display space the time evolution is in game time and not the “world time per game second” in world space. This change in time affects the scaling of the gravitational constant! This is accounted for in the implementation.

The RigidBody components of the ships are initally configured to have a contraint that freezes their position. This leaves them free to rotate but allows GE2 to move the transforms in the usual way.

Conversion from GE2 to RigidBody:

  1. Get the current world state \((r,v)\) of the ship

  2. Scale into \((r,v)\) for the rigidBody component and set there

  3. Remove the GSBody from the controlles and disable display body/orbit

  4. Configure the rigidBody so there are no contraints.

  5. Compute the force for the rigidbody (and continue to do so on subsequent fixed updates)

Conversion from RigidBody to GE2:

  1. Get current \((r, v)\) from the rigidbody

  2. Convert to GE2 world scale

  3. Update the body initial data of the GSBody with \((r,v)\)

  4. Add the GSBody and record the new body id

  5. Set the body id in the display objects and re-enable their display

  6. Set the rigidBody contraints to freeze position