Warning: Can't synchronize with the repository (Couldn't open Subversion repository /home/crystal/scm/crystal: SubversionException: ("Expected FS format between '1' and '3'; found format '4'", 160043)). Look in the Trac log for more information.

This page collects information on the GSOC project about the overhaul of the collision and physics systems.

API proposition

Main objects are:

For the collision system:

  • iCollisionSystem: main plugin, can create sectors/objects/colliders (objects are destroyed when no one has any reference on them)
  • iCollisionSector: holder for a set of colliders (to be mapped with a iSector), can add/remove portals/objects
  • iCollisionObject: a list of colliders holding together, can be ghost/solid, can add/remove colliders
  • iCollider: methods to define the type of the collider (sphere, box, etc)
  • iCollisionActor, inherits from iCollisionObject: dynamic object (see csColliderActor and Bullet's character controller)
  • iCollisionCallback: to be set on a iCollisionObject (and soft bodies?) // TODO

For the physical system:

  • iPhysicalSystem: also exposed when this is the Bullet plugin
  • iPhysicalSector: also exposed when this is the Bullet plugin
  • iPhysicalObject: implements iCollisionObject?
  • iRigidBody, inherits from iPhysicalObject, iCollisionObject
  • iSoftBody, inherits from iPhysicalObject
  • iJoint

API proposition

Here is the current proposition of the API made by Lulu.

  • collision.h
    #ifndef __CS_IVARIA_COLLISION_H__
    #define __CS_IVARIA_COLLISION_H__
    
    namespace CS
    {
    namespace Collision
    {
    
    struct csConvexResult;
    typedef size_t CollisionGroupMask;
    
    enum ColliderType
    {
        COLLIDER_INVALID = 0,
        COLLIDER_BOX,
        COLLIDER_SPHERE,
        COLLIDER_CYLINDER,
        COLLIDER_CAPSULE,
        COLLIDER_CONE,
        COLLIDER_PLANE,
        COLLIDER_CONVEX_MESH,
        COLLIDER_CONCAVE_MESH,
        COLLIDER_CONCAVE_MESH_SCALED,        
        COLLIDER_TERRAIN, 
    };
    
    enum CollisionObjectType
    {
        COLLISION_OBJECT_BASE = 0,
        COLLISION_OBJECT_GHOST,
        COLLISION_OBJECT_ACTOR
    };
    
    struct CollisionGroup
    {
        csString name;
        CollisionGroupMask value;
    };
    
    struct MoveResult
    {
        bool hasHit;
        csVector3 hitNormalWorld;
        csVector3 hitPointWorld;
        csVector3 hitNormalLocal;
        csVector3 hitPointLocal;
    };
    
    struct HitBeamResult
    {
        HitBeamResult ()
        : hasHit (false), body (0), isect (0.0f), normal (0.0f), vertexIndex (0)
        {}
    
        /**
        * Whether the beam has hit a body or not.
        */
        bool hasHit;
    
        /**
        * The collision object that was hit, or \a nullptr if no object was hit.
        */
        iCollisionObject* object;
    
        /**
        * Intersection point in world space.
        */
        csVector3 isect;
    
        /**
        * Normal to the surface of the body at the intersection point.
        */
        csVector3 normal;
    
        /**
        * The index of the closest vertex of the soft body to be hit. This is only valid
        * if it is a soft body which is hit.
        */
        size_t vertexIndex;
    };
    
    struct CollisionData
    {
        csVector3 position; // in world coordinates? in object coordinates for both bodies?
        csVector3 penetration;
    };
    
    struct iCollisionCallback: public virtual iBase
    {
        SCF_INTERFACE (iCollisionCallback, 1, 0, 0);
    
        /**
        * A collision occurred.
        * \param thisbody The body that received a collision.
        * \param otherbody The body that collided with \a thisBody.
        * \param collisions The list of collisions between the two bodies.
        * \param timesteps Since how many simulation time steps this collision occured.
        */
        virtual void OnCollision (iCollisionObject *thisbody, iCollisionObject *otherbody,
                                  const csArray<CollisionData>& collisions, size_t timesteps) = 0;
    };
    
    /**
    * A base interface for colliders. 
    * Other colliders will be derived from this one.
    */
    struct iCollider : public virtual iBase
    {
        SCF_INTERFACE (CS::Collision::iCollider, 1, 0, 0);
    
        /**
        * Get the geometry type of this collider.
        */
        virtual ColliderType GetGeometryType () const = 0;
    
        virtual void SetLocalScale (const csVector3& scale) = 0;
    
        virtual const csVector3& GetLocalScale () const = 0;
    
        /**
        * Set the margin of this collision shape.
        */
        virtual void SetMargin (float margin) = 0;
    
        virtual float GetMargin () const = 0;
    }
    
    /**
    * A box collider.
    *
    * Main creators of instances implementing this interface:
    * - iCollisionSystem::CreateColliderBox()
    * 
    * Main ways to get pointers to this interface:
    * - iCollisionObject::GetCollider()
    * 
    * Main users of this interface:
    * - iCollisionObject
    */
    struct iColliderBox : public virtual iCollider
    {
        SCF_INTERFACE (CS::Collision::iColliderBox, 1, 0, 0);
    
        /**
        * Get the box geometry of this collider.
        */
        virtual csVector3 GetBoxGeometry ()  = 0;
        // + methods to change the geometry?
    };
    
    /**
    * A sphere collider.
    *
    * Main creators of instances implementing this interface:
    * - iCollisionSystem::CreateColliderSphere()
    * 
    * Main ways to get pointers to this interface:
    * - iCollisionObject::GetCollider()
    * 
    * Main users of this interface:
    * - iCollisionObject
    */
    struct iColliderSphere : public virtual iCollider
    {
        SCF_INTERFACE (CS::Collision::iColliderSphere, 1, 0, 0);
    
        /**
        * Get the sphere geometry of this collider.
        */
        virtual float GetSphereGeometry () = 0;
    };
    
    /**
    * A cylinder collider.
    *
    * Main creators of instances implementing this interface:
    * - iCollisionSystem::CreateColliderCylinder()
    * 
    * Main ways to get pointers to this interface:
    * - iCollisionObject::GetCollider()
    * 
    * Main users of this interface:
    * - iCollisionObject
    */
    struct iColliderCylinder : public virtual iCollider
    {
        SCF_INTERFACE (CS::Collision::iColliderCylinder, 1, 0, 0);
    
        /**
        * Get the cylinder geometry of this collider.
        */
        virtual void GetCylinderGeometry (float& length, float& radius) = 0;
    };
    
    /**
    * A capsule collider.
    *
    * Main creators of instances implementing this interface:
    * - iCollisionSystem::CreateColliderCapsule()
    * 
    * Main ways to get pointers to this interface:
    * - iCollisionObject::GetCollider()
    * 
    * Main users of this interface:
    * - iCollisionObject
    */
    struct iColliderCapsule : public virtual iCollider
    {
        SCF_INTERFACE (CS::Collision::iColliderCapsule, 1, 0, 0);
    
        /**
        * Get the capsule geometry of this collider.
        */
        virtual void GetCapsuleGeometry (float& length, float& radius) = 0;
    };
    
    /**
    * A cone collider.
    *
    * Main creators of instances implementing this interface:
    * - iCollisionSystem::CreateColliderCone()
    * 
    * Main ways to get pointers to this interface:
    * - iCollisionObject::GetCollider()
    * 
    * Main users of this interface:
    * - iCollisionObject
    */
    struct iColliderCone : public virtual iCollider
    {
        SCF_INTERFACE (CS::Collision::iColliderCone, 1, 0, 0);
    
        /// Get the capsule geometry of this collider.
        virtual void GetConeGeometry (float& length, float& radius) = 0;
    };
    
    /**
    * A plane collider.
    *
    * Main creators of instances implementing this interface:
    * - iCollisionSystem::CreateColliderPlane()
    * 
    * Main ways to get pointers to this interface:
    * - iCollisionObject::GetCollider()
    * 
    * Main users of this interface:
    * - iCollisionObject
    */
    struct iColliderPlane : public virtual iCollider
    {
        SCF_INTERFACE (CS::Collision::iColliderPlane, 1, 0, 0);
    
        /**
        * Get the plane geometry of this collider.
        */
        virtual csPlane3 GetPlaneGeometry () = 0;
    };
    
    /**
    * A convex mesh collider.
    *
    * Main creators of instances implementing this interface:
    * - iCollisionSystem::CreateColliderConvexMesh()
    * 
    * Main ways to get pointers to this interface:
    * - iCollisionObject::GetCollider()
    * 
    * Main users of this interface:
    * - iCollisionObject
    */
    struct iColliderConvexMesh : public virtual iCollider
    {
        SCF_INTERFACE (CS::Collision::iColliderConvexMesh, 1, 0, 0);
    
        /**
        * Get the mesh factory of this collider.
        */
        virtual iMeshFactoryWrapper* GetMeshFactory () = 0;
    };
    
    /**
    * A concave mesh collider.
    *
    * Main creators of instances implementing this interface:
    * - iCollisionSystem::CreateColliderConcaveMesh()
    * 
    * Main ways to get pointers to this interface:
    * - iCollisionObject::GetCollider()
    * 
    * Main users of this interface:
    * - iCollisionObject
    */
    struct iColliderConcaveMesh : public virtual iCollider
    {
        SCF_INTERFACE (CS::Collision::iColliderConcaveMesh, 1, 0, 0);
    
        /**
        * Get the mesh factory of this collider.
        */
        virtual iMeshFactoryWrapper* GetMeshFactory () = 0;
    };
    
    /**
    * A scaled concave mesh collider.
    *
    * Main creators of instances implementing this interface:
    * - iCollisionSystem::CreateColliderConcaveMeshScaled()
    * 
    * Main ways to get pointers to this interface:
    * - iCollisionObject::GetCollider()
    * 
    * Main users of this interface:
    * - iCollisionObject
    */
    struct iColliderConcaveMeshScaled : public virtual iCollider
    {
        SCF_INTERFACE (CS::Collision::iColliderConcaveMeshScaled, 1, 0, 0);
    
        /**
        * Get the concave collider scaled by this collider.
        */
        virtual iColliderConcaveMesh* GetCollider () = 0;
    };
    
    /**
    * A terrain collider.
    *
    * Main creators of instances implementing this interface:
    * - iCollisionSystem::CreateColliderTerrain()
    * 
    * Main ways to get pointers to this interface:
    * - iCollisionObject::GetCollider()
    * 
    * Main users of this interface:
    * - iCollisionObject
    */
    struct iColliderTerrain : public virtual iCollider
    {
        SCF_INTERFACE (CS::Collision::iColliderTerrain, 1, 0, 0);
    
        virtual iTerrainSystem* GetTerrain () const = 0;
    };
    
    /**
     * A iCollisionActor is a kinematic collision object. It has a faster collision detection and response.
     * You can use it to create a player or character model with gravity handling.
     *
     * Main creators of instances implementing this interface:
     * - iCollisionSystem::CreateCollisionActor()
     * 
     * Main ways to get pointers to this interface:
     * - iCollisionSystem::GetCollisionActor()
     * 
     * Main users of this interface:
     * - iCollisionSystem
     */
    // kickvb: most of this would have to be redesigned, let's do it later
    struct iCollisionActor : public virtual iCollisionObject
    {
        SCF_INTERFACE (CS::Collision::iCollisionActor, 1, 0, 0);
    
        /**
        * Check if we are on the ground.
        */
        virtual bool IsOnGround () = 0;
    
        /**
        * Set the onground status.
        */
        //virtual void SetOnGround (bool og) = 0;
    
        /**
        * Get current rotation in angles around every axis.
        */
        virtual csVector3 GetRotation () const = 0;
    
        /**
        * Set current rotation in angles around every axis and set to actor.
        * If a camera is used, set it to camera too.
        */
        virtual void SetRotation (const csVector3& rot) = 0;
    
        /**
        * Move the actor.
        */
        virtual void UpdateAction (float delta) = 0;
    
        /**
        * Draw the debug informations of this actor.
        */
        // really?
        //virtual void DebugDraw (iView* rview) = 0;
    
        /**
        * Set the up axis of the actor.
        */
        virtual void SetUpAxis (int axis) = 0;
    
        /**
        * Set the walking velocity of the actor.
        */
        virtual void SetVelocity (const csVector3& dir) = 0;
    
        /**
        * Set the walking velocity with which the character should move for
        * the given time period. After the time period, velocity is reset to zero.
        * Negative time intervals will result in no motion.
        */
        virtual void SetVelocityForTimeInterval (const csVector3& velo,
            float timeInterval) = 0;
    
        /**
        * This is used by UpdateAction() but you can also call it manually.
        * It will adjust the new position to match with collision
        * detection.
        */
        virtual void PreStep () = 0;
    
        /**
        * This is used by UpdateAction() but you can also call it manually.
        * Move the actor to proper target position.
        */
        virtual void PlayerStep (float delta) = 0;
    
        /**
        * Set the falling speed.
        */
        virtual void SetFallSpeed (float fallSpeed) = 0;
    
        /**
        * Set the jumping speed.
        */
        virtual void SetJumpSpeed (float jumpSpeed) = 0;
    
        /**
        * Set the max jump height an actor can have.
        */
        virtual void setMaxJumpHeight (float maxJumpHeight) = 0;
    
        /**
        * Let the actor jump.
        */
        virtual void Jump () = 0;
    
        /**
        * The max slope determines the maximum angle that the actor can walk up.
        * The slope angle is measured in radians.
        */
        virtual void SetMaxSlope (float slopeRadians) = 0;
        
        /**
        * Get the max slope.
        */
        virtual float GetMaxSlope () const = 0;
    };
    
    /**
    * This is the interface of a collision object. 
    * It contains the collision information of the object.
    *
    * Main creators of instances implementing this interface:
    * - iCollisionSystem::CreateCollisionObject()
    * 
    * Main ways to get pointers to this interface:
    * - iCollisionSystem::GetCollisionObject()
    * 
    * Main users of this interface:
    * - iCollisionSystem
    */
    struct iCollisionObject : public virtual iBase
    {
        SCF_INTERFACE (CS::Collision::iCollisionObject, 1, 0, 0);
    
        /**
        * Set the type of the collision object.
        */
        virtual void SetObjectType (CollisionObjectType type) = 0;
    
        /**
        * Return the type of the collision object.
        */
        virtual CollisionObjectType GetObjectType () = 0;
    
        /**
        * Set the movable attached to this collision object. Its position will be updated
        * automatically when this object is moved.
        */
        virtual void SetAttachedMovable (iMovable* movable) = 0;
    
        /**
        * Get the movable attached to this collision object.
        */
        virtual iMovable* GetAttachedMovable () = 0;
    
        /**
        * Set the transform.
        */
        virtual void SetTransform (const csOrthoTransform& trans) = 0;
    
        /**
        * Get the transform.
        */
        virtual csOrthoTransform GetTransform () = 0;
    
        /**
        * Add a collider to this collision body.
        */
        virtual void AddCollider (iCollider* collider, const csOrthoTransform& trans) = 0;
    
        /**
        * Remove the given collider from this collision object.
        */
        virtual void RemoveCollider (iCollider* collider) = 0;
    
        /**
        * Remove the collider with the given index from this collision object.
        */
        virtual void RemoveCollider (size_t index) = 0;
    
        /**
        * Get the collider with the given index.
        */
        virtual iCollider* GetCollider (size_t index) = 0;
    
        /**
        * Get the count of colliders in this collision object.
        */
        virtual size_t GetColliderCount () = 0;
    
        /**
        * Rebuild this collision object.
        */
        virtual void RebuildObject () = 0;
    
        /**
        * Set the collision group this object belongs to.
        */
        virtual void SetCollisionGroup (const char* name);
    
        /**
        * Get the collision group this object belongs to.
        */
        virtual const char* GetCollisionGroup () const;
    
        /**
        * Set a callback to be executed when this body collides with another.
        * If 0, no callback is executed.
        */
        virtual void SetCollisionCallback (iCollisionCallback* cb) = 0;
        // + methods to get the current list of collisions with other objects?
        // + functionalities to filter the collisions we would like to listen to?
    
        /**
        * Get the collision response callback.
        */
        virtual iCollisionCallback* GetCollisionCallback () = 0;
    
        /**
        * Test collision with another collision objects.
        */
        virtual bool Collide (iCollisionObject* otherObject) = 0;
    
        /**
        * Follow a beam from start to end and return whether this body was hit.
        */
        virtual HitBeamResult HitBeam (
            const csVector3& start, const csVector3& end) = 0;
    };
    
    struct iCollisionSector : public virtual iBase
    {
        SCF_INTERFACE (CS::Collision::iCollisionSector, 1, 0, 0);
    
        virtual void SetInternalScale (float scale) = 0;
    
        /**
        * Set the global gravity.
        */
        virtual void SetGravity (const csVector3& v) = 0;
    
        /**
        * Get the global gravity.
        */
        virtual csVector3 GetGravity () const = 0;
    
        /**
        * Add a collision object into the sector.
        * The collision object has to be initialized.
        */
        virtual void AddCollisionObject (iCollisionObject* object) = 0;
    
        /**
        * Remove a collision object by pointer.
        */
        virtual void RemoveCollisionObject (iCollisionObject* object) = 0;
    
        /**
        * Add a portal into the sector. Collision objects crossing a portal will be switched from iCollisionSector's.
        */
        virtual void AddPortal (iPortal* portal);
    
        /**
        * Remove the given portal from this sector.
        */
        virtual void RemovePortal (iPortal* portal);
    
        /**
        * Set the engine iSector related to this collison sector. The iMovable that are 
        * attached to a iCollisionObject present in this collision sector will be put automatically in the given engine sector.
        */
        virtual void SetSector (iSector* sector) = 0;
    
        /**
        * Get the engine iSector related to this collison sector.
        */
        virtual iSector* GetSector () = 0;
    
        /**
        * Follow a beam from start to end and return the first body that is hit.
        */
        virtual HitBeamResult HitBeam (
            const csVector3& start, const csVector3& end) = 0;
    
        /**
        * Follow a beam from start to end and return the first body that is hit.
        */
        //Lulu: What's this? return the first portal that is hit? Or cast a ray from a portal?
        // see iSector::HitBeam/HitBeamPortal: the first won't cross the portals, the second will
        virtual HitBeamResult HitBeamPortal (
            const csVector3& start, const csVector3& end) = 0;
    
        /**
        * Performs a discrete collision test against all objects in this iCollisionSector.
        * it reports one or more contact points for every overlapping object
        */
        virtual bool CollisionTest (iCollisionObject* object, csArray<CollisionData>& collisions) = 0;
    
        /**
        * Try to move the given object from \a fromWorld to \a toWorld and return the first collision occured if any.
        */
        // kickvb: a test only on convex colliders is probably not interesting, so remove this method if not possible to do on any collision object
        //virtual MoveResult MoveTest (iCollisionObject* object, const csOrthoTransform& fromWorld, const csOrthoTransform& toWorld) = 0;
    };
    
    /**
    * This is the Collision plug-in. This plugin is a factory for creating
    * iCollider, iCollisionObject, iCollisionSector and iCollisionActor
    * entities. 
    *
    * Main creators of instances implementing this interface:
    * - OPCODE plugin (crystalspace.collisiondetection.opcode)
    * - Bullet plugin (crystalspace.dynamics.bullet)
    *
    * Main ways to get pointers to this interface:
    * - csQueryRegistry()
    */
    struct iCollisionSystem : public virtual iBase
    {
        SCF_INTERFACE (CS::Collision::iCollisionSystem, 2, 2, 2);
    
        /**
        * Create a convex mesh collider.
        */
        virtual csPtr<iColliderConvexMesh> CreateColliderConvexMesh (iMeshWrapper* mesh) = 0;
    
        /**
        * Create a concave mesh collider.
        */
        virtual csPtr<iColliderConcaveMesh> CreateColliderConcaveMesh 
            (iMeshWrapper* mesh) = 0;
    
        /**
        * Create a scaled concave mesh collider.
        */
        virtual csPtr<iColliderConcaveMeshScaled> CreateColliderConcaveMeshScaled
         (iColliderConcaveMesh* collider, float scale) = 0;
    
        /**
        * Create a cylinder collider.
        */
        virtual csPtr<iColliderCylinder> CreateColliderCylinder (float length, float radius) = 0;
    
        /**
        * Create a box collider.
        */
        virtual csPtr<iColliderBox> CreateColliderBox (const csVector3& size) = 0;
    
        /**
        * Create a sphere collider.
        */
        virtual csPtr<iColliderSphere> CreateColliderSphere (float radius) = 0;
    
        /**
        * Create a capsule collider.
        */
        virtual csPtr<iColliderCapsule> CreateColliderCapsule (float length, float radius) = 0;
    
        /**
        * Create a plane collider.
        */
        virtual csPtr<iColliderPlane> CreateColliderPlane (const csPlane3& plain) = 0;
    
        /**
        * Create a terrain collider.
        */
        virtual csPtr<iColliderTerrain> CreateColliderTerrain (const iTerrainSystem* terrain,
            float minHeight = 0, float maxHeight = 0) = 0;
    
        /**
        * Create a collision object. Without any initialization.
        * Need to call iCollisionObject::RebuildObject.
        */
        virtual csPtr<iCollisionObject> CreateCollisionObject (
            CollisionObjectType type = COLLISION_OBJECT_BASE) = 0;
    
        /**
        * Decompose a concave mesh in convex parts. Each convex part will be added to
        * the collision object as a separate iColliderConvexMesh.
        */
        virtual void DecomposeConcaveMesh (iCollisionObject* object, iMeshWrapper* mesh) = 0;
    
        /**
        * Create a collision actor.
        * Need to call iCollisionObject::RebuildObject.
        */
        virtual csPtr<iCollisionActor> CreateCollisionActor () = 0;
        
        /**
        * Create a collision group.
        */
        virtual CollisionGroup& CreateCollisionGroup (const char* name) = 0;
    
        /**
        * Find a collision group by name.
        */
        virtual CollisionGroup& FindCollisionGroup (const char* name) = 0;
    
        virtual void SetGroupCollision (CollisionGroup& group1,
            CollisionGroup& group2, bool collide) = 0;
    
        virtual bool GetGroupCollision (CollisionGroup& group1,
            CollisionGroup& group2) = 0;
    
        /**
        * Create a collision sector.
        */
        virtual csPtr<iCollisionSector> CreateCollisionSector () = 0;
    };
    }
    }
    
    #endif
    
  • physical.h
    #ifndef __IVARIA_PHYSICS_H__
    #define __IVARIA_PHYSICS_H__
    
    namespace CS
    {
    namespace Collision
    {
    
    struct iCollisionCallback;
    struct iCollisionObject;
    struct CollisionGroup;
    struct iCollisionObject;
    
    }
    }
    
    namespace CS
    {
    namespace Physics
    {
    
    struct iJoint;
    struct iObject;
    struct iRigidBody;
    struct iSoftBody;
    struct iKinematicCallback;
    struct iPhysicalSystem;
    
    enum PhysicalBodyType
    {
        BODY_RIGID = 0,
        BODY_SOFT
    };
    
    enum RigidBodyState
    {
        STATE_STATIC = 0,
        STATE_DYNAMIC,
        STATE_KINEMATIC
    };
    /*
    enum JointType
    {
        JOINT_P2P;
        JOINT_CONETWIST;
        JOINT_6DOF;
        JOINT_SPRING;
    };
    
    struct iJointHelper : public virtual iBase
    {
        SCF_INTERFACE (CS::Physics::iJointHelper ,1, 0, 0);
    
        virtual csPtr<iJoint> CreateP2PJoint ();
    
        virtual csPtr<iJoint> CreateConeTwistJoint ();
    
        virtual csPtr<iJoint> Create6DOFJoint ();
    
        virtual csPtr<iJoint> CreateSpringJoint ();
    };
    */
    
    /**
    * A base interface of physical bodies. 
    * iRigidBody and iSoftBody will be derived from this one.
    */
    struct iPhysicalBody : public virtual iCollisionObject
    {
        SCF_INTERFACE (CS::Physics::iPhysicalBody, 1, 0, 0);
    
        virtual PhysicalBodyType GetType () const = 0;
    
        virtual iRigidBody* QueryRigidBody () = 0;
    
        virtual iSoftBody* QuerySoftBody () = 0;
    
        /**
        * Disable this collision object.
        */
        virtual bool Disable () = 0;
    
        /**
        * Enable this collision object.
        */
        virtual bool Enable () = 0;
    
        /**
        * Check if the collision object is enabled.
        */
        virtual bool isEnabled () = 0;
    
        // move "virtual iRigidBody::RigidBodyState GetState () = 0;" here and implement it for soft bodies by switching to rigid bodies when static/dynamic?
        //Lulu: If soft body can switch to rigid body, what about the parameters? Dose user have to call functions to set the parameters of rigid body? 
        //      If iPhysicalSystem create a new rigidbody, it's based on the softbody's current shape or original shape? 
        //      And the collision system will create a collision shape for the mesh? How to decide which type of collider is appropriate?
    
        /**
        * Get the mass of this body.
        */
        virtual float GetMass () const = 0;
    
        /**
        * Set the mass of this body.
        */
        virtual void SetMass (float mass) = 0;
    
        virtual float GetDensity () const = 0;
    
        virtual void SetDensity (float density) = 0;
    
        /**
        * Return the volume of this body.
        */
        virtual float GetVolume () = 0;
    
        // AddForce/Torque? Velocities? 
        //Lulu: soft body doesn't support AddTorque.
        
        /**
        * Add a force to the whole body.
        */
        virtual void AddForce (const csVector3& force) = 0;
        
        /**
        * Set the linear velocity (movement).
        */
        virtual void SetLinearVelocity (const csVector3& vel) = 0;
        
        /**
        * Get the linear velocity (movement).
        */
        virtual csVector3 GetLinearVelocity (size_t index = 0) const = 0;
    
        /**
        * Set the friction of this body.
        * [0,1] for soft body.
        */
        virtual void SetFriction (float friction) = 0;
    
        /**
        * Get the friction of this rigid body.
        */
        virtual void GetFriction (float& friction) = 0;
    }
    
    /**
    * This is the interface for a rigid body.
    * It keeps all properties for the body.
    * It can also be attached to a movable or a bone,
    * to automatically update it.
    *
    * Main creators of instances implementing this interface:
    * - iPhysicalSystem::CreateRigidBody()
    * 
    * Main ways to get pointers to this interface:
    * - iPhysicalSystem::GetRigidBody()
    * 
    * Main users of this interface:
    * - iPhysicalSystem
    *
    * \sa iSoftBody
    */
    struct iRigidBody : public iPhysicalBody
    {
        SCF_INTERFACE (CS::Physics::iRigidBody, 1, 0, 2);
    
        /**
        * Get the iCollisionObject pointer of this body.
        */
        virtual iCollisionObject* QueryCollisionObject () = 0;
    
        /**
        * Get the current state of the body.
        */
        virtual RigidBodyState GetState () = 0;
        
        /**
        * Set the current state of the body.
        */
        virtual void SetState (RigidBodyState state) = 0;
    
        /**
        * Set the elasticity of this rigid body.
        */
        virtual void SetElasticity (float elasticity) = 0;
    
        /**
        * Get the elasticity of this rigid body.
        */
        virtual void GetElasticity (float elasticity) = 0;
    
        /**
        * Set the angular velocity (rotation).
        */
        virtual void SetAngularVelocity (const csVector3& vel) = 0;
    
        /**
        * Get the angular velocity (rotation)
        */
        virtual csVector3 GetAngularVelocity () const = 0;
    
        /**
        * Add a torque (world space) (active for one timestep).
        */
        virtual void AddTorque (const csVector3& force) = 0;
    
        /**
        * Add a force (local space) (active for one timestep).
        */
        virtual void AddRelForce (const csVector3& force) = 0;
    
        /**
        * Add a torque (local space) (active for one timestep).
        */
        virtual void AddRelTorque (const csVector3& force) = 0;
    
        /**
        * Add a force (world space) at a specific position (world space)
        * (active for one timestep)
        */
        virtual void AddForceAtPos (const csVector3& force,
            const csVector3& pos) = 0;
    
        /**
        * Add a force (world space) at a specific position (local space)
        * (active for one timestep)
        */
        virtual void AddForceAtRelPos (const csVector3& force,
            const csVector3& pos) = 0;
    
        /**
        * Add a force (local space) at a specific position (world space)
        * (active for one timestep)
        */
        virtual void AddRelForceAtPos (const csVector3& force,
            const csVector3& pos) = 0;
    
        /**
        * Add a force (local space) at a specific position (local space)
        * (active for one timestep)
        */
        virtual void AddRelForceAtRelPos (const csVector3& force,
            const csVector3& pos) = 0;
    
        /**
        * Get total force (world space).
        */
        virtual csVector3 GetForce () const = 0;
    
        /**
        * Get total torque (world space).
        */
        virtual csVector3 GetTorque () const = 0;
    
        /**
        * Set the callback to be used to update the transform of the kinematic body.
        * If no callback are provided then the dynamic system will use a default one.
        */
        virtual void SetKinematicCallback (iKinematicCallback* cb) = 0;
    
        /**
        * Get the callback used to update the transform of the kinematic body.
        */
        virtual iKinematicCallback* GetKinematicCallback () = 0;
    
        /**
        * Set the linear dampener for this rigid body. The dampening correspond to
        * how much the movements of the objects will be reduced. It is a value
        * between 0 and 1, giving the ratio of speed that will be reduced
        * in one second. 0 means that the movement will not be reduced, while
        * 1 means that the object will not move.
        * The default value is 0.
        * \sa iDynamicSystem::SetLinearDampener()
        */
        virtual void SetLinearDampener (float d) = 0;
    
        /**
        * Get the linear dampener for this rigid body.
        */
        virtual float GetLinearDampener () = 0;
    
        /**
        * Set the angular dampener for this rigid body. The dampening correspond to
        * how much the movements of the objects will be reduced. It is a value
        * between 0 and 1, giving the ratio of speed that will be reduced
        * in one second. 0 means that the movement will not be reduced, while
        * 1 means that the object will not move.
        * The default value is 0.
        * \sa iDynamicSystem::SetRollingDampener()
        */
        virtual void SetRollingDampener (float d) = 0;
    
        /**
        * Get the angular dampener for this rigid body.
        */
        virtual float GetRollingDampener () = 0;
    };
    
    /**
    * A soft body is a physical body that can be deformed by the physical
    * simulation. It can be used to simulate eg ropes, clothes or any soft
    * volumetric object.
    *
    * A soft body does not have a positional transform by itself, but the
    * position of every vertex of the body can be queried through GetVertexPosition().
    *
    * A soft body can neither be static or kinematic, it is always dynamic.
    * \sa iRigidBody 
    */
    struct iSoftBody : public iPhysicalBody
    {
        SCF_INTERFACE (CS::Physics::iSoftBody, 2, 0, 3);
    
        /**
        * Set the mass of a node by index.
        */
        virtual void SetVertexMass (float mass, size_t index) = 0;
    
        /**
        * Get the mass of a node by index.
        */
        virtual float GetVertexMass (size_t index) = 0;
    
        /**
        * Return the count of vertices of this soft body.
        */
        virtual size_t GetVertexCount () = 0;
    
        /**
        * Return the position in world coordinates of the given vertex.
        */
        virtual csVector3 GetVertexPosition (size_t index) const = 0;
    
        /**
        * Anchor the given vertex to its current position. This vertex will no more move.
        */
        virtual void AnchorVertex (size_t vertexIndex) = 0;
    
        /**
        * Anchor the given vertex to the given rigid body. The relative position of the
        * vertex and the body will remain constant.
        */
        virtual void AnchorVertex (size_t vertexIndex,
            iRigidBody* body) = 0;
    
        /**
        * Anchor the given vertex to the given controller. The relative position of the
        * vertex and the controller will remain constant.
        */
        virtual void AnchorVertex (size_t vertexIndex,
            iAnchorAnimationControl* controller) = 0;
    
        /**
        * Update the position of the anchor of the given vertex relatively to the anchored
        * rigid body. This can be used to have a finer control of the anchor position
        * relatively to the rigid body.
        *
        * This would work only if you called AnchorVertex (size_t,iRigidBody*) before.
        * The position to be provided is in world coordinates.
        *
        * \warning The stability of the simulation can be lost if you move the position too far
        * from the previous position.
        * \sa CS::Animation::iSoftBodyAnimationControl::CreateAnimatedMeshAnchor ()
        */
        virtual void UpdateAnchor (size_t vertexIndex,
            csVector3& position) = 0;
    
        /**
        * Remove the given anchor. This won't work if you anchored the vertex to a rigid body, due
        * to a limitation in the Bullet library.
        */
        virtual void RemoveAnchor (size_t vertexIndex) = 0;
    
        /**
        * Set the rigidity of this body. The value should be in the 0 to 1 range, with
        * 0 meaning soft and 1 meaning rigid.
        */
        virtual void SetRigidity (float rigidity) = 0;
    
        /**
        * Get the rigidity of this body.
        */
        virtual float GetRidigity () = 0;
    
        /**
        * Set the linear velocity of the given vertex of the body.
        */
        virtual void SetLinearVelocity (const csVector3& velocity,
            size_t vertexIndex) = 0;
    
        /**
        * Set the wind velocity of the whole body.
        */
        // kickvb: in iPhysicalSector instead?
        virtual void SetWindVelocity (const csVector3& velocity) = 0;
    
        /**
        * Get the wind velocity of the whole body.
        */
        virtual const csVector3& GetWindVelocity () const = 0;
    
        /**
        * Add a force at the given vertex of the body.
        */
        virtual void AddForce (const csVector3& force, size_t vertexIndex) = 0;
    
        /**
        * Return the count of triangles of this soft body.
        */
        virtual size_t GetTriangleCount () = 0;
    
        /**
        * Return the triangle with the given index.
        */
        virtual csTriangle GetTriangle (size_t index) const = 0;
    
        /**
        * Return the normal vector in world coordinates for the given vertex.
        */
        virtual csVector3 GetVertexNormal (size_t index) const = 0;
    
        /**
        * Currently Blender set this to 0 when creating a soft body.
        * Used to create a btTriangleMesh for soft body.
        */
        //virtual void SetWelding (float welding) = 0;
    };
    
    /**
    * A joint that can constrain the relative motion between two iRigidBody.
    * For instance if all motion in along the local X axis is constrained
    * then the bodies will stay motionless relative to each other
    * along an x axis rotated and positioned by the joint's transform.
    *
    * Main creators of instances implementing this interface:
    * - iPhysicalSystem::CreateJoint()
    * 
    * Main users of this interface:
    * - iPhysicalSystem
    */
    struct iJoint : public virtual iBase
    {
        SCF_INTERFACE (CS::Physics::iJoint, 1, 0, 0);
    
        /**
        * Set the rigid bodies that will be affected by this joint. Set force_update to true if 
        * you want to apply the changes right away.
        */
        virtual void Attach (iPhysicalBody* body1, iPhysicalBody* body2,
            const csOrthoTransform& trans1,
            const csOrthoTransform& trans2,
            bool forceUpdate = true) = 0;
    
        /**
        * Get the attached body with the given index (valid values for body are 0 and 1).
        */
        virtual iPhysicalBody* GetAttachedBody (int index) = 0;
    
        /**
        * Set the local transformation of the joint.
        *
        * Set force_update to true if you want to apply the changes right away.
        */
        virtual void SetTransform (const csOrthoTransform& trans,
            bool forceUpdate = true) = 0;
    
        /**
        * Get the local transformation of the joint.
        */
        virtual csOrthoTransform GetTransform () const = 0;
    
        /**
        * Set the new position of the joint, in world coordinates.
        */
        virtual void SetPosition (const csVector3& position) = 0;
    
        /**
        * Get the current position of the joint, in world coordinates.
        */
        virtual csVector3 GetPosition () const = 0;
    
        /**
        * Set the translation constraints on the 3 axes. If true is
        * passed for an axis then the Joint will constrain all motion along
        * that axis (ie no motion will be allowed). If false is passed in then all motion along that
        * axis is free, but bounded by the minimum and maximum distance
        * if set. Set force_update to true if you want to apply the changes 
        * right away.
        */
        virtual void SetTransConstraints (bool X, 
            bool Y, bool Z, 
            bool forceUpdate = true) = 0;
    
        /**
        * True if this axis' translation is constrained.
        */
        virtual bool IsXTransConstrained () = 0;
    
        /**
        * True if this axis' translation is constrained.
        */
        virtual bool IsYTransConstrained () = 0;
    
        /**
        * True if this axis' translation is constrained.
        */
        virtual bool IsZTransConstrained () = 0;
    
        /**
        * Set the minimum allowed distance between the two bodies. Set force_update to true if 
        * you want to apply the changes right away.
        */
        virtual void SetMinimumDistance (const csVector3& dist,
            bool forceUpdate = true) = 0;
    
        /**
        * Get the minimum allowed distance between the two bodies.
        */
        virtual csVector3 GetMinimumDistance () const = 0;
    
        /**
        * Set the maximum allowed distance between the two bodies. Set force_update to true if 
        * you want to apply the changes right away.
        */
        virtual void SetMaximumDistance (const csVector3& dist,
            bool forceUpdate = true) = 0;
    
        /**
        * Get the maximum allowed distance between the two bodies.
        */
        virtual csVector3 GetMaximumDistance () const = 0;
    
        /**
        * Set the rotational constraints on the 3 axes. If true is
        * passed for an axis then the Joint will constrain all rotation around
        * that axis (ie no motion will be allowed). If false is passed in then all rotation around that
        * axis is free, but bounded by the minimum and maximum angle
        * if set. Set force_update to true if you want to apply the changes 
        * right away.
        */
        virtual void SetRotConstraints (bool X, 
            bool Y, bool Z, 
            bool forceUpdate = true) = 0;
    
        /**
        * True if this axis' rotation is constrained.
        */
        virtual bool IsXRotConstrained () = 0;
    
        /**
        * True if this axis' rotation is constrained.
        */
        virtual bool IsYRotConstrained () = 0;
    
        /**
        * True if this axis' rotation is constrained.
        */
        virtual bool IsZRotConstrained () = 0;
    
        /**
        * Set the minimum allowed angle between the two bodies, in radian. Set force_update to true if 
        * you want to apply the changes right away.
        */
        virtual void SetMinimumAngle (const csVector3& angle,
            bool forceUpdate = true) = 0;
    
        /**
        * Get the minimum allowed angle between the two bodies (in radian).
        */
        virtual csVector3 GetMinimumAngle () const = 0;
    
        /**
        * Set the maximum allowed angle between the two bodies (in radian). Set force_update to true if 
        * you want to apply the changes right away.
        */
        virtual void SetMaximumAngle (const csVector3& dist,
            bool forceUpdate = true) = 0;
    
        /**
        * Get the maximum allowed angle between the two bodies (in radian).
        */
        virtual csVector3 GetMaximumAngle () const = 0;
    
        /** 
        * Set the restitution of the joint's stop point (this is the 
        * elasticity of the joint when say throwing open a door how 
        * much it will bounce the door back closed when it hits).
        */
        virtual void SetBounce (const csVector3& bounce,
            bool forceUpdate = true) = 0;
    
        /**
        * Get the joint restitution.
        */
        virtual csVector3 GetBounce () const = 0;
    
        /**
        * Apply a motor velocity to joint (for instance on wheels). Set force_update to true if 
        * you want to apply the changes right away.
        */
        virtual void SetDesiredVelocity (const csVector3& velo,
            bool forceUpdate = true) = 0;
    
        /**
        * Get the desired velocity of the joint motor.
        */
        virtual csVector3 GetDesiredVelocity () const = 0;
    
        /**
        * Set the maximum force that can be applied by the joint motor to reach the desired velocity.
        * Set force_update to true if  you want to apply the changes right away.
        */
        virtual void SetMaxForce (const csVector3& force,
            bool forceUpdate = true) = 0;
    
        /**
        * Get the maximum force that can be applied by the joint motor to reach the desired velocity.
        */
        virtual csVector3 GetMaxForce () const = 0;
    
        /**
        * Set a custom angular constraint axis (have sense only with rotation free minimum along 2 axis).
        * Set force_update to true if you want to apply the changes right away.
        */
        virtual void SetAngularConstraintAxis (const csVector3& axis,
            bool forceUpdate = true) = 0;
    
        /**
        * Get the custom angular constraint axis.
        */
        virtual csVector3 GetAngularConstraintAxis () const = 0;
    
        /**
        * Rebuild the joint using the current setup. Return true if the rebuilding operation was successful
        * (otherwise the joint won't be active).
        */
        virtual bool RebuildJoint () = 0;
    
        /**
        * Set the spring constraints on the 3 axes. If true is
        * passed for an axis then the Joint will have a spring constraint on
        * that axis. If false is passed in then no spring constraint on the
        * axis. Set force_update to true if you want to apply the changes 
        * right away.
        */
        virtual void SetSpringConstraints (bool X, 
            bool Y, bool Z, 
            bool forceUpdate = true) = 0;
    
        /**
        * True if this axis has a spring constraint.
        */
        virtual bool IsXSpringConstrained () = 0;
    
        /**
        * True if this axis has a spring constraint.
        */
        virtual bool IsYSpringConstrained () = 0;
    
        /**
        * True if this axis has a spring constraint.
        */
        virtual bool IsZSpringConstrained () = 0;
    
        /**
        * Set the stiffness of the spring.
        */
        virtual void SetStiffness (float stiff) = 0;
    
        /**
        * Set the damping of the spring.
        */
        virtual void SetDamping (float damp) = 0;
    
        /**
        * Set the current constraint position/orientation as an equilibrium point.
        * If index = -1, then set equilibrium point for all DOF, else set it for given DOF.
        */
        virtual void SetEquilibriumPoint (int index = -1);
        
        /**
        * Set the value to an equilibrium point for given DOF.
        */
        virtual void SetEquilibriumPoint (int index, float value);
    
        virtual void SetBreakingImpulseThreshold (float threshold) = 0;
    
        virtual float GetBreakingImpulseThreshold () = 0;
    };
    
    struct iPhysicalSystem : public virtual iBase
    {
        SCF_INTERFACE (CS::Physics::iPhysicalSystem, 1, 0, 0);
    
        /**
        * Create a rigid body, if there's an iCollisionObject pointer, 
        * Need to call iCollisionObject::RebuildObject.
        */
        virtual csPtr<iRigidBody> CreateRigidBody () = 0;
    
        /**
        * Create a joint and add it to the simulation.
        */
        virtual csPtr<iJoint> CreateJoint () = 0;
    
        /**
        * Create a soft body rope.
        * \param start Start position of the rope.
        * \param end End position of the rope.
        * \param segmentCount Number of segments in the rope.
        * \remark You must call SetSoftBodyWorld() prior to this.
        */
        virtual iSoftBody* CreateRope (csVector3 start,
            csVector3 end, size_t segmentCount) = 0;
    
        /**
        * Create a soft body rope with explicit positions of the vertices.
        * \param vertices The array of positions to use for the vertices.
        * \param vertexCount The amount of vertices for the rope.
        * \remark You must call SetSoftBodyWorld() prior to this.
        */
        virtual iSoftBody* CreateRope (csVector3* vertices, size_t vertexCount) = 0;
    
        /**
        * Create a soft body cloth.
        * \param corner1 The position of the top left corner.
        * \param corner2 The position of the top right corner.
        * \param corner3 The position of the bottom left corner.
        * \param corner4 The position of the bottom right corner.
        * \param segmentCount1 Number of horizontal segments in the cloth.
        * \param segmentCount2 Number of vertical segments in the cloth.
        * \param withDiagonals Whether there must be diagonal segments in the cloth
        * or not. Diagonal segments will make the cloth more rigid.
        * \remark You must call SetSoftBodyWorld() prior to this.
        */
        virtual iSoftBody* CreateCloth (csVector3 corner1, csVector3 corner2,
            csVector3 corner3, csVector3 corner4,
            size_t segmentCount1, size_t segmentCount2,
            bool withDiagonals = false) = 0;
    
        /**
        * Create a volumetric soft body from a genmesh.
        * \param genmeshFactory The genmesh factory to use.
        * \param if there's an iCollisionObject pointer, attach the iCollisionObject to it.
        * \remark You must call SetSoftBodyWorld() prior to this.
        */
        virtual csPtr<iSoftBody> CreateSoftBody (iGeneralFactoryState* genmeshFactory) = 0;
    
        /**
        * Create a custom volumetric soft body.
        * \param vertices The vertices of the soft body. The position is absolute.
        * \param vertexCount The count of vertices of the soft body.
        * \param triangles The faces of the soft body.
        * \param triangleCount The count of faces of the soft body.
        \param if there's an iCollisionObject pointer, attach the iCollisionObject to it.
        * \remark You must call SetSoftBodyWorld() prior to this.
        */
        virtual csPtr<iSoftBody> CreateSoftBody (csVector3* vertices,
            size_t vertexCount, csTriangle* triangles,
            size_t triangleCount) = 0;
    };
    
    struct iPhysicalSector : public virtual iBase
    {
        SCF_INTERFACE (CS::Physics::iPhysicalSector, 1, 0, 0);
    
        /**
        * Set the simulation speed. A value of 0 means that the simulation is not made
        * automatically (but it can still be made manually through Step())
        */
        virtual void SetSimulationSpeed (float speed) = 0;
    
        /**
        * Step the simulation forward by the given duration, in second
        */
        virtual void Step (float duration) = 0;
    
        /**
        * Set the global linear dampener. The dampening correspond to how
        * much the movements of the objects will be reduced. It is a value
        * between 0 and 1, giving the ratio of speed that will be reduced
        * in one second. 0 means that the movement will not be reduced, while
        * 1 means that the object will not move.
        * The default value is 0.
        * \sa CS::Physics::Bullet::iRigidBody::SetLinearDampener()
        */
        virtual void SetLinearDampener (float d) = 0;
    
        /**
        * Get the global linear dampener setting.
        */
        virtual float GetLinearDampener () const = 0;
    
        /**
        * Set the global angular dampener. The dampening correspond to how
        * much the movements of the objects will be reduced. It is a value
        * between 0 and 1, giving the ratio of speed that will be reduced
        * in one second. 0 means that the movement will not be reduced, while
        * 1 means that the object will not move.
        * The default value is 0.
        * \sa CS::Physics::Bullet::iRigidBody::SetRollingDampener()
        */
        virtual void SetRollingDampener (float d) = 0;
    
        /**
        * Get the global rolling dampener setting.
        */
        virtual float GetRollingDampener () const = 0;
    
        /**
        * Turn on/off AutoDisable functionality.
        * AutoDisable will stop moving objects if they are stable in order
        * to save processing time. By default this is enabled.
        */
        // always enabled?
        //virtual void EnableAutoDisable (bool enable) = 0;
       
        /**
        * Return whether the AutoDisable is on or off.
        */
        //virtual bool AutoDisableEnabled () = 0;
        
        /**
        * Set the parameters for AutoDisable.
        * \param linear Maximum linear movement to disable a body. Default value is 0.8.
        * \param angular Maximum angular movement to disable a body. Default value is 1.0.
        * \param steps Minimum number of steps the body meets linear and angular
        * requirements before it is disabled. Default value is 0.
        * \param time Minimum time the body needs to meet linear and angular
        * movement requirements before it is disabled. Default value is 0.0.
        * \remark With the Bullet plugin, the 'steps' parameter is ignored.
        * \remark With the Bullet plugin, calling this method will not affect bodies already
        * created.
        */
        virtual void SetAutoDisableParams (float linear, float angular, int steps,
            float time) = 0;
    
        /**
        * Add a rigid body into the sector.
        * The rigid body has to be initialized.
        */
        virtual void AddRidigBody (iRigidBody* body) = 0;
    
        /**
        * Remove a rigid body by pointer.
        */
        virtual void RemoveRigidBody (iRigidBody* body) = 0;
    
        /**
        * Add a soft body into the sector.
        */
        virtual void AddSoftBody (iSoftBody* body) = 0;
    
        /**
        * Remove a soft body by pointer.
        */
        virtual void RemoveSoftBody (iSoftBody* body) = 0;
    
        virtual void SetStepParameters (float timeStep, size_t maxSteps,
            size_t iterations) = 0;
    };
    }
    }
    #endif
    
  • bullet.h
    #ifndef __IVARIA_PHYSICS_BULLET_H__
    #define __IVARIA_PHYSICS_BULLET_H__
    
    namespace CS
    {
    namespace Physics
    {
    namespace Bullet
    {
    
    enum DebugMode
    {
        DEBUG_NOTHING = 0,     /*!< Nothing will be displayed. */
        DEBUG_COLLIDERS = 1,   /*!< Display the colliders of the bodies. */
        DEBUG_AABB = 2,        /*!< Display the axis aligned bounding boxes of the bodies. */
        DEBUG_JOINTS = 4       /*!< Display the joint positions and limits. */
    };
    
    struct iSoftBody : public virtual iBase
    {
        SCF_INTERFACE (CS::Physics::Bullet::iSoftBody, 1, 0, 0);
    
        /**
        * Draw the debug informations of this soft body. This has to be called
        * at each frame, and will add 2D lines on top of the rendered scene.
        */
        virtual void DebugDraw (iView* rView) = 0;
    
        /// Set linear stiffness coefficient [0,1].
        virtual void SetLinearStiff (float stiff) = 0;
    
        /// Set area/angular stiffness coefficient [0,1].
        virtual void SetAngularStiff (float stiff) = 0;
    
        /// Set volume stiffness coefficient [0,1].
        virtual void SetVolumeStiff (float vol) = 0;
    
        /// Reset the collision flag to 0.
        virtual void ResetCollisionFlag () = 0;
    
        /// Set true if use cluster vs convex handling for rigid vs soft collision detection.
        virtual void SetClusterCollisionRS (bool cluster) = 0;
    
        /// Set true if use cluster vs cluster handling for soft vs soft collision detection.
        virtual void SetClusterCollisionSS (bool cluster) = 0;
    
        /// Set soft vs rigid hardness [0,1] (cluster only).
        virtual void SetSRHardness (float hardness) = 0;
    
        /// Set soft vs kinetic hardness [0,1] (cluster only).
        virtual void SetSKHardness (float hardness) = 0;
    
        /// Set soft vs soft hardness [0,1] (cluster only).
        virtual void SetSSHardness (float hardness) = 0;
    
        /// Set soft vs rigid impulse split [0,1] (cluster only).
        virtual void SetSRImpulse (float impulse) = 0;
    
        /// Set soft vs rigid impulse split [0,1] (cluster only).
        virtual void SetSKImpulse (float impulse) = 0;
    
        /// Set soft vs rigid impulse split [0,1] (cluster only).
        virtual void SetSSImpulse (float impulse) = 0;
    
        /// Set velocities correction factor (Baumgarte).
        virtual void SetVeloCorrectionFactor (float factor) = 0;
    
        /// Set damping coefficient [0,1].
        virtual void SetDamping (float damping) = 0;
    
        /// Set drag coefficient [0,+inf].
        virtual void SetDrag (float drag) = 0;
    
        /// Set lift coefficient [0,+inf].
        virtual void SetLift (float lift) = 0;
    
        /// Set pressure coefficient [-inf,+inf].
        virtual void SetPressure (float pressure) = 0;
    
        /// Set volume conversation coefficient [0,+inf].
        virtual void SetVolumeConversationCoefficient (float conversation) = 0;
    
        /// Set pose matching coefficient [0,1].	
        virtual void SetShapeMatchThreshold (float matching) = 0;
    
        /// Set rigid contacts hardness [0,1].
        virtual void SetRContactsHardness (float hardness) = 0;
    
        /// Set kinetic contacts hardness [0,1].
        virtual void SetKContactsHardness (float hardness) = 0;
    
        /// Set soft contacts hardness [0,1].
        virtual void SetSContactsHardness (float hardness) = 0;
    
        /// Set anchors hardness [0,1].
        virtual void SetAnchorsHardness (float hardness) = 0;
    
        /// Set velocities solver iterations.
        virtual void SetVeloSolverIterations (int iter) = 0;
    
        /// Set positions solver iterations.
        virtual void SetPositionIterations (int iter) = 0;
    
        /// Set drift solver iterations.
        virtual void SetDriftIterations (int iter) = 0;
    
        /// Set cluster solver iterations.
        virtual void SetClusterIterations (int iter) = 0;
    
        /// Set true if use pose matching.
        virtual void SetShapeMatching (bool match) = 0;
    
        /**
        * Configure the soft body with parameters set above.
        * If bending constraint is used set it with true.
        */
        //virtual void ConfigureSoftBody (bool bending) = 0;
    };
    
    struct iPhysicalSystem : public virtual iBase
    {
        SCF_INTERFACE (CS::Physics::Bullet::iPhysicalSystem, 1, 0, 0);
    
        virtual void StartProfile () = 0;
    
        virtual void StopProfile () = 0;
    
        virtual void DumpProfile (bool resetProfile = true) = 0;
    };
    
    struct iPhysicalSector : public virtual iBase
    {
        SCF_INTERFACE (CS::Physics::Bullet::iPhysicalSector, 1, 0, 0);
    
        /**
        * Set whether this dynamic world can handle soft bodies or not.
        * \warning You have to call this method before adding any objects in the
        * dynamic world.
        */
        virtual void SetSoftBodyEnabled (bool enabled) = 0;
    
        /**
        * Return whether this dynamic world can handle soft bodies or not.
        */
        virtual bool GetSoftBodyEnabled () = 0;
    
        virtual void SetGimpactEnabled (bool enabled) = 0;
        virtual bool GetGimpactEnabled () = 0;
    
        /**
        * Save the current state of the dynamic world in a file.
        * \return True if the operation succeeds, false otherwise.
        */
        virtual void SaveWorld (const char* filename) = 0;
    
        /**
        * Draw the debug informations of the dynamic system. This has to be called
        * at each frame, and will add 2D lines on top of the rendered scene. The
        * objects to be displayed are defined by SetDebugMode().
        */
        // probably Bullet specific -> CS::Physics::Bullet::iPhysicalSector
        //Lulu: PhysX supports Debug Rendering. And Havok has a Visual Debugger, but it's client/server architecture. It's quite different from Bullet. 
        //      I don't know how to implement visual debugger using these API. Should I move these to Bullet namespace?
        // kickvb: let's see that later
        virtual void DebugDraw (iView* rview) = 0;
    
        /**
        * Set the mode to be used when displaying debug informations. The default value
        * is 'CS::Physics::Bullet::DEBUG_COLLIDERS | CS::Physics::Bullet::DEBUG_JOINTS'.
        * \remark Don't forget to call DebugDraw() at each frame to effectively display
        * the debug informations.
        */
        virtual void SetDebugMode (DebugMode mode) = 0;
    
        /**
        * Get the current mode used when displaying debug informations.
        */
        virtual DebugMode GetDebugMode () = 0;  
    };
    
    }
    }
    }
    #endif
    

Example of use

  • the creation of the plugin gives an iCollisionSystem object. If this is the Bullet plugin then this object also implements the iPhysicalSystem interface.
  • the user uses the iCollisionSystem interface to create one or more iCollisionSector's and portals connecting them. If this is the Bullet plugin then the sectors also implements the iPhysicalSector interface.
  • creation of an object: either through iCollisionSystem for ghost/actor/static collider objects, or through iPhysicalSystem for rigid or soft bodies.
  • create colliders through the iCollisionSystem interface and add them to the body. Use the specific object interface to setup the remaining properties.
  • call iCollisionObject::RebuildObject () to apply all changes
  • add the object in a iCollisionSector, now it is active

Ideas & open questions

  • Remove all collision stuff from terrain2. This should go in the iColliderTerrain class.
  • Add an higher-level plugin iCollisionManager: mapping a mesh factory/portal to a iCollisionObject/iCollisionPortal + building a iCollisionSector from a iSector + building a collision world from the engine content

-> how to keep it in sync with the engine content? Either iEngine needs the addition of callbacks for sector/mesh/portal added/removed, or the user would have to add/position meshes using the collision manager and no more the engine