GoblinPhysics
GoblinPhysics copied to clipboard
Raycast vehicle system
Dependent on first adding more callbacks that such a system can tie into.
:+1: Definitely behind this. Do you recall what callbacks you needed? Cannon's implementation appears to update the vehicle every step.
World
will emit a stepStart
event which serves the same purpose. World
would need to be modified to track its vehicle
systems similar to how rigid bodies are tracked (this.systems
, this.addSystem
, this.removeSystem
). All system
s should be notified when they are added/removed to/from the world so they can manage any relevant constraints. Knowing what world it is added to also provides a way to cast the rays.
A RaycastVehicleSystem
should take the vehicle's rigid body and a system description in the constructor, something listing the wheels/suspension information, build the internal state, add constraints to the world, and listen for stepStart
.
Depending on implementation details, HingeConstraint
may need motor capability added and SliderConstraint
may need limits & a motor, or a SpringConstraint
be created (ideal).
At a broad level I believe that's everything required.
The idea of creating a separate systems
array to track vehicles didn't make much sense to me until I looked at the RigidBody
implementation- not only does it track values but it also contains a number of helper functions. Looks like the way to go.
Two questions though:
-
How can we handle constraints? In cannon's implementation, traditional constraints do not seem to be used. Instead, all the math is handled within the RaycastVehicle
updateVehicle
callback and various helper functions. Wheel positions and their custom options are tracked within an array ofWheelInfo
objects.As it stands, Cannon's RaycastVehicle is ~700 lines of code and I feel that the vast majority of it is because the developer re-implemented things like
HingeConstraint
andSpringConstraint
. I can only assume this is because the wheels aren't actually bodies and cannot be used with the standard constraint definitions.Is there a clean solution for this?
-
Do you think it would be possible to use
systems
to track more than just raycast vehicles or do you see that causing problems later? I think as long as each system exposed certain functions likeupdate
there should be no issues.
I'll answer the second question first, you are correct. This should be a reusable interface that other systems like a ragdoll body could take advantage of as well.
To your first question. It is completely valid for a system to handle its internal constraints itself, for example Bullet's ragdoll system implements a featherweight constraint solver for ragdolls which runs independent of the rest of the world's constraints. As you noted, Cannon takes the same approach for its vehicles. It's a trade off between performance and accuracy. I'd prefer the accuracy provided by intertwining the constraints into the world unless we can show that's terrible performance.
As an overall approach which likely has holes, each wheel will need a spring for suspension and a slider for applying the wheel's change in velocity. Since a raycast vehicle doesn't have actual, physical wheels there's no need for any hinge constraints for steering the wheel or applying power. I believe nothing needs to be added to the slider constraint for this, as the bias
can be used to add velocity to the system in lieu of a motor. Should probably create an independent SpringConstraint
.
At each step, a ray is cast from the mount point on the vehicle's rigid body "downward" to a maximum length of max_suspension_length + wheel_radius
, if an object collides with the ray then the spring and slider constraints are activated and updated for that frame. For performance there would need to be direct modification of the constraints' values instead of destroying/recreating them every frame. Because it's probably not obvious, the slider constraint would act to propel the car and the object beneath it in equal but opposite directions.
It's possible the slider could be avoided and a FrictionConstraint
is used instead. In this case a custom Contact
object would need to be created and filled in with the results of the ray intersection.
Couple things that look like they could be useful that a quick search pulled up - http://www.asawicki.info/Mirror/Car%20Physics%20for%20Games/Car%20Physics%20for%20Games.html http://nccastaff.bournemouth.ac.uk/jmacey/MastersProjects/MSc12/Srisuchat/Thesis.pdf
Both of these end up going into engine/clutch/gearing that can be ignored for Goblin, at least for the initial implementation.
Thanks, that's some good info. Could you give me a rough example of how the SliderConstraint
solution would be implemented? Specifically, how would force be applied to the object in contact?
Thinking about this some more, the SliderConstraint isn't the best answer because it will constrain all motion, not just apply force along one axis. Perhaps the best start is to take the approach detailed in that PDF and keep it all local to the vehicle system, no external constraints.