Index: /CS/trunk/plugins/physics/dyndebug/dyndebug.cpp
===================================================================
--- /CS/trunk/plugins/physics/dyndebug/dyndebug.cpp (revision 33668)
+++ /CS/trunk/plugins/physics/dyndebug/dyndebug.cpp (revision 33752)
@@ -85,6 +85,13 @@
 
   DynamicsDebugger::DynamicsDebugger (DebuggerManager* manager)
-    : scfImplementationType (this), manager (manager)
-  {
+    : scfImplementationType (this), manager (manager), debugMode (false)
+  {
+    // Init debug materials
+    materials[0] = CS::Material::MaterialBuilder::CreateColorMaterial
+      (manager->object_reg, "dyndebug_static", csColor (0, 0, 1));
+    materials[1] = CS::Material::MaterialBuilder::CreateColorMaterial
+      (manager->object_reg, "dyndebug_dynamic", csColor (0, 1, 0));
+    materials[2] = CS::Material::MaterialBuilder::CreateColorMaterial
+      (manager->object_reg, "dyndebug_kinematic", csColor (0, 0, 1));
   }
 
@@ -100,4 +107,15 @@
 
   void DynamicsDebugger::SetDebugDisplayMode (bool debugMode)
+  {
+    // Check display mode has changed
+    if (debugMode == this->debugMode)
+      return;
+
+    this->debugMode = debugMode;
+
+    UpdateDisplay ();
+  }
+
+  void DynamicsDebugger::UpdateDisplay ()
   {
     // Check dynsys available
@@ -109,21 +127,4 @@
     }
 
-    // Check debug material available
-    if (!material)
-      material = CS::Material::MaterialBuilder::CreateColorMaterial
-	(manager->object_reg, "dynsysdebug", csColor (1, 0, 0));
-
-    if (!material)
-    {
-      manager->Report (CS_REPORTER_SEVERITY_WARNING,
-		       "No debug material defined");
-      return;
-    }
-
-    // Check display mode has changed
-    if (debugMode == this->debugMode)
-      return;
-    this->debugMode = debugMode;
-
     // Find the pointer to the engine plugin
     csRef<iEngine> engine = csQueryRegistry<iEngine> (manager->object_reg);
@@ -135,5 +136,37 @@
     }
 
-    // TODO: remove all previous debug meshes
+    // Reset all stored meshes
+    for (csList<MeshData>::Iterator it (storedMeshes); it.HasNext (); )
+    {
+      MeshData &meshData = it.Next ();
+
+      // Remove the debug mesh
+      if (meshData.debugMesh)
+      {
+	engine->RemoveObject (meshData.debugMesh);
+	if (meshData.rigidBody)
+	  meshData.rigidBody->AttachMesh (0);
+      }
+
+      // Put back the original mesh
+      if (meshData.originalMesh)
+      {
+	meshData.originalMesh->GetMovable ()->SetSector (sector);
+	meshData.rigidBody->AttachMesh (meshData.originalMesh);
+      }
+
+      // Put back the kinematic callback
+      if (meshData.callback && meshData.rigidBody)
+      {
+	csRef<iBulletRigidBody> bulletBody =
+	  scfQueryInterface<iBulletRigidBody> (meshData.rigidBody);
+	bulletBody->SetKinematicCallback (meshData.callback->callback);
+      }
+    }
+    storedMeshes.DeleteAll ();
+
+    // If not in debug mode then it is over
+    if (!debugMode)
+      return;
 
     // Iterate through each rigid body
@@ -144,51 +177,35 @@
       iRigidBody* body = system->GetBody (bodyIndex);
 
+      // Search the bullet interface of the rigid body
+      csRef<iBulletRigidBody> bulletBody =
+	scfQueryInterface<iBulletRigidBody> (body);
+
+      // Find the material to be used for this object
+      csBulletState state = BULLET_STATE_DYNAMIC;
+      if (bulletBody)
+	state = bulletBody->GetDynamicState ();
+      else if (body->IsStatic ())
+	state = BULLET_STATE_STATIC;
+
+      iMaterialWrapper* material = materials[state];
+      if (!material)
+	continue;
+
+      // Create the MeshData object
       MeshData meshData;
