Simple Physics Engine SPE Simplified Chinese

Home Download License Document FeedBack Forum

What's new in SPE SDK 3.00
  • New interface ISPEPhysicsState and ISPEConstraint and ISPEContact to access the new solver and building custom joints.
  • New APIs for Physics Filter in ISPERigidBody and ISPEWorld.
  • New Individual APIs for detect collisions for characters etc. in ISPEWorld.
  • ISPEShape::SetMassCenter() avaible now to move the center of mass after shape been initialized.
  • Old ISPERigidBody::SetPosition()/SetOrientation() changed to SetPositionMesh()/SetOrientationMesh() which are refer to mesh frame, and current SetPosition()/SetOrientation() are refer to the center of mass(body frame). Set/GetTransform() also changed to Set/GetTransformMesh().
  • Remove the functions use single float as parameters like SetPosition(float x, float y, float z) in ISPERigidBody and ISPEParticle.
  • New APIs to access the sleep status of rigid body: SetSleeping(), GetSleeping(), SetSleepFactor(), GetSleepFactor().
  • New APIs to set or get AngularDamping of rigid body: Set/GetAngularDamping().
  • New APIs to filter collision for a single rigid body: AddCollisionException()/BeInCollisionException()/DeleteCollisionException, and Set/GetGroupId() for group filter.
  • Functions for Point and Vector transfer: BodyPoint()/WorldPoint()/BodyVector()/WorldVector() moved to ISPEPhysicsState form ISPERigidBody.
  • ISPERigidBody::AddWorldImpulse()/AddBodyTorque() changed to ISPERigidBody::ApplyWorldImpulse()/ApplyBodyTorque().
  • ISPERigidBody::GetContact had the new form, you must use ISPEContact interface.
  • Spring and friction in Joint not support any more, you must maintain them yourself.
  • ISPEWorld::Set/GetMaxSubStep() changed to Set/GetMaxStepPerUpdate().
  • ISPEWorld::DirectStep() avaible now to call single Step() directly.
  • ISPEWorld::GetBreakList() avaible now to get list of rigid bodies that need to break.
  • New APIs to config the precision and speed of new solver in ISPEWorld: SetSolverCacheFactor()/SetSolverPrecision().
  • ISPEWorld::Set/GetNumThreads() not avaible now in public SDK.
  • New APIs to clear the physics world: ISPEWorld::Clear(), and ISPEWorld::ClearGarbage() to release unused memory.
  • New tutorials in SDK: Physics and AI, CustomJoint.

  • Introduction :
    How does SPE work!? Constraint in SPE
    Tutorials :
    Get Start Joint Break Contact Query Fluid Physics Filter Collision Detection
    References :
    ISPEShape ISPEPhysicsState ISPERigidBody ISPEJoint ISPEConstraint
    ISPEContact ISPEParticle ISPEFluid ISPEWorld

    How does SPE work?

    Constraint in SPE
  • Introduction of SPEConstraintData.

    struct SPEConstraintData
    {
        SPEVector r[2];  // vector from center of mass to constraint point
        SPEVector n;  // normal
        float dv; // desired relative velocity in normal
        float u;  // friction coefficient in tangent space
        float low, high; // low and high bound of normal impulse
    };


  • // To solve collisions, we set constraint data this way:
    LPSPECONTACT pContact = pWorld->AddContact(); // Create contact
    // specify rigid bodies
    pContact->SetRigidBody(RigidBody0, RigidBody1); 
    // then enable the contact 
    pContact->SetEnabled(true);
    LPSPECONSTRAINT pConstraint = pContact->AddConstraint();
    SPEConstraintData data;
    data.r[0] = r0;
    data.r[1] = r1;
    data.n = n;
    // note that the relative velocity is defined as v0-v1 in SPE.
    data.dv = -e * ( ( Velocity0(p) - Velocity1(p) ) * n );
    data.u = 0.5f * ( u0 + u1); // artificial formula
    data.low = 0.0f;
    data.high = SPE_POSITIVE_INFINITE;
    // submit data
    pConstraint->SetData(data);



    // To solve ball joint, we set constraint data this way:
    LPSPECONTACT pContact = pWorld->AddContact();
    // specify rigid bodies
    pContact->SetRigidBody(RigidBody0, RigidBody1); 
    // then enable the contact 
    pContact->SetEnabled(true);
    LPSPECONSTRAINT pConstraint = pContact->AddConstraint();
    SPEConstraintData data;
    data.r[0] = r0;
    data.r[1] = r1;
    data.n = n; // p1-p0
    // correct positions
    data.dv = (p1-p0).Length()/StepTime;
    // use infinite friction to avoid sliding in tangent space
    data.u = SPE_POSITIVE_INFINITE;
    // need not to clamp impulse in this case
    data.low = SPE_NEGATIVE_INFINITE;
    data.high = SPE_POSITIVE_INFINITE;
    // submit data
    pConstraint->SetData(data);

    // This is only the basic idea of ball joint solving, 
    //for a more reliable implementation, see CustomJoint in the SDK.


    Get Start
  • Import the Library. Configure your IDE to make sure the compiler and linker can find "SPE.lib" and "SPE.h".
  • Include the header file of SPE, "SPE.h" is the only file you need to include.

    #include "SPE.h"

  • Define some global variables.

    LPSPEWORLD         pWorld; // interface of physics world
    LPSPERIGIDBODY     pBody; // interface of a rigidbody
    LPD3DXMESH     pBoxMesh;

  • Ready for physics simulation.

    // Function to initialize a shape from D3DXMesh
    void InitShape(ISPEShape* pShape, ID3DXMesh* pMesh)
    {
        BYTE *pVB;
        void *pIB;
        pMesh->LockVertexBuffer(D3DLOCK_NOSYSLOCK, (void**)&pVB);
        pMesh->LockIndexBuffer (D3DLOCK_NOSYSLOCK, (void**)&pIB);
        if(pMesh->GetOptions() & D3DXMESH_32BIT)  // 32BIT index
        {
            pShape->Initialize (pVB, pMesh->GetNumBytesPerVertex (),
                (int*)pIB, pMesh->GetNumFaces ());
        }
        else  // 16BIT index
        {
            pShape->Initialize (pVB, pMesh->GetNumBytesPerVertex (),
                (WORD*)pIB, pMesh->GetNumFaces ());
        }
        pMesh->UnlockVertexBuffer ();
        pMesh->UnlockIndexBuffer ();
    }

    void InitApp()
    {
        D3DXLoadMeshFromX ("box.x", &pBoxMesh); // load a model from x file

        pWorld = CreateSPEWorld();  // create a instance of physics world
        pWorld->SetGravity (SPEVector(0, -9.8f, 0)); // set the gravity

        LPSPESHAPE pShape = pWorld->CreateShape(); // create a shape instance
        InitShape(pShape, pBoxMesh);  // initialize the shape
        pBody = pWorld->AddRigidBody (pShape); // add a rigid body to SPEWorld with this shape
        pBody->SetPosition (SPEVector(0.0f, 2.0f, 0.0f)); // set position of rigid body
        pBody->SetVelocity (SPEVector(0.0f, 0.0f, -5.0f)); // set velocity
        pBody->SetAngularVelocity (SPEVector(0.0f, 25.0f, 0.0f));

        pWorld->ReleaseShape(pShape); // release the shape

        // another way to add a rigid body is to use "Shape" which is a member of pWorld, it had
        // been created when the pWorld was created. e.g.

        // InitShape(pWorld->Shape, pBoxMesh);
        // pBody = pWorld->AddRigidBody (); 

        // you needn't pass any parameter if you want to add a rigid body by "Shape" , and needn't release it
        // it can be Re-Initialize too.



  • Update the physics world.

    void CALLBACK OnFrameMove(float fElapsedTime )
    {
        pWorld->Update(fElapsedTime);


  • Get physics result from engine.

    void CALLBACK OnFrameRender( IDirect3DDevice9* m_pd3dDevice )
    {
        D3DXMATRIX matWorld;
        pBody->GetTransformMesh (&matWorld); // get the world matrix of a rigid body
        pd3dDevice->SetTransform (D3DTS_WORLD, &matWorld);
        pBoxMesh->DrawSubset (0);


  • Release all resources.

    void CALLBACK OnDestroyDevice( void* pUserContext )
    {
        SAFE_RELEASE( pBoxMesh );
        ReleaseSPEWorld( pWorld );  // release physics world
    }


  • Joint

    void InitApp() 
    {
        LPSPESHAPE pShape = pWorld->CreateShape(); // create a shape instance 
        D3DXLoadMeshFromX ("cask.x", &pCaskMesh); // load a model from x file 
        InitShape(pShape, pCaskMesh);

        // add 4 rigid bodies to the physics world using same shape
        for(int i=0; i<4; i++)
        {
            pBody[i]=pWorld->AddRigidBody (pShape);
            pBody[i]->SetPosition (SPEVector(0, (float)i+2, 0));
        }
        pWorld->ReleaseShape(pShape);


        SPEJointDesc jd;  // define a joint desc
        jd.Default();  // set to default
        jd.Body[0]=pBody[0];  // first body to be linked by the joint
        jd.Body[1]=pBody[1];  // second body to be linked by the joint
        jd.CreateByWorldAnchor=true;  // create by world anchor
        jd.WorldAnchor=SPEVector(0, 2.5f, 0); // specify the world position of anchor
        pJoint[0]=pWorld->AddJoint(jd); // add joint to the physics world

        pBody[3]->SetBeStatic(true);
        jd.Default();
        jd.Body[0]=pBody[3];
        jd.Body[1]=pBody[2];
        jd.CreateByWorldAnchor=false;  // create by body anchor
        jd.BodyAnchor[0]=SPEVector(0,-0.5f,0); // specify the position in the first body's frame
        jd.BodyAnchor[1]=SPEVector(0,0,1); // specify the position in the second body's frame
        pJoint[1]=pWorld->AddJoint(jd);

    }


    Break

    SPEArray<LPSPERIGIDBODY> Bodies;   // use an array to save dynamic increasing rigid bodies

    // function to create a SPEMesh from D3DXMesh
    void InitMesh(SPEMesh &speMesh, LPD3DXMESH pMesh)
    {
        DXVERTEX *dxvb;
        int *dxib;
        pMesh->LockVertexBuffer(D3DLOCK_NOSYSLOCK, (void**)&dxvb);
        pMesh->LockIndexBuffer (D3DLOCK_NOSYSLOCK, (void**)&dxib);

        int nBytes=pMesh->GetNumBytesPerVertex ();
        speMesh.Initialize ((BYTE*)dxvb, nBytes, (BYTE*)&dxvb[0].t,
            nBytes, dxib, pMesh->GetNumFaces ());

        pMesh->UnlockVertexBuffer ();
        pMesh->UnlockIndexBuffer ();

    }

    void InitApp() 
    {    
        LPSPESHAPE pShape = pWorld->CreateShape(); // create a shape instance 

        // add a normal rigid body
        D3DXLoadMeshFromX ("cask.x", &pBoxMesh); // load a model from x file 
        InitShape(pShape, pBoxMesh);
        pbody=pWorld->AddRigidBody (pShape);
        pbody->SetPosition (SPEVector(-5, 3, 0));
        pbody->SetVelocity (SPEVector(10,0,0));
        pbody->UserData=pBoxMesh; // use UserData as flag for rendering.
        Bodies.push(pbody);

        // add a breakable rigid body
        D3DXMatrixScaling(&mat, 1.0f, 1.0f, 1.0f);
        LoadMesh(pd3dDevice, pMesh[3], L"media/bone.x", mat);
        // to make a breakable rigid body, shape initializing from SPEMesh is necessary!
        SPEMesh speMesh;
        InitMesh(speMesh, pMesh[3]); // create a SPEMesh first
        pShape->Initialize(speMesh); // Initialize a shape from SPEMesh
        pbody=pWorld->AddRigidBody (pShape);
        pbody->SetPosition (SPEVector(-1, 3, 0));
        pbody->SetAngularVelocity (SPEVector(10,0,0));
        pbody->SetBreakForce(30.0f); // positive value make the body be breakable
        pbody->UserData=0; // use UserData as flag for rendering
        Bodies.push(pbody);

        pWorld->ReleaseShape(pShape);

        D3DXCreateTextureFromFile(pd3dDevice, L"media/spehome.bmp", &spe); // texture for original surface
        D3DXCreateTextureFromFile(pd3dDevice, L"media/section.bmp", §ion); // texture for sections

    }

    // function to break a rigid body into pieces
    void CheckBreak()
    {
        for(int i=0; i<Bodies.size; i++)
        {
            if(Bodies[i]->WantBreak()) // if a force greater than "BreakForce" had just applied to body
            {
                SPEContactInfo ci;
                Bodies[i]->GetBreakContact(ci); // get the contact which make the body break
                srand(timeGetTime());
                SPEVector n(rnd(1),rnd(1),rnd(1)); // generate a rand normal direction
                // create a plane by rand normal and contact info as a knife to carve the body
                SPEPlane pl(n, ci.Position); 
                pWorld->Carve(Bodies[i], pl); // carve the body and the result is saved in ISPEWorld::Meshes
                LPSPERIGIDBODY pbody;
                for(int j=0; j<pWorld->Meshes.size; j++)
                {
                    pWorld->Shape->Initialize(pWorld->Meshes[j]); // initialize shape from piece mesh
                    if(pWorld->Shape->GetVolume()<0.0005f) continue; // ignore the too small pieces
                    pbody=pWorld->AddRigidBody(); // add a rigid body to SPEWorld by ISPEWorld::Shape
                     // if the volume is greater than 0.05f, then make it breakable too
                    if(pWorld->Shape->GetVolume()>0.05f)
                    {
                        pbody->SetBreakForce(30.0f);
                    }
                    // compute states to make all pieces looks like a real part from the old body
                    pbody->PatternState (Bodies[i]); 
                    pbody->UserData=0; // set the render flag
                    Bodies.push(pbody); // add to body list
                }
                pWorld->DeleteRigidBody(Bodies[i]); // delete the old broken body from SPEWorld
                Bodies.del(i); // delete the pointer from local body list
                i--;
            }
        }
        
    }

    void CALLBACK OnFrameMove(float fElapsedTime)
    {
        pWorld->Update(fElapsedTime);
        CheckBreak(); // check break every frame
    }

    void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice)
    {

        D3DXMATRIX matWorld;

        for(int i=0; i<Bodies.size; i++)
        {
            Bodies[i]->GetTransform (&matWorld);
            pd3dDevice->SetTransform (D3DTS_WORLD, &matWorld);
            if(Bodies[i]->UserData)
            {
                LPD3DXMESH pMesh=(LPD3DXMESH)(Bodies[i]->UserData);
                pd3dDevice->SetTexture(0, spe);
                pMesh->DrawSubset (0);
            }
            else // render objects by SPEMesh
            {                
                SPEMesh* pMesh=Bodies[i]->GetShape()->GetMesh();
                // render the original surface 
                pd3dDevice->SetTexture(0, spe);
                pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST,
                    pMesh->GetNum(0), pMesh->GetData(0), sizeof(SPEVertex));
                // render the section
                pd3dDevice->SetTexture(0, section);
                pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST,
                    pMesh->GetNum(1), pMesh->GetData(1), sizeof(SPEVertex));
            }
        }

    }


    ContactQuery

    LPSPECONTACT pContact;
    int num=pBody[1]->GetNumContacts();
    for(int i=0; i<num; i++)
    {
        pContact=pBody[1]->GetContact(i);
        float sign = pBody[1]==pContact->GetRigidBody(0) ? 1.0f : -1.0f; // normal and impulse in Constraint is for the first rigid body
        int numConstraints=pContact->GetNumConstraints();
        for(int j=0; j<numConstraints; j++)
        {
            LPSPECONSTRAINT pConstraint=pContact->GetConstraint(j);
            SPEVector position=pConstraint->GetPosition();
            SPEVector normal=pConstraint->GetNormal()*sign;
            SPEVector impulse=pConstraint->GetImpulse()*sign;
            DrawLine(pd3dDevice, position, position+normal, 0);
            DrawLine(pd3dDevice, position, position+impulse*0.05f, 0xffffff00);
        }
    }


    Fluid

    LPSPEWORLD    pWorld;
    LPSPEFLUID    pFluid;

    void InitApp()
    {
        pFluid=pWorld->AddFluid(); // add a Fluid to SPEWorld
        pFluid->SetMaterial(SPE_WATER); // set material
        //pFluid->SetMaterial(SPE_SMOKE);
        pFluid->SetMeshGeneration(true); // generate surface mesh for rendering    
        
        float step=0.08f;
        SPEVector velocity(0, 0, 0);
        for(float y=0.0f; y<1.0f; y+=step)
        {
            for(float x=0.0f; x<step*9.5f; x+=step)
            {
                for(float z=0.0f; z<step*9.5f; z+=step)
                {
                    pFluid->AddParticle(SPEVector(x, y+1.0f, z), velocity); // add particle to Fluid
                }
            }
        }
    }

    void RenderFluid()
    {
        D3DXMatrixIdentity(&matWorld); // all the vertices of fluid mesh are in world frame
        pd3dDevice->SetTransform (D3DTS_WORLD, &matWorld);
        pd3dDevice->SetFVF(DXFVF);
        pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST,pFluid->GetMesh()->Triangle.size,
            &pFluid->GetMesh()->Triangle[0],sizeof(SPEVertex));

        // to render Fluid as particles, use ISPEFluid::GetParticlePosition, and do not forget to turn mesh generation off.
    }


    Physics Filter
  • There are 2 ways to disable collision detection.

    LPSPEWORLD pWorld;
    LPSPERIGIDBODY pBody0, pBody1;
    // 1) Using collision exception list of rigid body:
    pBody0->AddCollisionException(pBody1); 
    // or
    pBody1->AddCollisionException(pBody0); 

    // 2) Use group filter.
    pBody0->SetGroupId(2);
    pBody1->SetGroupId(3);
    pWorld->AddGroupPhysicsFlag(2, 3, SPE_PHYSICS_NONE);
    // the order of GroupId is arbitrary so it is equal to:
    pWorld->AddGroupPhysicsFlag(3, 2, SPE_PHYSICS_NONE);

  • You can only use group filter to disable solving.

  • Collision Detection
  • 1) Create rigid body first using ISPEWorld::CreateRigidBody():

    LPSPERIGIDBODY pBody0, pBody1;
    pBody0=pWorld->CreateRigidBody(pShape);
    pBody1=pWorld->CreateRigidBody(pShape);

  • 2) Specify the position and new position to the State and NewState for each rigid body:

    pBody0->GetState()->SetPosition(pos);
    pBody0->GetNewState()->SetPosition(npos);

    pBody1->GetState()->SetPosition(pos);
    pBody1->GetNewState()->SetPosition(npos);

  • 3) Push the rigid bodies to an array and call DetectCollisions().

    SPEArray<LPSPERIGIDBODY> list;
    list.push(pBody0);
    list.push(pBody1);
    pWorld->DetectCollisions(list);

  • 4) Then you can get the collision information by contact query interfaces of ISPERigidBody.

  • Note:
    [1]You can also change the orientation on step 2);
    [2]SPE do not generate a full swept volume to detect collisions, so if the distance from position to new position is too long and make broad phase skiped, you may miss some collisions.
    [3]Contact information is stored in a temporary list, you must use it before you call ISPEWorld::DetectCollisions() next time.
    [4]Physics filter is also effective here.

  • ISPEShape Reference
  • Applications use the methods of the ISPEShape interface to create collision shapes and ready for create rigid bodies.

    struct ISPEShape
    {
        virtual SPERESULT Initialize(BYTE *pVertex, int StrideSize, int *pIndex, int NumTriangles) = 0;
        
    Create a shape from tri-mesh data.
    Parameters
        pVertex
            [in] Pointer to vertex buffer.
        StrideSize
            [in] Stride of one vertex, in bytes.
        pIndex
            [in] Pointer to index buffer, index must be 32BIT.
        NumTriangles
            [in] Number of triangles.
        
    Return
            SPE_OK if the method succeeds, else return SPE_FAILED.
        
    Remarks
        

        virtual SPERESULT Initialize(BYTE *pVertex, int StrideSize, WORD *pIndex, int NumTriangles) = 0;
        
    Create a shape from tri-mesh data.
    Parameters
        pVertex
            [in] Pointer to vertex buffer.
        StrideSize
            [in] Stride of one vertex, in bytes.
        pIndex
            [in] Pointer to index buffer, index must be 16BIT.
        NumTriangles
            [in] Number of triangles.
        
    Return
            SPE_OK if the method succeeds, else return SPE_FAILED.
        
    Remarks
        

        virtual SPERESULT InitializeForStatic(BYTE *pVertex, int StrideSize, int *pIndex, int NumTriangles) = 0;
        
    Create a shape from tri-mesh data for static rigid body.
    Parameters
        pVertex
            [in] Pointer to vertex buffer.
        StrideSize
            [in] Stride of one vertex, in bytes.
        pIndex
            [in] Pointer to index buffer, index must be 32BIT.
        NumTriangles
            [in] Number of triangles.
        
    Return
            SPE_OK if the method succeeds, else return SPE_FAILED.
        
    Remarks
            Shape Initializing by this function can only be static, you can not use SetBeStatic(false) to active it. This function is just a little faster than the general initializing.
        

        virtual SPERESULT Initialize(BYTE *pVertex, int StrideSize, int NumVertices) = 0;
        
    Create a convex hull by giving vertices.
    Parameters
        pVertex
            [in] Pointer to vertex buffer.
        StrideSize
            [in] Stride of one vertex, in bytes.
        NumVertices
            [in] Number of vertices.
        
    Return
            SPE_OK if the method succeeds, else return SPE_FAILED.
        
    Remarks
        

        virtual SPERESULT Initialize(SPEMesh &speMesh) = 0;
        
    Create a shape from a SPEMesh object.
    Parameters
        speMesh
            [in] reference of a SPEMesh object.
        
    Return
            SPE_OK if the method succeeds, else return SPE_FAILED.
        
    Remarks
        

        virtual SPERESULT InitializeAsSphere(float r) = 0;
        
    Create a sphere shape.
    Parameters
        r
            [in] radius of sphere.
        
    Return
            SPE_OK if the method succeeds, else return SPE_FAILED.
        
    Remarks
        

        virtual SPERESULT InitializeAsCapsule(float length, float r) = 0;
        
    Create a capsule shape.
    Parameters
        length
            [in] length of capsule.
        r
            [in] radius of capsule.
        
    Return
            SPE_OK if the method succeeds, else return SPE_FAILED.
        
    Remarks
            The axis of capsule is align on Z, length must be greater than 2*r.
        

        virtual float GetVolume() = 0;
        
    Get the volume of shape.
    Parameters
        
    Return
            The volume of shape.
        
    Remarks
            The volume is computed while the shape be initialized.
        

        virtual SPERESULT SetMassCenter(const SPEVector &cm) = 0;
        
    Set the center of mass of shape.
    Parameters
        cm
            [in] center of mass.
        
    Return
            SPE_OK if the method succeeds, else return SPE_FAILED.
        
    Remarks
            This function is only valid after initializing and before creating rigid body, if you try to change the center of mass using interface from the ISPERigidBody::GetShape(), it would failed.
        

        virtual SPEVector GetMassCenter(void *pv=0) = 0;
        
    Get the mass center of shape.
    Parameters
        pv
            [out] If pv is not null, mass center value will be copied to.
        
    Return
            The mass center of shape.
        
    Remarks
            The mass center is computed while the shape be initialized.
        

        virtual SPEMesh* GetMesh() = 0;
        
    Get the pointer of SPEMesh contained in the shape.
    Parameters
        
    Return
            The pointer of SPEMesh.
        
    Remarks
            If the shape is not initialize from SPEMesh, the return valume is 0.
        

        virtual SPERESULT CloneTo(ISPEShape** ppIShape) = 0;
        
    Clone the shape instance to another interface.
    Parameters
        ppIShape
            [out] Address of a pointer to an ISPEShape interface, representing the destination shape.
        
    Return
            SPE_OK if the method succeeds, else return SPE_FAILED.
        
    Remarks
            An initialized shape must be released before get the new shape data.
        


    protected:
        ISPEShape(){}
        virtual ~ISPEShape(){}
    };



  • ISPEPhysicsState Reference
  • Applications use the methods of the ISPEPhysicsState interface to query of modify the physics state of rigid body.

    struct ISPEPhysicsState
    {
        // Set or Get member of State for body frame
        virtual void SetPosition(const SPEVector pos) = 0;
        virtual SPEVector GetPosition() = 0;
        virtual void SetOrientation(const SPEMatrix ort) = 0;
        virtual SPEMatrix GetOrientation() = 0;
        virtual void SetVelocity(const SPEVector vel) = 0;
        virtual SPEVector GetVelocity() = 0;
        virtual void SetAngularVelocity(const SPEVector& av) = 0;
        virtual SPEVector GetAngularVelocity() = 0;

        // Set or Get member of State for mesh frame
        virtual void SetPositionMesh(const SPEVector pos) = 0;
        virtual SPEVector GetPositionMesh() = 0;
        virtual void SetOrientationMesh(const SPEMatrix ort) = 0;
        virtual SPEMatrix GetOrientationMesh() = 0;

        // Transform a point or a vector between body frame and world frame
        virtual SPEVector PointBodyToWorld(const SPEVector &p) = 0;
        virtual SPEVector PointWorldToBody(const SPEVector &p) = 0;
        virtual SPEVector VectorBodyToWorld(const SPEVector &p) = 0;
        virtual SPEVector VectorWorldToBody(const SPEVector &p) = 0;

        // Get the velocity at a point in world frame
        virtual SPEVector GetVelocityAtWorldPoint(const SPEVector &p) = 0;

    protected:
        ISPEPhysicsState(){}
        virtual ~ISPEPhysicsState(){}
    };

  • ISPERigidBody Reference
  • Applications use the methods of the ISPERigidBody interface to manipulate and query rigid body.

    struct ISPERigidBody
    {
        virtual void SetMass(float mass) = 0;
        
    Set the mass of rigid body.
    Parameters
        mass
            [in] mass of rigid body.
        
    Return
        
    Remarks
            The default mass of a rigid body is 1000 * ShapeVolume.
        

        virtual float GetMass() = 0;
        
    Get the mass of rigid body.
    Parameters
        
    Return
            The mass of rigid body.
        
    Remarks
            The default mass of a rigid body is 1000 * ShapeVolume.
        

        virtual void SetDensity(float density=1000) = 0;
        
    Set the density of rigid body.
    Parameters
        density
            [in] density of rigid body.
        
    Return
        
    Remarks
            The default density of rigid body is 1000. New mass of rigid body would be density * ShapeVolume.
        

        virtual float GetDensity() = 0;
        
    Get the density of rigid body.
    Parameters
        
    Return
            The density of rigid body.
        
    Remarks
            The default density of rigid body is 1000.
        

        virtual void SetInertia(const SPEMatrix &inertia) = 0;
        
    Set the inertia tensor.
    Parameters
        inertia
            [in] inertia tensor.
        
    Return
        
    Remarks
            The inertia tensor is computed automatically by system. Note that inertia would be restored while you call SetMass()/SetDensity().
        

        virtual SPEMatrix GetInertia() = 0;
        
    Get the inertia tensor.
    Parameters
        
    Return
            The inertia tensor of rigid body.
        
    Remarks
            The inertia tensor is computed automatically by system. Note that inertia would be restored while you call SetMass()/SetDensity().
        

        virtual SPEMatrix GetWorldInertia() = 0;
        
    Get the inertia tensor in world frame by current orientation.
    Parameters
        
    Return
            The inertia tensor of rigid body.
        
    Remarks
            The inertia tensor is computed automatically by system. Note that inertia would be restored while you call SetMass()/SetDensity().
        


        virtual ISPEPhysicsState* GetState() = 0;
        
    Get the interface of "State" of rigid body.
    Parameters
        
    Return
            interface of "State".
        
    Remarks
        

        virtual ISPEPhysicsState* GetNewState() = 0;
        
    Get the interface of "New State" of rigid body.
    Parameters
        
    Return
            interface of "New State".
        
    Remarks
        

        
        virtual void SetPosition(SPEVector& pos) = 0;
        
    Set the position of rigid body.
    Parameters
        pos
            [in] position.
        
    Return
        
    Remarks
            The default position of rigid body is SPEVector(0,0,0).
        

        virtual SPEVector GetPosition() = 0;
        
    Get the position of rigid body.
    Parameters
        
    Return
            Position of rigid body.
        
    Remarks
        

        virtual void SetOrientation(SPEMatrix& ort) = 0;
        
    Set the Orientation of rigid body.
    Parameters
        ort
            [in] Orientation.
        
    Return
        
    Remarks
            The default Orientation of rigid body is SPEMatrix::Identity().
        

        virtual SPEMatrix GetOrientation() = 0;
        
    Get the Orientation of rigid body.
    Parameters
        
    Return
            orientation of rigid body.
        
    Remarks
            The default Orientation of rigid body is SPEMatrix::Identity().
        

        virtual void SetVelocity(SPEVector& v) = 0;
        
    Set the velocity of rigid body.
    Parameters
         v
            [in] velocity.
        
    Return
        
    Remarks
            The default velocity of rigid body is SPEVector(0,0,0).
        

        virtual SPEVector GetVelocity() = 0;
        
    Get the velocity of rigid body.
    Parameters
        
    Return
        
    Remarks
            The default velocity of rigid body is SPEVector(0,0,0).
        

        virtual void SetAngularVelocity(SPEVector& av) = 0;
        
    Set the angular velocity of rigid body.
    Parameters
         av
            [in] angular velocity.
        
    Return
        
    Remarks
            The default angular velocity of rigid body is SPEVector(0,0,0).
        

        virtual SPEVector GetAngularVelocity() = 0;
        
    Get the angular velocity of rigid body.
    Parameters
        
    Return
        
    Remarks
            The default angular velocity of rigid body is SPEVector(0,0,0).
        


        virtual void SetPositionMesh(const SPEVector& pos) = 0;
        
    Set the position of rigid body for mesh frame.
    Parameters
        pos
            [in] position.
        
    Return
        
    Remarks
            The default position of rigid body is SPEVector(0,0,0), hence the default position for mesh frame is -MassCenter.
        

        virtual SPEVector GetPositionMesh() = 0;
        
    Get the position of rigid body for mesh frame.
    Parameters
        
    Return
            position.
        
    Remarks
            The default position of rigid body is SPEVector(0,0,0), hence the default position for mesh frame is -MassCenter.
        

        virtual void SetOrientationMesh(const SPEMatrix& ort) = 0;
        
    Set the Orientation of rigid body for mesh frame.
    Parameters
        ort
            [in] Orientation.
        
    Return
        
    Remarks
            The default Orientation of rigid body is SPEMatrix::Identity(). Changing the orientation for mesh frame may also caused the position of body frame change.
        

        virtual SPEMatrix GetOrientationMesh() = 0;
        
    Get the Orientation of rigid body.
    Parameters
        
    Return
            orientation of rigid body.
        
    Remarks
            The default Orientation of rigid body is SPEMatrix::Identity().
        

        virtual void SetTransformMesh(SPEMatrix& trans) = 0;
        
    Set the Transform of rigid body for mesh frame, include position and orientation.
    Parameters
        trans
            [in] Transform.
        
    Return
        
    Remarks
            The default Transform of rigid body is SPEMatrix::Identity(), hence the default transform matrix for mesh frame is SPEMatrix::Translate(-MassCenter);
        

        virtual void SetTransformMesh(void* pmat) = 0;
        
    Set the Transform of rigid body using other data type, include position and orientation.
    Parameters
        pmat
            [in] address of a matrix.
        
    Return
        
    Remarks
            The default Transform of rigid body is SPEMatrix::Identity(), hence the default transform matrix for mesh frame is SPEMatrix::Translate(-MassCenter);
        

        virtual SPEMatrix GetTransformMesh(void* pmat=0) = 0;
        
    Get the Transform of rigid body, include position and orientation.
    Parameters
        pmat
            [out] address of a matrix or NULL.
        
    Return
        
    Remarks
            If pamt is not 0, Transform data would copied to. The default Transform of rigid body is SPEMatrix::Identity(), hence the default transform matrix for mesh frame is SPEMatrix::Translate(-MassCenter);
        

        
        virtual void SetBeStatic(bool bs) = 0;
        
    Set if the rigid body be static.
    Parameters
         bs
            [in] bool.
        
    Return
        
    Remarks
            If the rigid body had been set to be static, it would not move and the mass is infinite. The default is false.
        

        virtual bool GetBeStatic() = 0;
        
    Get if the rigid body be static.
    Parameters
        
    Return
            true if the rigid body be static, else return false.
        
    Remarks
            If the rigid body had been set to be static, it would not move and the mass is infinite. The default is false.
        

        virtual SPERESULT SetSleeping(bool sleeping) = 0;
        
    Force to sleep or wake up the rigid body.
    Parameters
        sleeping
            [in] (true)sleep or (false)wake up.
        
    Return
        
    Remarks
        

        virtual bool GetSleeping() = 0;
        
    Get the state of sleeping of a rigid body.
    Parameters
        
    Return
            true if is sleeping, else return false.
        
    Remarks
        

        virtual void SetSleepFactor(float factor) = 0;
        
    Set the factor of sleep threshold which would determine how fast a rigid body go to sleep.
    Parameters
        factor
            [in] factor.
        
    Return
        
    Remarks
            The default factor is 1.0f;
        

        virtual float GetSleepFactor() = 0;
        
    Get the factor of sleep threshold which would determine how fast a rigid body go to sleep.
    Parameters
        
    Return
            factor.
        
    Remarks
            The default factor is 1.0f;
        

        virtual void SetDynamicGeneration(bool dg) = 0;
        
    Set if the rigid body would be controled by manual.
    Parameters
         dg
            [in] bool.
        
    Return
        
    Remarks
            If the rigid body had been set to generate dynamic, Velocity and AngularVelocity is generated while you call SetTransform or SetPosition or SetOrientation, making ragdoll interact with other bodies. The default is false.
        

        virtual bool GetDynamicGeneration() = 0;
        
    Get if the rigid body would be controled by manual.
    Parameters
        
    Return
            true if the rigid body had been set to generate dynamic, else return false.
        
    Remarks
            If the rigid body had been set to generate dynamic, Velocity and AngularVelocity is generated while you call SetTransform or SetPosition or SetOrientation, making ragdoll interact with other bodies. The default is false.
        

        virtual void SetExternForceField(SPEVector &force) = 0; // this function can used for particles
        
    Set extern force field influence to rigid body.
    Parameters
        force
            [in] a vector reprenting the force field.
        
    Return
        
    Remarks
            This is a dedicate function design for particle simulation. The default is SPEVector(0,0,0).
        

        virtual SPEVector GetExternForceField() = 0;
        
    Get extern force field influence to rigid body.
    Parameters
        
    Return
            Extern force field.
        
    Remarks
            The default is SPEVector(0,0,0).
        


        virtual void SetDamping(float damping) = 0;
        
    Set damping of rigid body.
    Parameters
        damping
            [in] damping.
        
    Return
        
    Remarks
            The default is 0.0f.
        

        virtual float GetDamping() = 0;
        
    Get damping of rigid body.
    Parameters
        
    Return
            damping of rigid body.
        
    Remarks
            The default is 0.0f.
        

        virtual void SetAngularDamping(float angulardamping) = 0;
        
    Set angular damping of rigid body.
    Parameters
        angulardamping
            [in] angular damping.
        
    Return
        
    Remarks
            The default is 0.0f.
        

        virtual float GetAngularDamping() = 0;
        
    Get angular damping of rigid body.
    Parameters
        
    Return
            angular damping of rigid body.
        
    Remarks
            The default is 0.0f.
        

        virtual void SetFriction(float friction) = 0;
        
    Set friction coefficient of rigid body.
    Parameters
        friction
            [in] friction coefficient.
        
    Return
        
    Remarks
            When two rigid bodies collide, the finally friction coefficient between two surfaces is: (body0.friction+body1.friction)/2 . The default is 0.5f.
        

        virtual float GetFriction() = 0;
        
    Get friction coefficient of rigid body.
    Parameters
        
    Return
            Friction coefficient of rigid body.
        
    Remarks
            When two rigid bodies collide, the finally friction coefficient between two surfaces is: (body0.friction+body1.friction)/2 . The default is 0.5f.
        

        virtual void SetElasticity(float elasticity) = 0;
        
    Set elasticity coefficient of rigid body.
    Parameters
        elasticity
            [in] elasticity coefficient.
        
    Return
        
    Remarks
            When two rigid bodies collide, the finally elasticity coefficient between two surfaces is: body0.elasticity*body1.elasticity . The default is 0.1f.
        

        virtual float GetElasticity() = 0;
        
    Get elasticity coefficient of rigid body.
    Parameters
        
    Return
            Elasticity coefficient of rigid body.
        
    Remarks
            When two rigid bodies collide, the finally elasticity coefficient between two surfaces is: body0.elasticity*body1.elasticity . The default is 0.1f.
        


        virtual void ApplyWorldImpulse(SPEVector &impulse, SPEVector &position) = 0;
        
    Apply a impulse to the rigid body.
    Parameters
        impulse
            [in] a vector representing the impulse, include direction and scalar, in world frame.
        position
            [in] position where impulse to applied, in world frame.
        
    Return
        
    Remarks
            Impulse would applied into the NewState.
        

        virtual void ApplyBodyTorque(SPEVector &torque) = 0;
        
    Add a Torque to the rigid body.
    Parameters
        torque
            [in] a vector representing the torque, include direction and scalar, in body frame.
        
    Return
        
    Remarks
            Impulse would applied into the NewState.
        


        virtual int     GetNumContacts() = 0;
        
    Get number of the contacts of rigid body.
    Parameters
        
    Return
            Number of the contacts of rigid body.
        
    Remarks
        

        virtual ISPEContact* GetContact(int index) = 0;
        
    Get index'th contact.
    Parameters
        index
            [in] index.
        
    Return
            the index'th contact.
        
    Remarks
        

        
        virtual bool CastRay(SPEVector &RayPos, SPEVector &RayDir, SPECastRayInfo &Info) = 0;
        
    Test if a ray intersect this rigid body.
    Parameters
        RayPos
            [in] Start position of the ray.
        RayDir
            [in] Direction of the ray.
        Info
            [out] Intersect information of this test.
        
    Return
            true if the ray intersect this rigid body, else return false.
        
    Remarks
            To find the nearest intersection in the whole world, use SPEWorld::CastRay(...).
        


        virtual void AddCollisionException(ISPERigidBody *pIBody) = 0;
        
    Add a rigid body to collision exception list to avoid collision detection.
    Parameters
        pIBody
            [in] interface of a rigid body.
        
    Return
        
    Remarks
        

        virtual bool BeInCollisionException(ISPERigidBody *pIBody) = 0;
        
    Check if a rigid body is in the collision exception list.
    Parameters
        
    Return
            true if in, else false.
        
    Remarks
        

        virtual void DeleteCollisionException(ISPERigidBody *pIBody=0) = 0;
        
    Delete a rigid body to collision exception list.
    Parameters
        pIBody
            [in] interface of a rigid body. if pIBody==0, all rigid body in the list would be deleted.
        
    Return
        
    Remarks
        

        virtual void SetGroupId(int id) = 0;
        
    Set the group Id of a rigid body.
    Parameters
        id
            [in] Id.
        
    Return
        
    Remarks
            Group Id is used for physics filter.
        

        virtual int GetGroupId() = 0;
        
    Get the group Id of a rigid body.
    Parameters
        
    Return
            Id.
        
    Remarks
            Group Id is used for physics filter.
        

        
        virtual void SetBreakForce(float force) = 0;
        
    Set the tolerance force of rigid body.
    Parameters
        force
            [in] tolerance force.
        
    Return
        
    Remarks
            While a force greater than BreakForce had applied to the rigid body, WantBreak() would return true. Negative value means unbreakable. The default is -1.
        

        virtual float GetBreakForce() = 0;
        
    Get the tolerance force of rigid body.
    Parameters
        
    Return
            Tolerance force.
        
    Remarks
            While a force greater than BreakForce had applied to the rigid body, WantBreak() would return true. Negative value means unbreakable. The default is -1.
        

        virtual bool WantBreak() = 0;
        
    Get the state whether a rigid body can break.
    Parameters
        
    Return
            true if a force greater than BreakForce had applied to the rigid body, else return false.
        
    Remarks
        

        virtual void GetBreakContact(SPEContactInfo &Contact) = 0;
        
    Get the information of contact which break the rigid body.
    Parameters
        Contact
            [out] Reference of a SPEContactInfo.
        
    Return
        
    Remarks
        

        virtual void PatternState(ISPERigidBody* ibody) = 0;
        
    Set all the states of the child pieces patterned from parent body.
    Parameters
        ibody
            [in] parent body.
        
    Return
        
    Remarks
            A dedicated function to implement breakable rigid bodies. It computes and sets new position, orientation, velocity, angular velocity to make pieces looks like a real part from the parent body.
        


        virtual ISPEShape* GetShape() = 0;
        
    Get the shape interface of rigid body.
    Parameters
        
    Return
            Shape interface of rigid body.
        
    Remarks
            Shape in the rigid body had been locked and can not be initialized.
        


        void*        UserData;
        int            iUserData;
        float        fUserData;

    protected:
        ISPERigidBody()
        {
            UserData=0;
            iUserData=0;
            fUserData=0.0f;
        }
        virtual ~ISPERigidBody(){}
    };

  • ISPEJoint Reference
  • Applications use the methods of the ISPEJoint interface to control joints.

    struct ISPEJoint
    {
        virtual ISPERigidBody* GetBody(int index) = 0;
        
    Get one of rigid body linked by this joint.
    Parameters
        index
            [in] Rigid body index, 0 or 1.
        
    Return
            Interface of the rigid body.
        
    Remarks
        

        virtual SPEVector GetWorldAnchor() = 0;
        
    Get the world anchor of joint.
    Parameters
        
    Return
            World anchor of joint.
        
    Remarks
        

        virtual void SetBodyAnchor(int index, SPEVector &anchor) = 0;
        
    Change the body anchor of joint.
    Parameters
        index
            [in] index of two bodies, 0 or 1.
        anchor
            [in] new position of body anchor, in body frame.
        
    Return
        
    Remarks
            Body anchor had been determined when the joint been created, this function allow user to change position of anchor.
        

        virtual SPEVector GetBodyAnchor(int index) = 0;
        
    Get the body anchor of joint.
    Parameters
        index
            [in] index of two bodies, 0 or 1.
        
    Return
        
    Remarks
            Body anchor had been determined when the joint been created.
        

        virtual bool IsBroken() = 0;
        
    Get the state that whether the joint is broken.
    Parameters
        
    Return
            true if the joint is broken, else return false.
        
    Remarks
            A joint been breakable only when the member of SPEJointDesc named BreakForce had been asigned a positive value when create the joint.
        

        virtual ISPEContact* GetContact() = 0;
        
    Get the contact interface for this joint.
    Parameters
        
    Return
             interface of contact.
        
    Remarks
        

    };

  • ISPEConstraint Reference
  • Applications use the methods of the ISPEConstraint interface to get collision information or build custom joints.

    struct ISPEConstraint
    {
        virtual SPERESULT SetData(const SPEConstraintData &data) = 0;
        
    Feed data to constraint.
    Parameters
        data
            [in] data.
        
    Return
            SPE_OK if the method succeeds, else return SPE_FAILED.
        
    Remarks
            If the length of n in data is less than 1.0e-6, the method would failed.
        

        virtual void GetData(SPEConstraintData &data) = 0;
        
    Get data of this constraint.
    Parameters
        data
            [out] data.
        
    Return
        
    Remarks
        

        virtual void SetEnabled(bool enabled) = 0;
        
    Enable of disable a constraint.
    Parameters
        enabled
            [in] value.
        
    Return
        
    Remarks
            The default is true.
        

        virtual bool GetEnabled() = 0;    
        
    Get the state of the constraint.
    Parameters
        
    Return
            true if enabled, else return false.
        
    Remarks
            The default is true.
        

        virtual SPEVector GetPosition() = 0;
        
    Get the position of the constraint.
    Parameters
        
    Return
            position.
        
    Remarks
            Only the constraint generated by collision detection had a valid position.
        

        virtual SPEVector GetNormal() = 0;
        
    Get the normal of the constraint.
    Parameters
        
    Return
            normal.
        
    Remarks
            The direction of normal is for the first rigid body of a contact pair, If you want to get the normal for the second rigid body, just reverse it(multply -1.0f).
            The return value is equal to the SPEConstraintData.n.
        

        virtual SPEVector GetImpulse() = 0;
        
    Get the Impulse work out by solver.
    Parameters
        
    Return
            impulse.
        
    Remarks
            The direction of impulse is for the first rigid body of a contact pair, If you want to get the impulse for the second rigid body, just reverse it(multply -1.0f).
             You can't get valid impulse in the CallBack function PreSolve() because the solver had not run.
        

        
    protected:
        ISPEConstraint(){}
        virtual ~ISPEConstraint(){}
    };

  • ISPEContact Reference
  • Applications use the methods of the ISPEContact interface to manage the constraints.

    struct ISPEContact
    {
        virtual void SetRigidBody(ISPERigidBody* pIBody0, ISPERigidBody* pIBody1) = 0;
        
    Specify the rigid body of contact pair.
    Parameters
        pIBody0, pIBody1
            [in] two rigid bodies.
        
    Return
        
    Remarks
            If you had not specify the rigid bodies, you can not enable this contact.
        

        virtual ISPERigidBody* GetRigidBody(int index) = 0; // index must be 0 or 1
        
    Get the rigid body of contact pair.
    Parameters
        index
            [in] index of two rigid body, must be 0 or 1.
        
    Return
        
    Remarks
        

        virtual ISPEConstraint* AddConstraint() = 0;
        
    Add a constraint to contact.
    Parameters
        
    Return
            interface of a constraint.
        
    Remarks
            You can also retrieve the interface by it's index.
        

        virtual SPERESULT DeleteConstraint(ISPEConstraint* pIConstraint=0) = 0;
        
    Delete a constraint or all constraints from contact.
    Parameters
        pIConstraint
            [in] interface of a constraint, it it's null, all constraints would be deleted.
        
    Return
            SPE_OK if pIConstraint is valid, else return SPE_FAILED.
        
    Remarks
        

        virtual SPERESULT SetEnabled(bool enabled) = 0;
        
    Enable or disable all constraints belong to the contact.
    Parameters
        enabled
            [in] value.
        
    Return
            SPE_OK if succeed, else return SPE_FAILED.
        
    Remarks
            If you had not specify the rigid bodies, you can not enable this contact. The default is false.
        

        virtual bool GetEnabled() = 0;
        
    Get the state of the contact.
    Parameters
        
    Return
            true if enabled, else return false.
        
    Remarks
            The default is false.
        

        virtual int GetNumConstraints() = 0;
        
    Get the numble of constraints.
    Parameters
        
    Return
            numble of constraints.
        
    Remarks
        

        virtual ISPEConstraint* GetConstraint(int index) = 0;
        
    Get the constraint by index.
    Parameters
        
    Return
            interface of constraint, if index is not valid, return 0.
        
    Remarks
        

        virtual ISPEConstraint* GetVirtualConstraint() = 0;
        
    Get the virtual constraint.
    Parameters
        
    Return
            interface of constraint.
        
    Remarks
            Virtual constraint is generated by collision detection system, generally, it is the center of all contact point,
            and it's normal is get from a contact point which had the deepest penetrate. Virtual constraint is used to process impact.
        

        virtual SPECONTACTTYPE GetType() = 0;
        
    Get the type of contact.
    Parameters
        
    Return
            type of contact.
        
    Remarks
            The type would be COLLISION, JOINT or CUSTOM.
        

        virtual SPEVector GetSumImpulse(int index) = 0; // index must be 0 or 1
        
    Get the sum of impulses of all constraint for index'th rigid body.
    Parameters
        
    Return
            sum of impulses.
        
    Remarks
        

        virtual SPEVector GetSumTorque(int index) = 0; // index must be 0 or 1
        
    Get the sum of torque of all constraint for index'th rigid body.
    Parameters
        
    Return
            sum of torques.
        
    Remarks
        


    protected:
        ISPEContact(){}
        virtual ~ISPEContact(){}
    };

  • ISPEParticle Reference
  • Applications use the methods of the ISPEParticle interface to access particles in Fluid.

    struct ISPEParticle
    {
        virtual void SetPosition(const SPEVector& pos) = 0;
        
    Set the position of particle.
    Parameters
        pos
            [in] position
        
    Return
        
    Remarks
        

        virtual SPEVector GetPosition() = 0;
        
    Get the position of particle.
    Parameters
        
    Return
            Position of particle.
        
    Remarks
            If pos is not 0, position data would copied to.
        

        virtual void SetVelocity(const SPEVector& v) = 0;
        
    Set the velocity of particle.
    Parameters
        v
            [in] velocity
        
    Return
        
    Remarks
        

        virtual SPEVector GetVelocity() = 0;
        
    Get the velocity of particle.
    Parameters
        
    Return
            Velocity of particle.
        
    Remarks
        


    protected:
        ISPEParticle(){}
        virtual ~ISPEParticle(){}
    };

  • ISPEFluid Reference
  • Applications use the methods of the ISPEFluid interface to control the simulation of Fluid.

    struct ISPEFluid
    {
        virtual void SetMaterial(SPEFLUIDMATERIAL material) = 0;
        
    Set the material of fluid.
    Parameters
        material
            [in] material, SPE_WATER or SPE_SMOKE.
        
    Return
        
    Remarks
            SPE hide any parameters of SPH algorithm to make the engine easy to use and to keep the engine be stable.
        

        virtual ISPEParticle* AddParticle(const SPEVector &position) = 0;
        
    Add a particle with zero velocity to fluid.
    Parameters
        position
            [in] position.
        
    Return
        
    Remarks        
        

        virtual ISPEParticle* AddParticle(const SPEVector &position, const SPEVector &velocity) = 0;
        
    Add a particle to fluid.
    Parameters
        position
            [in] position.
        velocity
            [in] velocity.
        
    Return
        
    Remarks        
        

        virtual void DeleteParticle(ISPEParticle* pIParticle=0) = 0;
        
    Delete a particle or all particles from Fluid.
    Parameters
        pIParticle
            [in] interface of a Fluid or NULL.
        
    Return
        
    Remarks
            If pIParticle is not NULL, pIParticle would be deleted, otherwise all Particles in the Fluid would be deleted.
        

        virtual int GetNumParticles() = 0;
        
    Get the number of particles in Fluid.
    Parameters
        
    Return
            Number of particles.
        
    Remarks        
        

        virtual void GetParticlePosition(void* pData, int StrideSize) = 0;
        
    Get the position of all particles in Fluid.
    Parameters
        pData
            [in] address of a buffer to store positions.
        StrideSize
            [in] stride of buffer, in bytes.
        
    Return
        
    Remarks        
        

        virtual void GetParticleVelocity(void* pData, int StrideSize) = 0;
        
    Get the velocity of all particles in Fluid.
    Parameters
        pData
            [in] address of a buffer to store positions.
        StrideSize
            [in] stride of buffer, in bytes.
        
    Return
        
    Remarks
        

        virtual void SetMeshGeneration(bool mg) = 0;
        
    Set if to generate surface mesh of Fluid.
    Parameters
        mg
            [in] bool.
        
    Return
        
    Remarks
            The reason SPE does not provide a function like GenerateMesh() is that the system only generate mesh at proper time.
        

        virtual bool GetMeshGeneration() = 0;
        
    Get if to generate surface mesh of Fluid.
    Parameters
        
    Return
            true if the system generate mesh, else return false.
        
    Remarks
            The reason SPE does not provide a function like GenerateMesh() is that the system only generate mesh at proper time.
        

        virtual SPEMesh* GetMesh() = 0;
        
    Get the surface mesh of Fluid.
    Parameters
        
    Return
            Pointer of surface mesh.
        
    Remarks
        


    protected:
        ISPEFluid(){}
        virtual ~ISPEFluid(){}
    };

  • ISPEWorld Reference
  • Applications use the methods of the ISPEWorld interface to control physics world.

    struct ISPEWorld
    {
        virtual void SetGravity(const SPEVector &g) = 0;
        
    Set the gravity of the physics world.
    Parameters
        g
            [in] gravity.
        
    Return
        
    Remarks
            The default is SPEVector(0, 0, -9.8f).
        

        virtual SPEVector GetGravity() = 0;
        
    Get the gravity of the physics world.
    Parameters
        
    Return
            gravity.
        
    Remarks
            The default is SPEVector(0, 0, -9.8f).
        

        virtual void SetStepTime(float time=0.01f) = 0;
        
    Set the step time to do physics simulation.
    Parameters
        time
            [in] step time.
        
    Return
        
    Remarks
            SPE use fixed time step to do physics simulation, small step time means more time to compute. The default is 0.01f.
        

        virtual float GetStepTime() = 0;
        
    Get the step time to do physics simulation.
    Parameters
        
    Return
            step time.
        
    Remarks
            SPE use fixed time step to do physics simulation, small step time means more time would be take to compute. The default is 0.01f.
        

        virtual void SetMaxStepPerUpdate(int sub=2) = 0; // 2 is the default
        
    Set the number of max step in a update.
    Parameters
        sub
            [in] number of max step.
        
    Return
        
    Remarks
            SPE use fixed time step to do physics simulation, when the elapsed time is greater than step time, SPE would do physics-computation more than once. The default is 2.
        

        virtual int GetMaxStepPerUpdate() = 0;
        
    Get the number of max step in a update.
    Parameters
        
    Return
            number of max step.
        
    Remarks
            SPE use fixed time step to do physics simulation, when the elapsed time is greater than step time, SPE would do physics-computation more than once. The default is 2.
        

        virtual int Update(float dt) = 0;
        
    Update the physics world, including integration, collision dection and collision resolve.
    Parameters
        dt
            [in] elapsed time.
        
    Return
            number of step ran during this update.
        
    Remarks
        

        virtual void DirectStep() = 0;
        
    Update the physics world with a single step.
    Parameters
        
    Return
        
    Remarks
        


        virtual void SetSolverCacheFactor(float factor=0.2f) = 0; // 0.2 is the default
        
    Set the percentage of cached results to be used as initialization value for solver.
    Parameters
        factor
            [in] percentage, must be in [0.0, 1.0].
        
    Return
        
    Remarks
            The default is 0.2(20%). Cache data is useful only when the solver precision is low and no large-scale impulse/force change in the simulation.
        

        virtual float GetSolverCacheFactor() = 0;
        
    Get the percentage of cached results to be used as initialization value for solver.
    Parameters
        
    Return
            percentage
        
    Remarks
            The default is 0.2(20%). Cache data is useful only when the solver precision is low and no large-scale impulse/force change in the simulation.
        

        virtual void SetSolverPrecision(int precision=2) = 0; // 2 is the default
        
    Set the Precision level of solver.
    Parameters
        precision
            [in] precision level, must be greater than 0.
        
    Return
        
    Remarks
            The default is 2.
        

        virtual int GetSolverPrecision() = 0;
        
    Get the Precision level of solver.
    Parameters
        
    Return
            precision
        
    Remarks
            The default is 2.
        

        
        virtual void SetCallBackPreSolve(SPECallBackFunc pFunc, void *pParam) = 0;
        
    Set the call back function which would be called before solver run.
    Parameters
        pFunc
            [in] a pointer to a function.
        pParam
            [in] parameter of your function.
        
    Return
        
    Remarks
            Call back function must defined like this: void* pFunc(void *pParam){...}. To disable call back function, set pFunc to 0.
        

        virtual void SetCallBackStepFinished(SPECallBackFunc pFunc, void *pParam) = 0;
        
    Set the call back function which would be called after a step is finished.
    Parameters
        pFunc
            [in] a pointer to a function.
        pParam
            [in] parameter of your function.
        
    Return
        
    Remarks
            Call back function must defined like this: void* pFunc(void *pParam){...}. To disable call back function, set pFunc to 0.
        

        
        virtual void SetNumThreads(int n) = 0;
        
    Set the number of threads to be use for each phase of physics computation. For Multi-Threads Library only.
    Parameters
        n
            [in] number of threads.
        
    Return
        
    Remarks
            The default is 1, means multi-thread is disabled. Do not try to use a number larger than the cores of CPU.
        

        virtual int GetNumThreads() = 0;
        
    Get the number of threads using for each phase of physics computation. For Multi-Threads Library only.
    Parameters
        
    Return
            number of threads.
        
    Remarks
            The default is 1, means multi-thread is disabled.        
        

        
        virtual ISPEShape*        CreateShape() = 0;
        
    Create a shape instance.
    Parameters
        
    Return
            Interface of a shape instance.
        
    Remarks
            SPEWorld::Shape is available as soon as the SPEWorld been created.
        

        virtual void                    ReleaseShape(ISPEShape *pIShape) = 0;
        
    Release a shape instance.
    Parameters
        pIShape
            [in] interface of a shape instance.
        
    Return        
        
    Remarks
        

        virtual ISPERigidBody*    AddRigidBody(ISPEShape *pIShape=0) = 0;
        
    Add a rigid body to the physics world by a shape.
    Parameters
        pIShape
            [in] interface of a shape instance or NULL.
        
    Return
            Interface of a rigid body.
        
    Remarks
            If pIShape==0, system would use SPEWorld::Shape to add a rigid body.
        

        virtual void                    DeleteRigidBody(ISPERigidBody *pIBody=0) = 0;
        
    Delete a rigid body or delete all rigid bodies in the physics world.
    Parameters
        pIBody
            [in] interface of a rigid body or NULL.
        
    Return        
        
    Remarks
            If pIBody is not NULL, pIBody would be deleted, otherwise all rigid bodies in the physics world would be deleted.
        

        virtual ISPEFluid*            AddFluid() = 0;
        
    Add a Fluid instance to the physics world.
    Parameters
        
    Return
            Interface of a Fluid.
        
    Remarks
        

        virtual void                    DeleteFluid(ISPEFluid* pIFluid=0) = 0;
        
    Delete a Fluid or delete all Fluids in the physics world.
    Parameters
        pIFluid
            [in] interface of a Fluid or NULL.
        
    Return
        
    Remarks
            If pIFluid is not NULL, pIFluid would be deleted, otherwise all Fluids in the physics world would be deleted.
        

        virtual ISPEJoint*            AddJoint(SPEJointDesc& joint) = 0;
        
    Add a joint to the physics world by a joint desc.
    Parameters
        joint
            [in] reference of a SPEJointDesc structure.
        
    Return
            Interface of a joint.
        
    Remarks
        

        virtual void                    DeleteJoint(ISPEJoint* pIJoint=0) = 0;
        
    Delete a joint or delete all joints in the physics world.
    Parameters
        pIJoint
            [in] interface of a joint or NULL.
        
    Return
        
    Remarks
            If pIJoint is not NULL, pIJoint would be deleted, otherwise all joints in the physics world would be deleted.
        

        virtual ISPEContact*        AddCustomContact() = 0;
        
    Add a custom contact to the physics world.
    Parameters
        
    Return
            Interface of a contact.
        
    Remarks
        

        virtual SPERESULT        DeleteCustomContact(ISPEContact* pIContact=0) = 0;
        
    Delete a custom contact or delete all custom contacts in the physics world.
    Parameters
        pIContact
            [in] interface of a contact or NULL.
        
    Return
        
    Remarks
            If pIContact is not NULL, pIContact would be deleted, otherwise all custom contact in the physics world would be deleted.
        

        
        virtual void Clear() = 0; // clear all above stuff
        
    Delete all rigid bodies, fluids, joints, custom contacts in the physics world.
    Parameters
        
    Return
        
    Remarks
        

        virtual void ClearGarbage() = 0; // release all unused memory
        
    Release all unused memory allocated by SPE.
    Parameters
        
    Return
        
    Remarks
        


        virtual ISPERigidBody* CreateRigidBody(ISPEShape* pIShape=0) = 0; // if pIShape==0, member "Shape" is used
        
    Create a rigid body but not add to the list for simulation.
    Parameters
        pIShape
            [in] interface of a shape instance or NULL.
        
    Return
            Interface of a rigid body.
        
    Remarks
            If pIShape==0, system would use SPEWorld::Shape to create a rigid body.
        

        virtual SPERESULT ReleaseRigidBody(ISPERigidBody *pIBody) = 0;
        
    Release a rigid body.
    Parameters
        pIBody
            [in] interface of a rigid body.
        
    Return
            SPE_OK if the method succeeds, else return SPE_FAILED.
        
    Remarks
            Only the interface returned by ISPEWorld::CreateRigidBody can be released.
        

        virtual void DetectCollisions(SPEArray &RigidBodyList) = 0;
        
    Detect collisions for a set of rigid bodies.
    Parameters
        RigidBodyList
            [in] a set of rigid bodies.
        
    Return
        
    Remarks
            For more information, see tutorial section in this document.
        


        virtual void AddGroupPhysicsFlag(int id0, int id1, SPEGROUPPHYSICSFLAG flag) = 0;
        
    Add a flag to physics world for physics filter.
    Parameters
        id0
            [in] the first group id.
        id0
            [in] the second group id.
        flag
            [in] physics filter flag.
        
    Return
        
    Remarks
        

        virtual SPEGROUPPHYSICSFLAG GetGroupPhysicsFlag(int id0, int id1) = 0;
        
    Query the flag for a pair of group.
    Parameters
        id0
            [in] the first group id.
        id0
            [in] the second group id.
        
    Return
            physics filter flag.
        
    Remarks
            If no matched pair is found, return SPE_PHYSICS_FULL.
        

        virtual void DeleteGroupPhysicsFlag(int id0, int id1) = 0;
        
    Delete a flag for a pair of group.
    Parameters
        id0
            [in] the first group id.
        id0
            [in] the second group id.
        
    Return
        
    Remarks
        

        virtual int GetNumGroupPhysicsFlags() = 0;
        
    Get the number of flags in physics world.
    Parameters
        
    Return
            number of flags.
        
    Remarks
        

        virtual void ClearGroupPhysicsFlag() = 0;
        
    Delete all flags.
    Parameters
        
    Return
        
    Remarks
        

        
        virtual int GetBreakList() = 0;
        
    Get the list of rigid bodies that need to break.
    Parameters
        
    Return
            size of list.
        
    Remarks
            list is stored in the ISPEWorld::List.
        

        virtual void Carve(ISPERigidBody* ibody, SPEPlane &knife) = 0;
        
    Carve a rigid body by a plane.
    Parameters
        ibody
            [in] interface of a rigid body to be carved.
        knife
            [in] a plane representing a knife.
        
    Return
        
    Remarks
            The result is a list of SPEMesh, which stored in the SPEWorld::Meshes.
        

        virtual void Carve(ISPERigidBody* ibody, SPEArray &knives) = 0;
        
    Carve a rigid body by a collection of planes.
    Parameters
        ibody
            [in] interface of a rigid body to be carved.
        knives
            [in] a collection of planes.
        
    Return
        
    Remarks
            The result is a list of SPEMesh, which stored in the SPEWorld::Meshes.
        


        virtual bool CastRay(SPEVector &RayPos, SPEVector &RayDir, SPECastRayInfo &Info) = 0; // find the nearest intersection
        
    Cast a ray to find the nearest intersection.
    Parameters
        RayPos
            [in] start position of the ray.
        RayDir
            [in] direction of the ray.
        Info
            [out] Intersect information of this test.
        
    Return
            true if the ray hits some thing, else return false.
        
    Remarks
            To test if a ray hits an appointed body, use SPERigidBody::CastRay(...).
        


        ISPEShape*    Shape;
        
    A shape interface to bring some conveniences while using SPE
    Parameters
        
    Return
        
    Remarks        
        

        SPEArray<SPEMesh> Meshes;
        
    A list of SPEMesh to store the result of Carve(...).
    Parameters
        
    Return
        
    Remarks        
        

        SPEArray<ISPERigidBody*> List;
        
    A list of rigid bodies to store the result of some functions.
    Parameters
        
    Return
        
    Remarks        
        


    protected:
        ISPEWorld(){}
        virtual ~ISPEWorld(){}
    };



  • © 2006-2008, spehome.com, All rights reserved.
    E-Mail: