I can’t speak to what the PhysicsViewer provides, but I dove into Bullet3 and PhysX pages linked earlier, and compred to what is provided in the Havok plugin.
Also, I think @regna 's idea that “raw line and color information” is somehow already generated inside Havok is likely not correct (but I have no evidence for my assertion, just wondering why would it?).
If raw color/line information doesn’t exist, then it would need to be created. With that in mind, my thought is to generate babylon visualization by initializing with physics shape data, then iterating, each physics frame, over each body for activation, position, rotation, and velocities and finally iterating over collisions for the contact points, normals, and impulses (and triangle index if it can be visualized).
I note here that Havok provides shape (geometry) debug visualization, but doesn’t seem to provide direct/aggregated access to body information (is that what PhysicsViewer does?)
In the lists below of Bullet3 and PhysX, I’ve noted with "Y"es, "N"o, "M"aybe, "E"quivalent possible, and “?” (don’t know what that is).
Ignoring constaints/joints for now.
Bullet3
- enum DebugDrawModes
- DBG_NoDebug = 0,
- Y DBG_DrawWireframe = 1,
- Y DBG_DrawAabb = 2,
- N DBG_DrawFeaturesText = 4,
- Y DBG_DrawContactPoints = 8,
- E DBG_NoDeactivation = 16,
- N DBG_NoHelpText = 32,
- N DBG_DrawText = 64,
- N DBG_ProfileTimings = 128,
- ? DBG_EnableSatComparison = 256,
- ? DBG_DisableBulletLCP = 512,
- ? DBG_EnableCCD = 1024,
- M DBG_DrawConstraints = (1 << 11),
- M DBG_DrawConstraintLimits = (1 << 12),
- N DBG_FastWireframe = (1 << 13),
- Y DBG_DrawNormals = (1 << 14),
- N DBG_DrawFrames = (1 << 15),
- DBG_MAX_DEBUG_DRAW_MODE
- DefaultColors()
- m_activeObject(1, 1, 1),
- m_deactivatedObject(0, 1, 0),
- m_wantsDeactivationObject(0, 1, 1),
- m_disabledDeactivationObject(1, 0, 0),
- m_disabledSimulationObject(1, 1, 0),
- m_aabb(1, 0, 0),
- m_contactPoint(1, 1, 0)
PhysX
Sleeping bodies are drawn in black, while awake bodies are drawn in white. If the body is sleeping and part of a sleeping group, it is drawn in red.
- Y eWORLD_AXES
- Y eBODY_AXES
- E eBODY_MASS_AXES [CG, INERTIA]
- Y eBODY_LIN_VELOCITY
- Y eBODY_ANG_VELOCITY
- Y eCONTACT_POINT
- Y eCONTACT_NORMAL
- ? eCONTACT_ERROR
- Y eCONTACT_IMPULSE (eCONTACT_FORCE PX_DEPRECATED)
- M eFRICTION_POINT
- M eFRICTION_NORMAL
- M eFRICTION_IMPULSE
- ? eACTOR_AXES
- Y eCOLLISION_AABBS (Visualize bounds (AABBs in world space)))
- Y eCOLLISION_SHAPES
- ? eCOLLISION_AXES
- Y eCOLLISION_COMPOUNDS - Compound visualization (compound AABBs in world space) [CONTAINER TYPE vs. COLLISION TYPE]
- M eCOLLISION_FNORMALS - Mesh & convex face normals
- M eCOLLISION_EDGES - Active edges for meshes
- M eCOLLISION_STATIC
- M eCOLLISION_DYNAMIC
- eJOINT_LOCAL_FRAMES [CONSTRAINTS]
- eJOINT_LIMITS [CONSTRAINTS]
- ? eCULL_BOX
- ? eMBP_REGIONS
- Y eSIMULATION_MESH
- N eSDF
LINK TO HAVOK INTERFACE
[ONCE?]
- HP_Body_GetGravityFactor(bodyId : HP_BodyId): [Result, number];
- HP_Body_GetLinearDamping(bodyId : HP_BodyId): [Result, number];
- HP_Body_GetAngularDamping(bodyId : HP_BodyId): [Result, number];
[PER FRAME?]
- HP_Body_GetQTransform(bodyId : HP_BodyId): [Result, QTransform];
- HP_Body_GetActivationState(bodyId: HP_BodyId): [Result, ActivationState];
- HP_Body_GetLinearVelocity(bodyId : HP_BodyId): [Result, Vector3];
- HP_Body_GetAngularVelocity(bodyId : HP_BodyId): [Result, Vector3];
- HP_World_GetCollisionEvents(world : HP_WorldId): [Result, number];
- HP_World_GetNextCollisionEvent(world: number, previousEvent: number): number;
- HP_Event_AsCollision(eventId : number): [Result, CollisionEvent];
[CONSTRAINTS]
- HP_Constraint_GetAxisFriction(constraint : HP_ConstraintId, axis : ConstraintAxis): [Result, number];
- HP_Constraint_GetAxisMode(constraint : HP_ConstraintId, axis : ConstraintAxis): [Result, ConstraintAxisLimitMode];
- HP_Constraint_GetAxisMinLimit(constraint : HP_ConstraintId, axis : ConstraintAxis): [Result, number];
- HP_Constraint_GetAxisMaxLimit(constraint : HP_ConstraintId, axis : ConstraintAxis): [Result, number];
- HP_Constraint_GetAxisMotorType(constraint : HP_ConstraintId, axis : ConstraintAxis): [Result, ConstraintMotorType];
- HP_Constraint_GetAxisMotorMaxForce(constraint : HP_ConstraintId, axis : ConstraintAxis): [Result, number];
- HP_Constraint_GetAxisMotorPositionTarget(constraint: HP_ConstraintId, axis: ConstraintAxis): [Result, number];
- HP_Constraint_GetAxisMotorVelocityTarget(constraint: HP_ConstraintId, axis: ConstraintAxis): [Result, number];
- HP_Constraint_GetAxisMotorStiffness(constraint: HP_ConstraintId, axis: ConstraintAxis): [Result, number];
- HP_Constraint_GetAxisMotorDamping(constraint: HP_ConstraintId, axis: ConstraintAxis): [Result, number];
- [Triggers not shown here]
[ITERATE ON BODIES]
- Returns the addr of the world’s body buffer, use with HP_Body_GetWorldTransformOffset:
- HP_World_GetBodyBuffer(world: HP_WorldId): [Result, number];
- HP_World_GetNumBodies(world : HP_WorldId): [Result, number];
- Return the memory offset containing the body’s transform from the world’s body buffer:
- HP_Body_GetWorldTransformOffset( bodyId: HP_BodyId ): [Result, number];
[SCALE VISUALIZATION OF VELOCITIES]
- HP_World_GetSpeedLimit(world: HP_WorldId): [Result, number /linear limit/, number /angular limit/];
[Existing debug - shape only, not body]
-
HP_Shape_CreateDebugDisplayGeometry( shape : HP_ShapeId ) : [Result, HP_DebugGeometryId];
-
HP_DebugGeometry_GetInfo( geometry : HP_DebugGeometryId ) : [Result, DebugGeometryInfo];
-
HP_DebugGeometry_Release( geometry : HP_DebugGeometryId ) : Result;
export type CollisionEvent = [
/* Type */ EventType,
/* Contact on body A */ ContactPoint,
/* Contact on body B */ ContactPoint,
/* Impulse applied */ number
];
export type ContactPoint = [
/* Body ID */ HP_BodyId,
/* Collider ID */ HP_ShapeId,
/* Shape hierarchy */ ShapePathIterator,
/* Position */ Vector3,
/* Normal */ Vector3,
/* Triangle index */ number
];