-
-      // If in debug mode, then store the original attached mesh
-      if (debugMode)
+      meshData.rigidBody = body;
+
+      // Store the current mesh attached to the rigid body
+      // TODO: not debug mesh stored twice?
+      meshData.originalMesh = body->GetAttachedMesh ();
+      if (meshData.originalMesh)
       {
 	// TODO: store the sector of the mesh
-	csRef<iMeshWrapper> mesh = body->GetAttachedMesh ();
-	if (mesh)
-	{
-	  engine->RemoveObject (mesh);
-	  meshData.mesh = mesh;
-	}
-
-	storedMeshes.PutUnique (body, meshData);
-      }
-
-      // Else, go back to normal mode
-      else
-      {
-	if (storedMeshes.Contains (body))
-	{
-	  // Remove the debug mesh
-	  engine->RemoveObject (body->GetAttachedMesh ());
-
-	  // Put back the original attached mesh
-	  MeshData nullData;
-	  meshData = storedMeshes.Get (body, nullData);
-
-	  if (meshData.mesh)
-	  {
-	    meshData.mesh->GetMovable ()->SetSector (sector);
-	    body->AttachMesh (meshData.mesh);
-	  }
-
-	  else
-	    body->AttachMesh (0);
-
-	  // Erase body reference
-	  storedMeshes.DeleteAll (body);
-	}
-
-	continue;
+	engine->RemoveObject (meshData.originalMesh);
       }
 
       // TODO: display the joints too
       // TODO: use iDynamicsSystemCollider::FillWithColliderGeometry instead?
-      // TODO: use specific colors for objects static/dynamic/active/inactive
+      // TODO: use specific colors for objects active/inactive
       // TODO: display collisions
 
@@ -202,103 +219,157 @@
 	  body->GetCollider (colliderIndex);
 
