I’m seeking feedback on my approach to physics debugging visualization.
The ideas and development were spurred by @regna post here and the contributions in that thread by @roland, @Cedric, @riven04, and @qq2315137135.
All the details are below. To set the stage, here is how you enable the visualization of lines emanating from a contact point in the direction of its normal and scaled relative to the size of the impulse imparted. All observers, data management, and the translation of the PhysicsEvent data into a visualization every frame are handled within the class.
var debugLines = new ContactLines({width:0.005,propertyName:"impulse",scale:2e6},hk,scene).enable();
And to turn the visualization and data collection off:
debugLines.disable();
Please review the following and feel free to provide feedback about any aspect. I am already planning to translate it into TypeScript to improve the likelihood of it becoming integrated and distributed with Babylon.
I have a set of classes that enable easy visualizion of Havok physics. I’m looking for feedback on this initial approach. After a brief review of a few engines and their associated mechanisms for visualization, it appears that PhysicsDebug layers from other engines separate out 1) the collection of the data (which come from the engine itself) and 2) a defined interface for visualization or transmission of that data. An object/instance of a visualization class implements that defined interface that is attached to and called directly from the engine. The physics engines vary in the level of integration with the visualization class, thus the visualization interface varies.
My approach here attaches to Havok (by passing in the Plugin) and extracts data either from Havok Plugin methods (havokPlugin) or directly from the Engine (havokPlugin._hknp). The Havok Plugin is a thin layer above the Havok engine itself. Some of the methods in the engine can be quite complicated, such as when body instances or compound shapes are involved. I’m leaning towards adapting to the Plugin instead of the Engine because it reduces this complexity. And because user-level Babylon code only uses the Plugin, any differences between the Engine and the Plugin still constitute a “problem with Babylon Havok,” so there is little to be gained by extracting data “closer to Havok.” When the information needed is only available from the Engine or when there are performance improvements from avoiding additional memory or translation, the Engine is accessed directly.
// Examples of Plugin methods used:
//havokPlugin._bodies
//havokPlugin.onCollisionObservable
// Examples of Havok engine methods used:
//havokPlugin._hknp.HP_Body_GetQTransform
//havokPlugin._hknp.HP_Body_GetActivationState
Below, you’ll find an explanation of my approach including what is already implemented and ideas for additional visualizations and options. Please comment!
/**
*
* Currently, the general pattern is shown below. Examples are shown at the end.
*
* class PhysicsDebug* { // for example: ContactLines, ContactPoints, DebugMeshes
* constructor(options, havokPlugin, scene) - allocate empty arrays, capture options
* options - {parameter:value,...}
* enable() - allocate memory and enable observers for rendering and object management
* disable() - deallocate memory to minimal and disable observers
* - memory allocated is similar to post-constructor
* set parameter(value) - change parameter value
* .
* .
* .
* }
*
* DebugMeshes contains options to show physics parameters related to PhysicsBody
* and in the local space of the PhysicsBody:
* - wireframe of PhysicsBody shape
* - ActivationState ACTIVE or INACTIVE (color)
* - can add? CG, inertia vector, local axes, bounding box
* - maybe: face normals
* - what about? ActivationControl, PreStepType, MotionType (with duration)
* - what about? SimpleMaterial option along with wireframe?
* - what about? velocity angular/linear, possibly scaled relative to maximums?
* - what about? adding/removing per body? specifying inclusion or exclusion lists?
*
* ContactPoints shows the points of collision or trigger (with duration)
* - currently a sphere with specified diameter
* - what about? color based on EventType? attached to one or both Meshes with duration?
*
* ContactLines shows lines at contact points in the direction of its normal.
* - width parameter
* - scaled by impulse (collision only) or distance (collision or trigger)
* - additional scale parameter
* - color by eventType: Collision / Trigger, Start / Continue / Stop
* - what about? adding duration?
* - what about maybe? highlight facet on mesh (with duration)?
*
* Constraints (not yet started)
* - with limits?
* - what about? motors and spring-dampened motors
* Types: BALL_AND_SOCKET, DISTANCE, HINGE, LOCK, PRISMATIC, SIX_DOF, SLIDER
*
* No idea yet on how to handle these, but here is a list of general constraint parameters.
*
* PhysicsConstraintParameters {
* axisA?: Vector3;
* axisB?: Vector3;
* collision?: boolean;
* maxDistance?: number;
* perpAxisA?: Vector3;
* perpAxisB?: Vector3;
* pivotA?: Vector3;
* pivotB?: Vector3;
* }
*
* Example usage:
* new ContactLines({width:0.005,propertyName:"impulse",scale:2e6},hk,scene).enable();
* new ContactPoints({duration:1000,diameter:0.01},hk,scene).enable();
* new DebugMeshes(hk,scene).enable();
*/