Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plunger mesh, collision and animation #84

Merged
merged 28 commits into from Jun 17, 2020
Merged

Plunger mesh, collision and animation #84

merged 28 commits into from Jun 17, 2020

Conversation

freezy
Copy link
Owner

@freezy freezy commented Jun 15, 2020

This PR adds mesh generation, collision and animation for the plunger, and closes #35.

Mesh Generation

Mesh generation is somewhat complex, since there are multiple types, and the plunger tip's shape can be customized in the editor. There are a few classes doing that (PlungerMeshGenerator, PlungerCoord and PlungerDesc). Furthermore, the mesh depends on the plunger's position (see Animation below).

Note that we generate the spring and the rod as separate meshes, while Visual Pinball produces one single mesh.

Collision

The plunger's physics bodies consist of a bunch of LineSegs andHitLineZs. Three of those are static, the other five are dynamic, i.e. depending on the plunger's position. Since the KdTree where the colliders are stored is static, we had to split those:

  • Static colliders are wrapped into a PlungerCollider and go into the KdTree.
  • Dynamic colliders are wrapped into PlungerColliderData and are attached to the plunger entity.
  • The nearphase of the PlungerCollider implementation then takes in PlungerColliderData so it can properly test for the nearest hit time.

Animation

Since the mesh depends on the plunger's position (it's not just a simple transformation, but vertices are lined up differently), we need to update the mesh when the plunger moves. What's currently happening is that vertices of all positions are packed as a dynamic buffer on the entity (PlungerMeshBufferElement), and when updating the mesh, we push the corresponding slice to the mesh.

I've asked this question on the Unity forums, and someone explained how to do it like Visual Pinball does it (i.e. upload all vertices to the GPU and just switch the index). Since we rarely do updates, the current approach runs fine, but there is potential for optimization.

Data Components

We have more data structs than usual, here's a brief summary:

  • PlungerAnimationData - Only stores the current position of the plunger, and if it has changed. The system that updates the mesh will look at this.
  • PlungerColliderData - Contains the dynamic colliders, as mentioned above
  • PlungerMovementData - The dynamic data of the plunger mechanics
  • PlungerStaticData - Static data from the .vpx file that doesn't change (or only via the (yet-to-be-defined) scripting API)
  • PlungerVelocityData - Also plunger mechanics data, but only used when calculating the velocity.

Systems

There are also a few more systems than usual. In order of execution:

  • PlungerVelocitySystem - That would be VP's PlungerMoverObject::UpdateVelocities(), as usual.
  • PlungerDisplacementSystem - VP's PlungerMoverObject::UpdateDisplacements(), as usual
  • PlungerAnimationSystem - Executed once per frame, this calculates the current position and if it has changed. This component is assigned to the children (i.e. the rod and the spring, where the mesh sits).
  • PlungerTransformationSystem - Updates the meshes, if changed. Also assigned to the children.

API

While the API isn't finalized, we still need a way to move the plunger. For now, I've taken Visual Pinball's API, i.e. PullBack() and Fire(). Now, there are two parts of this. The first part is the ECS related stuff, i.e. fetching the component data, writing the new values and applying it back to the entity. This went into PlungerApi.

The second part is computing the new values. The Fire() command for example has two dozens of lines dealing with the fire speed and whatnot. This went into PlungerCommand.

In short, mapping a button to the plunger via the API looks like that:

if (Input.GetKeyDown(KeyCode.Return)) {
	_tableApi.Plunger("Plunger").PullBack();
}
if (Input.GetKeyUp(KeyCode.Return)) {
	_tableApi.Plunger("Plunger").Fire();
}

TODO

  • Expand the AABB to the full length so it's not dependent on the current position
  • Deal with spring-less plungers
  • Get the Unity inspector on par with the other elements

@freezy freezy added unity Concerns the Unity project geometry Related to mesh generation physics Related to the physics engine labels Jun 15, 2020
@freezy freezy added this to the Physics Working milestone Jun 15, 2020
@freezy freezy self-assigned this Jun 15, 2020
@freezy freezy merged commit 4e6a53c into master Jun 17, 2020
@freezy freezy deleted the feature/plunger branch July 4, 2020 20:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
geometry Related to mesh generation physics Related to the physics engine unity Concerns the Unity project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement plunger hit collider
2 participants