-	switch (collider->GetGeometryType ())
-	  {
-	  case BOX_COLLIDER_GEOMETRY:
-	    {
-	      // Get box geometry
-	      csVector3 boxSize;
-	      collider->GetBoxGeometry (boxSize);
-	      boxSize /= 2.0;
-	      const csBox3 box(-boxSize, boxSize);
-
-	      // Create box
-	      csRef<iMeshWrapper> mesh =
-		CreateBoxMesh (box, material, collider->GetLocalTransform (),
-			       sector);
-	      body->AttachMesh (mesh);
-	    }
-	    break;
-
-	  case SPHERE_COLLIDER_GEOMETRY:
-	    {
-	      // Get sphere geometry
-	      csSphere sphere;
-	      collider->GetSphereGeometry (sphere);
-
-	      // Create sphere
-	      csRef<iMeshWrapper> mesh =
-		CreateSphereMesh (sphere, material, sector);
-	      body->AttachMesh (mesh);
-	    }
-	    break;
-
-	  case CYLINDER_COLLIDER_GEOMETRY:
-	    {
-	      // Get cylinder geometry
-	      float length, radius;
-	      collider->GetCylinderGeometry (length, radius);
-
-	      // Create cylinder
-	      csRef<iMeshWrapper> mesh =
-		CreateCylinderMesh (length, radius, material,
+	csRef<iMeshWrapper> mesh = CreateColliderMesh (collider, material);
+
+	// Register the new debug mesh
+	if (mesh)
+	{
+	  body->AttachMesh (mesh);
+	  meshData.debugMesh = mesh;
+	}
+
+	// If the body is kinematic then create a new kinematic callback
+	if (mesh && state == BULLET_STATE_KINEMATIC)
+	{
+	  meshData.callback.AttachNew
+	    (new BoneKinematicCallback (mesh, bulletBody->GetKinematicCallback ()));
+	  bulletBody->SetKinematicCallback (meshData.callback);
+	}
+      }
+
+      // Store the MeshData
+      storedMeshes.PushBack (meshData);
+    }
+
+    // Iterate through each colliders of the dynamic system
+    for (unsigned int colliderIndex = 0;
+	 colliderIndex < (unsigned int) system->GetColliderCount ();
+	 colliderIndex++)
+    {
+      iDynamicsSystemCollider* collider = system->GetCollider (colliderIndex);
+
+      // Find the material to be used for this object
+      csBulletState state = BULLET_STATE_DYNAMIC;
+      if (collider->IsStatic ())
+	state = BULLET_STATE_STATIC;
+
+      iMaterialWrapper* material = materials[state];
+      if (!material)
+	continue;
+
+      // Create the MeshData object
+      MeshData meshData;
+      meshData.debugMesh = CreateColliderMesh (collider, material);
+
+      // Store the MeshData
+      storedMeshes.PushBack (meshData);
+    }
+  }
+
+  void DynamicsDebugger::SetStaticBodyMaterial (iMaterialWrapper* material)
+  {
+    materials[0] = material;
+  }
+
+  void DynamicsDebugger::SetDynamicBodyMaterial (iMaterialWrapper* material)
+  {
+    materials[1] = material;
+  }
+
+  void DynamicsDebugger::SetBodyStateMaterial (csBulletState state,
+					       iMaterialWrapper* material)
+  {
+    materials[state] = material;
+  }
+
+  csRef<iMeshWrapper> DynamicsDebugger::CreateColliderMesh
+    (iDynamicsSystemCollider* collider, iMaterialWrapper* material)
+  {
+    csRef<iMeshWrapper> mesh;
+
+    switch (collider->GetGeometryType ())
+      {
+      case BOX_COLLIDER_GEOMETRY:
+	{
+	  // Get box geometry
+	  csVector3 boxSize;
+	  collider->GetBoxGeometry (boxSize);
+	  boxSize /= 2.0;
+	  const csBox3 box(-boxSize, boxSize);
+
+	  // Create box
+	  mesh = CreateBoxMesh (box, material, collider->GetLocalTransform (),
+				sector);
+	}
+	break;
+
+      case SPHERE_COLLIDER_GEOMETRY:
+	{
+	  // Get sphere geometry
+	  csSphere sphere;
+	  collider->GetSphereGeometry (sphere);
+
+	  // Create sphere
+	  mesh = CreateSphereMesh (sphere, material, sector);
+	}
+	break;
+
+      case CYLINDER_COLLIDER_GEOMETRY:
+	{
+	  // Get cylinder geometry
+	  float length, radius;
+	  collider->GetCylinderGeometry (length, radius);
+
+	  // Create cylinder
+	  mesh = CreateCylinderMesh (length, radius, material,
+				     collider->GetLocalTransform (), sector);
+	}
+	break;
+
+      case CAPSULE_COLLIDER_GEOMETRY:
+	{
+	  // Get capsule geometry
+	  float length, radius;
+	  collider->GetCapsuleGeometry (length, radius);
+
+	  // Create capsule
+	  mesh = CreateCapsuleMesh (length, radius, material,
 				    collider->GetLocalTransform (), sector);
-	      body->AttachMesh (mesh);
-	    }
-	    break;
-
-	  case CAPSULE_COLLIDER_GEOMETRY:
-	    {
-	      // Get capsule geometry
-	      float length, radius;
-	      collider->GetCapsuleGeometry (length, radius);
-
-	      // Create capsule
-	      csRef<iMeshWrapper> mesh =
-		CreateCapsuleMesh (length, radius, material,
+	}
+	break;
+
+      case TRIMESH_COLLIDER_GEOMETRY:
+	{
+	  // Get mesh geometry
+	  csVector3* vertices = 0;
+	  int* indices = 0;
+	  size_t vertexCount, triangleCount;
+	  collider->GetMeshGeometry (vertices, vertexCount, indices, triangleCount);
+
+	  // Create mesh
+	  mesh = CreateCustomMesh (vertices, vertexCount, indices, triangleCount,
+				   material, collider->GetLocalTransform (), sector);
+	}
+	break;
+
+      case CONVEXMESH_COLLIDER_GEOMETRY:
+	{
+	  // Get mesh geometry
+	  csVector3* vertices = 0;
+	  int* indices = 0;
+	  size_t vertexCount, triangleCount;
+	  collider->GetConvexMeshGeometry (vertices, vertexCount, indices, triangleCount);
+
+	  // Create mesh
+	  mesh = CreateCustomMesh (vertices, vertexCount, indices, triangleCount, material,
 				   collider->GetLocalTransform (), sector);
-	      body->AttachMesh (mesh);
-	    }
-	    break;
-
-	  case TRIMESH_COLLIDER_GEOMETRY:
-	    {
-	      // Get mesh geometry
-	      csVector3* vertices = 0;
-	      int* indices = 0;
-	      size_t vertexCount, triangleCount;
-	      collider->GetMeshGeometry (vertices, vertexCount, indices, triangleCount);
-
-	      // Create mesh
-	      csRef<iMeshWrapper> mesh =
-		CreateCustomMesh (vertices, vertexCount, indices, triangleCount, material,
-				collider->GetLocalTransform (), sector);
-	      body->AttachMesh (mesh);
-	    }
-	    break;
-
-	  case CONVEXMESH_COLLIDER_GEOMETRY:
-	    {
-	      // Get mesh geometry
-	      csVector3* vertices = 0;
-	      int* indices = 0;
-	      size_t vertexCount, triangleCount;
-	      collider->GetConvexMeshGeometry (vertices, vertexCount, indices, triangleCount);
-
-	      // Create mesh
-	      csRef<iMeshWrapper> mesh =
-		CreateCustomMesh (vertices, vertexCount, indices, triangleCount, material,
-				collider->GetLocalTransform (), sector);
-	      body->AttachMesh (mesh);
-	    }
-	    break;
-
-	  default:
-	    // TODO: plan meshes
-	    break;
-	  }
+	}
+	break;
+
+      default:
+	// TODO: plan meshes
+	break;
       }
