This PR adds support for kinematic colliders. It closes #322.
The behavior is quite similar to Unity's kinematic rigidbody, i.e. it's not part of the simulation, but can transform freely with the colliders being transformed along.
We use the items' transformation matrix as a source. That means a component that transforms an item must go through the VPE-specific data in order to apply the transformation. That also means that just transforming it through Unity's Transform won't automatically update the colliders.
The rest is automatic. For example, if your component moves an object each frame by changing the primitive's X-position, the physics engine now automatically updates the colliders on each frame.
Caveats
It would be great if the physics engine supported parenting, i.e. transforming a parent object whose children are items that would then be automatically updated. VPX doesn't support this, but here it would make a lot of sense.
It would also be great if moving colliders came with a velocity. Right now, kinematic colliders cannot be used for continuous contact like a ball in a rotating gun, since the gun colliders don't push the ball away when they collide with it (they are literally teleported from position n to n+1 each frame).
Both of these caveats will eventually be addressed, but aren't part of this PR.
Implementation
The approach is the following:
Items in the editor can be marked as kinematic, which results in their colliders going into another NativeColliders collection, called KinematicColliders.
During start-up, the physics engine builds three additional sets of data:
A list of changed transformation matrices for each kinematic item.
Another copy of all kinematic colliders, but each transformed to their identity matrix (KinematicCollidersAtIdentity).
A list of collider IDs for each kinematic item.
On each frame, before entering the physics loop, the physics engine checks which of the kinematic items' transformation matrix has changed.
During the physics loop, for each frame:
The changed transformation matrices are applied to the respective kinematic colliders, using KinematicCollidersAtIdentity as a base, written to KinematicColliders.
A new octree is built from KinematicColliders
During the physics loop, for each tick:
The new kinematic octree is run through broad phase.
The narrow phase and collision code is the same as for static collisions, but now knows which collider collection to access, thanks to CollisionEventData.IsKinematic
TODO before merging
[x] Make transformation matrix creation GC-less
~[ ] Treat the remaining item types~
~[ ] Create a new component that applies transformations based on coil signals.~
~[ ] Documentation~
This PR and various comments on Discord made me realize that the next step before getting support for all items is to properly handle parenting. For example, all dragpoint-based items (rubbers, walls, ramps, etc) currently don't transform at all in VPX. They are uniquely defined by their dragpoint's (global) position. The first step would be to make all items transformable, i.e. make their colliders transformable. Once that's possible, the next step is parenting, and then we get kinematic support for all of these items basically for free.
This PR adds support for kinematic colliders. It closes #322.
The behavior is quite similar to Unity's kinematic rigidbody, i.e. it's not part of the simulation, but can transform freely with the colliders being transformed along.
https://github.com/freezy/VisualPinball.Engine/assets/70426/3d92a2b4-cb67-4f2b-85d0-4bb8f49607ce
How it works
We use the items' transformation matrix as a source. That means a component that transforms an item must go through the VPE-specific data in order to apply the transformation. That also means that just transforming it through Unity's
Transform
won't automatically update the colliders.The rest is automatic. For example, if your component moves an object each frame by changing the primitive's X-position, the physics engine now automatically updates the colliders on each frame.
Caveats
It would be great if the physics engine supported parenting, i.e. transforming a parent object whose children are items that would then be automatically updated. VPX doesn't support this, but here it would make a lot of sense.
It would also be great if moving colliders came with a velocity. Right now, kinematic colliders cannot be used for continuous contact like a ball in a rotating gun, since the gun colliders don't push the ball away when they collide with it (they are literally teleported from position
n
ton+1
each frame).Both of these caveats will eventually be addressed, but aren't part of this PR.
Implementation
The approach is the following:
NativeColliders
collection, calledKinematicColliders
.KinematicCollidersAtIdentity
).KinematicCollidersAtIdentity
as a base, written toKinematicColliders
.KinematicColliders
CollisionEventData.IsKinematic
TODO before merging
This PR and various comments on Discord made me realize that the next step before getting support for all items is to properly handle parenting. For example, all dragpoint-based items (rubbers, walls, ramps, etc) currently don't transform at all in VPX. They are uniquely defined by their dragpoint's (global) position. The first step would be to make all items transformable, i.e. make their colliders transformable. Once that's possible, the next step is parenting, and then we get kinematic support for all of these items basically for free.