Visualize and debug physics to diagnose issues:

// Enable physics debug visualization
const physicsViewer = new BABYLON.PhysicsViewer(scene);

// Show impostors for specific objects
physicsViewer.showImpostor(box.physicsImpostor, box);
physicsViewer.showImpostor(sphere.physicsImpostor, sphere);

// Visualize all physics impostors in the scene
scene.meshes.forEach(mesh => {
    if (mesh.physicsImpostor) {
        physicsViewer.showImpostor(mesh.physicsImpostor, mesh);
    }
});

// Add debugging UI
const debugLayer = new BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");

const panel = new BABYLON.GUI.StackPanel();
panel.width = "220px";
panel.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_RIGHT;
panel.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_TOP;
debugLayer.addControl(panel);

// Button to toggle physics debug visibility
const showPhysicsButton = BABYLON.GUI.Button.CreateSimpleButton("showPhysics", "Toggle Physics Debug");
showPhysicsButton.width = "200px";
showPhysicsButton.height = "40px";
showPhysicsButton.color = "white";
showPhysicsButton.background = "green";
showPhysicsButton.onPointerUpObservable.add(() => {
    // Toggle all impostor renderers
    physicsViewer.isEnabled = !physicsViewer.isEnabled;
});
panel.addControl(showPhysicsButton);

// Button to pause/resume physics
const pausePhysicsButton = BABYLON.GUI.Button.CreateSimpleButton("pausePhysics", "Pause Physics");
pausePhysicsButton.width = "200px";
pausePhysicsButton.height = "40px";
pausePhysicsButton.color = "white";
pausePhysicsButton.background = "blue";
let physicsEnabled = true;
pausePhysicsButton.onPointerUpObservable.add(() => {
    if (physicsEnabled) {
        // Pause physics
        scene.getPhysicsEngine().setTimeStep(0);
        pausePhysicsButton.textBlock.text = "Resume Physics";
    } else {
        // Resume physics
        scene.getPhysicsEngine().setTimeStep(1/60);
        pausePhysicsButton.textBlock.text = "Pause Physics";
    }
    physicsEnabled = !physicsEnabled;
});
panel.addControl(pausePhysicsButton);

// Button to reset all physics objects
const resetPhysicsButton = BABYLON.GUI.Button.CreateSimpleButton("resetPhysics", "Reset Physics");
resetPhysicsButton.width = "200px";
resetPhysicsButton.height = "40px";
resetPhysicsButton.color = "white";
resetPhysicsButton.background = "red";
resetPhysicsButton.onPointerUpObservable.add(() => {
    // Reset all dynamic objects to their original positions
    scene.meshes.forEach(mesh => {
        if (mesh.physicsImpostor && mesh.physicsImpostor.mass > 0) {
            // Reset position and rotation
            if (mesh._originalPosition) {
                mesh.position = mesh._originalPosition.clone();
                mesh.rotationQuaternion = mesh._originalRotation ? 
                    mesh._originalRotation.clone() : new BABYLON.Quaternion();
                
                // Reset velocities
                mesh.physicsImpostor.setLinearVelocity(BABYLON.Vector3.Zero());
                mesh.physicsImpostor.setAngularVelocity(BABYLON.Vector3.Zero());
            }
        }
    });
});
panel.addControl(resetPhysicsButton);

// Store original positions for reset functionality
scene.meshes.forEach(mesh => {
    if (mesh.physicsImpostor) {
        mesh._originalPosition = mesh.position.clone();
        mesh._originalRotation = mesh.rotationQuaternion ? 
            mesh.rotationQuaternion.clone() : null;
    }
});

// Log physics activity
let collisionCount = 0;
scene.meshes.forEach(mesh => {
    if (mesh.physicsImpostor) {
        mesh.physicsImpostor.onCollideEvent = (collider, collidedWith) => {
            collisionCount++;
            console.log(`Collision #${collisionCount}: ${collider.object.name} hit ${collidedWith.object.name}`);
            
            // Get collision velocity
            const relVelocity = collider.getLinearVelocity().subtract(
                collidedWith.getLinearVelocity()
            ).length();
            
            console.log(`Impact velocity: ${relVelocity.toFixed(2)}`);
        };
    }
});