-    }
-
-    // TODO: do the same with the static colliders of the dynamic system
+
+    return mesh;
   }
 
@@ -510,4 +581,22 @@
   }
 
+  BoneKinematicCallback::BoneKinematicCallback (iMeshWrapper* mesh,
+			   iBulletKinematicCallback* callback)
+    : scfImplementationType (this), mesh (mesh), callback (callback)
+  {
+  }
+
+  BoneKinematicCallback::~BoneKinematicCallback ()
+  {
+  }
+
+  void BoneKinematicCallback::GetBodyTransform
+    (iRigidBody* body, csOrthoTransform& transform) const
+  {
+    callback->GetBodyTransform (body, transform);
+    mesh->GetMovable ()->SetTransform (transform);
+    mesh->GetMovable ()->UpdateMove ();
+  }
+
 }
 CS_PLUGIN_NAMESPACE_END(DebugDynamics)
Index: /CS/trunk/plugins/physics/dyndebug/dyndebug.h
===================================================================
--- /CS/trunk/plugins/physics/dyndebug/dyndebug.h (revision 33668)
+++ /CS/trunk/plugins/physics/dyndebug/dyndebug.h (revision 33752)
@@ -26,5 +26,6 @@
 #include "csutil/leakguard.h"
 #include "csutil/weakref.h"
-#include "csutil/refarr.h"
+#include "csutil/list.h"
+#include "ivaria/bullet.h"
 #include "ivaria/dynamicsdebug.h"
 
@@ -40,4 +41,5 @@
 {
   class DynamicsDebugger;
+  class BoneKinematicCallback;
 
   class DebuggerManager : public scfImplementation2<DebuggerManager,
@@ -76,7 +78,17 @@
     virtual void SetDynamicSystem (iDynamicSystem* system);
     virtual void SetDebugSector (iSector* sector);
+
     virtual void SetDebugDisplayMode (bool debugMode);
+    virtual void UpdateDisplay ();
+
+    virtual void SetStaticBodyMaterial (iMaterialWrapper* material);
+    virtual void SetDynamicBodyMaterial (iMaterialWrapper* material);
+    virtual void SetBodyStateMaterial (csBulletState state,
+				       iMaterialWrapper* material);
 
   private:
+    csRef<iMeshWrapper> CreateColliderMesh (iDynamicsSystemCollider* collider,
+					    iMaterialWrapper* material);
+
     csRef<iMeshWrapper> CreateBoxMesh (csBox3 box,
 				       iMaterialWrapper* material,
@@ -108,6 +120,8 @@
     struct MeshData
     {
-      csRef<iMeshWrapper> mesh;
-      //csOrthoTransform transform;
+      csWeakRef<iRigidBody> rigidBody;
+      csRef<iMeshWrapper> originalMesh;
+      csRef<iMeshWrapper> debugMesh;
+      csRef<BoneKinematicCallback> callback;
     };
 
@@ -115,7 +129,25 @@
     csRef<iDynamicSystem> system;
     csRef<iSector> sector;
-    csRef<iMaterialWrapper> material;
+    csRef<iMaterialWrapper> materials[3];
     bool debugMode;
-    csHash<MeshData, csPtrKey<iRigidBody> > storedMeshes;
+    csList<MeshData> storedMeshes;
+  };
+
+
+  class BoneKinematicCallback : public scfImplementation1
+    <BoneKinematicCallback, iBulletKinematicCallback>
+  {
+  public:
+    BoneKinematicCallback (iMeshWrapper* mesh,
+			   iBulletKinematicCallback* callback);
+    ~BoneKinematicCallback ();
+
+    void GetBodyTransform (iRigidBody* body, csOrthoTransform& transform) const;
+
+  private:
+    csWeakRef<iMeshWrapper> mesh;
+    csRef<iBulletKinematicCallback> callback;
+
+    friend class DynamicsDebugger;
   };
 
Index: /CS/trunk/include/ivaria/dynamicsdebug.h
===================================================================
--- /CS/trunk/include/ivaria/dynamicsdebug.h (revision 33602)
+++ /CS/trunk/include/ivaria/dynamicsdebug.h (revision 33752)
@@ -23,5 +23,5 @@
 
 /**\file
- * Debugging of dynamics systems
+ * Debugging of dynamic systems
  */
 
@@ -31,4 +31,6 @@
 struct iDynamicSystem;
 struct iSector;
+struct iMaterialWrapper;
+enum csBulletState;
 
 /**
@@ -51,5 +53,5 @@
 struct iDynamicSystemDebugger : public virtual iBase
 {
-  SCF_INTERFACE(iDynamicSystemDebugger, 1, 0, 0);
+  SCF_INTERFACE(iDynamicSystemDebugger, 1, 0, 1);
 
   /**
@@ -74,4 +76,35 @@
    */
   virtual void SetDebugDisplayMode (bool debugMode) = 0;
+
+  /**
+   * Update the list of colliders that are displayed. Call this when you have
+   * added or removed some dynamic bodies to/from the dynamic system.
+   */
+  virtual void UpdateDisplay () = 0;
+
+  /**
+   * Set the material to be used for the colliders of the rigid bodies that are
+   * in 'static' state. If 0 is passed then the rigid bodies in 'static' state
+   * won't be displayed. If this method is not used, then a default red colored
+   * material will be used.
+   */
+  virtual void SetStaticBodyMaterial (iMaterialWrapper* material) = 0;
+
+  /**
+   * Set the material to be used for the colliders of the rigid bodies that are
+   * in 'dynamic' state. If 0 is passed then the rigid bodies in 'dynamic' state
+   * won't be displayed. If this method is not used, then a default green colored
+   * material will be used.
+   */
+  virtual void SetDynamicBodyMaterial (iMaterialWrapper* material) = 0;
+
+  /**
+   * Set the material to be used for the colliders of the rigid bodies that are
+   * in the given state. If 0 is passed then the rigid bodies in the given state
+   * won't be displayed. If this method is not used, then a default blue colored
+   * material will be used.
+   */
+  virtual void SetBodyStateMaterial (csBulletState state,
+				     iMaterialWrapper* material) = 0;
 };
 
