Jump to content

  • Log In with Google      Sign In   
  • Create Account

#ActualSteve_Segreto

Posted 03 April 2013 - 12:13 AM

I have integrated Bullet Physics into a D3D9 class engine and it is not that difficult. Let me share an overview of Bullet, I may be glossing over many details, please refer to the Wiki page and other web resources as well.

 

You start by creating an object that derives from btCollisionWorld, like btDiscreteDynamicsWorld. You can tick this object using the stepSimulation member, which will basically identify all contacts between "collision" objects and update their positions based on physical properties like gravity, mass, etc.

 

Collision objects fall into two classes (well three if you consider the character controller), rigid bodies, soft bodies and kinematic objects. You can add immovable (static) collision objects by setting the mass to a special constant (0.0f). You add rigid bodies using the addRigidBody member of your collision world object. You can do ray testing against the objects in your world using the rayTest() member of the collision world object.

 

When first creating your collision world, you need to select and specify a collision dispatcher, a broadphase object, a constraint solver and some config data. Your program needs to allocate and de-allocate all objects and memory passed to Bullet, the library does not own any pointers provided to it.

 

The choice of broadphase object can determine how well the collision world responds to very dynamic rigid bodies changing position every frame. You can overload both broadphase and nearphase collision responses and filters (so you can make a player rigid body collide with nothing but the ground, but make every other rigid body bounce off the player, for instance).

 

You can also declare a debug drawer and provide a D3D9 implementation to help you visualize the collision world and the collision objects as you place them in the world.

 

Here's the debug drawer I use, maybe it would help you?

 

//-----------------------------------------------------------------------------
// File: CDebugDrawer.h
//
// Purpose: A debug drawer used by the physics library.
//
// Copyright (c) 2007-2011 Steve Segreto. All rights reserved.
//-----------------------------------------------------------------------------
#pragma once
#include "LinearMath/btIDebugDraw.h"
#include <vector>
struct VCol
{
    VCol(
        const D3DXVECTOR3& v,
        D3DCOLOR           c
        ) : pos(v),col(c)
    {
    }
    D3DXVECTOR3 pos;
    D3DCOLOR col;
};
void VisualizeRay (
    D3DXVECTOR3 rayStartW,
    D3DXVECTOR3 rayDirW,
    D3DXCOLOR   color
    );
void VisualizeLineSegment (
    D3DXVECTOR3 startW,
    D3DXVECTOR3 endW,
    D3DXCOLOR   color
    );
void VisualizeBox (
    struct AABB* box,
    D3DXCOLOR color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f )
    );
void VisualizeBox (
    struct OBB* box,
    D3DXCOLOR color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f )
    );
void VisualizeQuad (
    D3DXVECTOR3 topLeft,
    D3DXVECTOR3 bottomRight,
    D3DXCOLOR color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f )
    );
void VisualizeFrustum (
    D3DXVECTOR3* corners,
    D3DXCOLOR    color
    );
void VisualizeRotation (
    D3DXVECTOR3 posW,
    D3DXQUATERNION rot,
    D3DXCOLOR colorX = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f),
    D3DXCOLOR colorY = D3DXCOLOR(1.0f, 1.0f, 0.0f, 1.0f),
    D3DXCOLOR colorZ = D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)
    );
void VisualizeRotation (
    D3DXVECTOR3 posW,
    D3DXMATRIX rot,
    D3DXCOLOR colorX = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f),
    D3DXCOLOR colorY = D3DXCOLOR(1.0f, 1.0f, 0.0f, 1.0f),
    D3DXCOLOR colorZ = D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)
    );
class CDebugDrawer : public btIDebugDraw
{
public:
    int m_debugMode;
    std::vector< VCol > m_vertices;
    CDebugDrawer();
    void DebugPresent ();
    virtual void drawLine (
        const btVector3& from,
        const btVector3& to,
        const btVector3& fromColor,
        const btVector3& toColor
        );
    virtual void drawLine (
        const btVector3& from,
        const btVector3& to,
        const btVector3& color
        );
    virtual void drawSphere (
        const btVector3& p,
        btScalar         radius,
        const btVector3& color
        );
    virtual void drawBox (
        const btVector3& boxMin,
        const btVector3& boxMax,
        const btVector3& color,
        btScalar         alpha
        );
    virtual void drawTriangle (
        const btVector3& a,
        const btVector3& b,
        const btVector3& c,
        const btVector3& color,
        btScalar         alpha
        );
    virtual void drawContactPoint (
        const btVector3& PointOnB,
        const btVector3& normalOnB,
        btScalar         distance,
        int              lifeTime,
        const btVector3& color
        );
    virtual void reportErrorWarning (const char* warningString);
    virtual void draw3dText (
        const btVector3& location,
        const char*      textString
        );
    virtual void setDebugMode (int debugMode);
    virtual int getDebugMode () const
    {
        return m_debugMode;
    }
};
//-----------------------------------------------------------------------------
// File: CDebugDrawer.cpp
//
// Purpose: A debug drawer used by the physics library.
//
// Copyright (c) 2007-2011 Steve Segreto. All rights reserved.
//-----------------------------------------------------------------------------
#include "Global.h"
#include "CRenderable.h"
#include "CVertexManager.h"
#include "CDebugDrawer.h"
extern CPhysicsEngine* g_pPhysics;
void VisualizeFrustum (
    D3DXVECTOR3* corners,
    D3DXCOLOR    color
    )
{
    VisualizeLineSegment( corners[ 4 ], corners[ 5 ], color );
    VisualizeLineSegment( corners[ 7 ], corners[ 6 ], color );
    VisualizeLineSegment( corners[ 4 ], corners[ 7 ], color );
    VisualizeLineSegment( corners[ 5 ], corners[ 6 ], color );
    VisualizeLineSegment( corners[ 0 ], corners[ 1 ], color );
    VisualizeLineSegment( corners[ 3 ], corners[ 2 ], color );
    VisualizeLineSegment( corners[ 0 ], corners[ 3 ], color );
    VisualizeLineSegment( corners[ 1 ], corners[ 2 ], color );
    VisualizeLineSegment( corners[ 0 ], corners[ 4 ], color );
    VisualizeLineSegment( corners[ 1 ], corners[ 5 ], color );
    VisualizeLineSegment( corners[ 2 ], corners[ 6 ], color );
    VisualizeLineSegment( corners[ 3 ], corners[ 7 ], color );
}

void VisualizeRay (
    D3DXVECTOR3 rayStartW,
    D3DXVECTOR3 rayDirW,
    D3DXCOLOR   color
    )
{
    D3DXVECTOR3 rayToW = (rayDirW * 1000) + rayStartW;

    g_pPhysics->m_pDebugDrawer->m_vertices.clear();
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( rayStartW.x, rayStartW.y,
                                                     rayStartW.z ),
                                          btVector3( rayToW.x, rayToW.y,
                                                     rayToW.z ),
                                          btVector3( color.r, color.g, color.b ),
                                          btVector3( color.r, color.g, color.b ) );
    g_pPhysics->m_pDebugDrawer->DebugPresent();
}

void VisualizeBox (
    AABB*     box,
    D3DXCOLOR color
    )
{
    //
    // Draw a box using 4 quads
    //
    D3DXVECTOR3 c0 = D3DXVECTOR3( box->maxPt.x, box->maxPt.y, box->maxPt.z );
    D3DXVECTOR3 c1 = D3DXVECTOR3( box->maxPt.x, box->minPt.y, box->maxPt.z );
    D3DXVECTOR3 c2 = D3DXVECTOR3( box->maxPt.x, box->maxPt.y, box->minPt.z );
    D3DXVECTOR3 c3 = D3DXVECTOR3( box->minPt.x, box->maxPt.y, box->maxPt.z );
    D3DXVECTOR3 c4 = D3DXVECTOR3( box->maxPt.x, box->minPt.y, box->minPt.z );
    D3DXVECTOR3 c5 = D3DXVECTOR3( box->minPt.x, box->maxPt.y, box->minPt.z );
    D3DXVECTOR3 c6 = D3DXVECTOR3( box->minPt.x, box->minPt.y, box->maxPt.z );
    D3DXVECTOR3 c7 = D3DXVECTOR3( box->minPt.x, box->minPt.y, box->minPt.z );

    VisualizeLineSegment( c0, c3, color );
    VisualizeLineSegment( c0, c1, color );
    VisualizeLineSegment( c0, c2, color );
    VisualizeLineSegment( c3, c5, color );
    VisualizeLineSegment( c3, c6, color );
    VisualizeLineSegment( c1, c4, color );
    VisualizeLineSegment( c1, c6, color );
    VisualizeLineSegment( c2, c5, color );
    VisualizeLineSegment( c2, c4, color );
    VisualizeLineSegment( c4, c7, color );
    VisualizeLineSegment( c5, c7, color );
    VisualizeLineSegment( c6, c7, color );
}

void VisualizeBox (
    OBB*      box,
    D3DXCOLOR color
    )
{
    //
    // Draw a box using 4 quads
    //
    D3DXVECTOR3 c0 = box->m_objectBounds[ 7 ];
    D3DXVECTOR3 c1 = box->m_objectBounds[ 5 ];
    D3DXVECTOR3 c2 = box->m_objectBounds[ 3 ];
    D3DXVECTOR3 c3 = box->m_objectBounds[ 6 ];
    D3DXVECTOR3 c4 = box->m_objectBounds[ 1 ];
    D3DXVECTOR3 c5 = box->m_objectBounds[ 2 ];
    D3DXVECTOR3 c6 = box->m_objectBounds[ 4 ];
    D3DXVECTOR3 c7 = box->m_objectBounds[ 0 ];

    VisualizeLineSegment( c0, c3, color );
    VisualizeLineSegment( c0, c1, color );
    VisualizeLineSegment( c0, c2, color );
    VisualizeLineSegment( c3, c5, color );
    VisualizeLineSegment( c3, c6, color );
    VisualizeLineSegment( c1, c4, color );
    VisualizeLineSegment( c1, c6, color );
    VisualizeLineSegment( c2, c5, color );
    VisualizeLineSegment( c2, c4, color );
    VisualizeLineSegment( c4, c7, color );
    VisualizeLineSegment( c5, c7, color );
    VisualizeLineSegment( c6, c7, color );
}

void VisualizeQuad (
    D3DXVECTOR3 topLeft,
    D3DXVECTOR3 bottomRight,
    D3DXCOLOR   color
    )
{
    //
    // Draw a quad between topLeft and bottomRight.
    //
    VisualizeLineSegment( topLeft,
                          D3DXVECTOR3( topLeft.x,
                                       bottomRight.y,
                                       topLeft.z ), color );
    VisualizeLineSegment( D3DXVECTOR3( topLeft.x,
                                       bottomRight.y,
                                       topLeft.z ), bottomRight, color );
    VisualizeLineSegment( bottomRight,
                          D3DXVECTOR3( bottomRight.x,
                                       topLeft.y,
                                       bottomRight.z ), color );
    VisualizeLineSegment( D3DXVECTOR3( bottomRight.x,
                                       topLeft.y,
                                       bottomRight.z ), topLeft, color );
}

void VisualizeLineSegment (
    D3DXVECTOR3 startW,
    D3DXVECTOR3 endW,
    D3DXCOLOR   color
    )
{
    g_pPhysics->m_pDebugDrawer->m_vertices.clear();
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( startW.x, startW.y,
                                                     startW.z ),
                                          btVector3( endW.x, endW.y, endW.z ),
                                          btVector3( color.r, color.g, color.b ),
                                          btVector3( color.r, color.g, color.b ) );
    g_pPhysics->m_pDebugDrawer->DebugPresent();
}

void VisualizeRotation (
    D3DXVECTOR3    posW,
    D3DXQUATERNION rot,
    D3DXCOLOR      colorX,
    D3DXCOLOR      colorY,
    D3DXCOLOR      colorZ
    )
{
    D3DXMATRIX m;

    D3DXMatrixRotationQuaternion( &m, &rot );
    VisualizeRotation( posW, m, colorX, colorY, colorZ );
}

void VisualizeRotation (
    D3DXVECTOR3 posW,
    D3DXMATRIX  m,
    D3DXCOLOR   colorX,
    D3DXCOLOR   colorY,
    D3DXCOLOR   colorZ
    )
{
    D3DXVECTOR3 xAxis = (D3DXVECTOR3( m._11, m._12, m._13 ) * 1) + posW;
    D3DXVECTOR3 yAxis = (D3DXVECTOR3( m._21, m._22, m._23 ) * 1) + posW;
    D3DXVECTOR3 zAxis = (D3DXVECTOR3( m._31, m._32, m._33 ) * 1) + posW;

    g_pPhysics->m_pDebugDrawer->m_vertices.clear();
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( posW.x, posW.y, posW.z ),
                                          btVector3( xAxis.x, xAxis.y, xAxis.z ),
                                          btVector3( colorX.r, colorX.g,
                                                     colorX.b ),
                                          btVector3( colorX.r, colorX.g,
                                                     colorX.b ) );
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( posW.x, posW.y, posW.z ),
                                          btVector3( yAxis.x, yAxis.y, yAxis.z ),
                                          btVector3( colorY.r, colorY.g,
                                                     colorY.b ),
                                          btVector3( colorY.r, colorY.g,
                                                     colorY.b ) );
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( posW.x, posW.y, posW.z ),
                                          btVector3( zAxis.x, zAxis.y, zAxis.z ),
                                          btVector3( colorZ.r, colorZ.g,
                                                     colorZ.b ),
                                          btVector3( colorZ.r, colorZ.g,
                                                     colorZ.b ) );
    g_pPhysics->m_pDebugDrawer->DebugPresent();
}

CDebugDrawer::CDebugDrawer() : m_debugMode(0)
{
}

void CDebugDrawer::DebugPresent ()
{
    if ( !m_vertices.size() )
    {
        return;
    }

    D3DXMATRIX world;
    D3DXMatrixIdentity( &world );
    g_d3dDevice->SetTransform(D3DTS_WORLD, &world);
    HR( g_pRenderStateMgr->SetVertexShader( NULL ) );
    HR( g_pRenderStateMgr->SetPixelShader( NULL ) );
    DWORD m_renderStates[ 256 ];
    g_pRenderStateMgr->SetToDefaults( m_renderStates );
    g_pRenderStateMgr->PostStates( m_renderStates );
    g_pRenderStateMgr->SetRenderState( D3DRS_LIGHTING, FALSE );
    HR( g_pRenderStateMgr->SetVertexDeclaration( VertexCol::Decl ) );
    DWORD vertsToDraw = (DWORD)m_vertices.size();
    DWORD vertOffset = 0;
    DWORD vertChunk;
    while (vertsToDraw)
    {
        vertChunk = min( 16, vertsToDraw );
        g_d3dDevice->DrawPrimitiveUP( D3DPT_LINELIST, (UINT)vertChunk / 2,
                                      &m_vertices[vertOffset],
                                      sizeof(VCol) );
        vertsToDraw -= vertChunk;
        vertOffset += vertChunk;
    }

    m_vertices.clear();
}

void CDebugDrawer::drawLine (
    const btVector3& from,
    const btVector3& to,
    const btVector3& fromColor,
    const btVector3& toColor
    )
{
    D3DXVECTOR3 vFrom, vTo, vCFrom, vCTo;

    memcpy( &vFrom,  &from,      sizeof( D3DXVECTOR3 ) );
    memcpy( &vTo,    &to,        sizeof( D3DXVECTOR3 ) );
    memcpy( &vCFrom, &fromColor, sizeof( D3DXVECTOR3 ) );
    memcpy( &vCTo,   &toColor,   sizeof( D3DXVECTOR3 ) );
    D3DCOLOR cFrom, cTo;
    cFrom =
        D3DCOLOR_ARGB( 0xFF, (DWORD)(vCFrom.x * 255), (DWORD)(vCFrom.y * 255),
                       (DWORD)(vCFrom.z * 255) );
    cTo =
        D3DCOLOR_ARGB( 0xFF, (DWORD)(vCTo.x * 255), (DWORD)(vCTo.y * 255),
                       (DWORD)(vCTo.z * 255) );
    VCol vert[] = {VCol(vFrom, cFrom), VCol(vTo, cTo)};
    m_vertices.push_back( vert[0] );
    m_vertices.push_back( vert[1] );
}

void CDebugDrawer::drawLine (
    const btVector3& from,
    const btVector3& to,
    const btVector3& color
    )
{
    drawLine(from, to, color, color);
}

void CDebugDrawer::drawSphere (
    const btVector3& p,
    btScalar         radius,
    const btVector3& color
    )
{
#if 0
    glColor4f ( color.getX(), color.getY(), color.getZ(), btScalar(1.0f) );
    glPushMatrix ();
    glTranslatef ( p.getX(), p.getY(), p.getZ() );
    int lats = 5;
    int longs = 5;
    int i, j;
    for(i = 0; i <= lats; i++)
    {
        btScalar lat0 = SIMD_PI * (-btScalar(0.5) + (btScalar) (i - 1) / lats);
        btScalar z0 = radius * sin(lat0);
        btScalar zr0 = radius * cos(lat0);
        btScalar lat1 = SIMD_PI * (-btScalar(0.5) + (btScalar) i / lats);
        btScalar z1 = radius * sin(lat1);
        btScalar zr1 = radius * cos(lat1);
        glBegin(GL_QUAD_STRIP);
        for(j = 0; j <= longs; j++)
        {
            btScalar lng = 2 * SIMD_PI * (btScalar) (j - 1) / longs;
            btScalar x = cos(lng);
            btScalar y = sin(lng);
            glNormal3f(x * zr0, y * zr0, z0);
            glVertex3f(x * zr0, y * zr0, z0);
            glNormal3f(x * zr1, y * zr1, z1);
            glVertex3f(x * zr1, y * zr1, z1);
        }

        glEnd();
    }

    glPopMatrix();
#endif
}

void CDebugDrawer::drawBox (
    const btVector3& boxMin,
    const btVector3& boxMax,
    const btVector3& color,
    btScalar         alpha
    )
{
#if 0
    btVector3 halfExtent = (boxMax - boxMin) * btScalar(0.5f);
    btVector3 center = (boxMax + boxMin) * btScalar(0.5f);
    glColor4f (color.getX(), color.getY(), color.getZ(), alpha);
    glPushMatrix ();
    glTranslatef ( center.getX(), center.getY(), center.getZ() );
    glScaled(2 * halfExtent[0], 2 * halfExtent[1], 2 * halfExtent[2]);
    glPopMatrix ();
#endif
}

void CDebugDrawer::drawTriangle (
    const btVector3& a,
    const btVector3& b,
    const btVector3& c,
    const btVector3& color,
    btScalar         alpha
    )
{
#if 0
    const btVector3 n = btCross(b - a,c - a).normalized();
    glBegin(GL_TRIANGLES);
    glColor4f(color.getX(), color.getY(), color.getZ(),alpha);
    glNormal3d( n.getX(),n.getY(),n.getZ() );
    glVertex3d( a.getX(),a.getY(),a.getZ() );
    glVertex3d( b.getX(),b.getY(),b.getZ() );
    glVertex3d( c.getX(),c.getY(),c.getZ() );
    glEnd();
#endif
}

void CDebugDrawer::setDebugMode (int debugMode)
{
    m_debugMode = debugMode;
}

void CDebugDrawer::draw3dText (
    const btVector3& location,
    const char*      textString
    )
{
#if 0
    glRasterPos3f( location.x(),  location.y(),  location.z() );
#endif
}

void CDebugDrawer::reportErrorWarning (const char* warningString)
{
    OutputDebugStringA( warningString );
    OutputDebugStringA( "\n" );
}

void CDebugDrawer::drawContactPoint (
    const btVector3& pointOnB,
    const btVector3& normalOnB,
    btScalar         distance,
    int              lifeTime,
    const btVector3& color
    )
{
#if 0
    btVector3 to = pointOnB + normalOnB * distance;
    const btVector3&from = pointOnB;
    glColor4f(color.getX(), color.getY(), color.getZ(),1.f);
    glBegin(GL_LINES);
    glVertex3d( from.getX(), from.getY(), from.getZ() );
    glVertex3d( to.getX(), to.getY(), to.getZ() );
    glEnd();
    glRasterPos3f( from.x(),  from.y(),  from.z() );
    char buf[12];
    sprintf(buf," %d",lifeTime);
#endif
}

You can create collision objects from your own model data in many ways. One way to do it is to treat your models as indexed triangle lists and use the example shown below. Be aware that your indices must match the size given below (i.e. either 16 or 32-bit indices - the example below uses 16-bit).

 

 

pMesh->m_pTriMesh = new btTriangleIndexVertexArray();
btIndexedMesh iMesh;
iMesh.m_numTriangles = pMesh->m_numFaces;
iMesh.m_triangleIndexBase = (const unsigned char *)pMesh->m_pIndices;
iMesh.m_triangleIndexStride = 3 * sizeof(IndexFormat);
iMesh.m_numVertices = pMesh->m_numVertices;
iMesh.m_vertexBase = (const unsigned char *)pMesh->m_pVertices;
iMesh.m_vertexStride = sizeof(D3DXVECTOR3);
pMesh->m_pTriMesh->addIndexedMesh( iMesh, PHY_SHORT );
pMesh->m_pTriShape = new btBvhTriangleMeshShape( pMesh->m_pTriMesh, false, true );

 

The basic process is to create a CollisionShape and then insert that as a rigid body as mentioned above. Other possible collision shapes are:

 

btHeightfieldTerrainShape,

btScaledBvhTriangleMeshShape

 

and of course the primitive shapes, btSphereShape, btCylinderShape, btBoxShape, etc.


#4Steve_Segreto

Posted 03 April 2013 - 12:12 AM

I have integrated Bullet Physics into a D3D9 class engine and it is not that difficult. Let me share an overview of Bullet, I may be glossing over many details, please refer to the Wiki page and other web resources as well.

 

You start by creating an object that derives from btCollisionWorld, like btDiscreteDynamicsWorld. You can tick this object using the stepSimulation member, which will basically identify all contacts between "collision" objects and update their positions based on physical properties like gravity, mass, etc.

 

Collision objects fall into two classes (well three if you consider the character controller), rigid bodies, soft bodies and kinematic objects. You can add immovable (static) collision objects by setting the mass to a special constant (0.0f). You add rigid bodies using the addRigidBody member of your collision world object. You can do ray testing against the objects in your world using the rayTest() member of the collision world object.

 

When first creating your collision world, you need to select and specify a collision dispatcher, a broadphase object, a constraint solver and some config data. Your program needs to allocate and de-allocate all objects and memory passed to Bullet, the library does not own any pointers provided to it.

 

The choice of broadphase object can determine how well the collision world responds to very dynamic rigid bodies changing position every frame. You can overload both broadphase and nearphase collision responses and filters (so you can make a player rigid body collide with nothing but the ground, but make every other rigid body bounce off the player, for instance).

 

You can also declare a debug drawer and provide a D3D9 implementation to help you visualize the collision world and the collision objects as you place them in the world.

 

Here's the debug drawer I use, maybe it would help you?

 

//-----------------------------------------------------------------------------
// File: CDebugDrawer.h
//
// Purpose: A debug drawer used by the physics library.
//
// Copyright (c) 2007-2011 Steve Segreto. All rights reserved.
//-----------------------------------------------------------------------------
#pragma once
#include "LinearMath/btIDebugDraw.h"
#include <vector>
struct VCol
{
    VCol(
        const D3DXVECTOR3& v,
        D3DCOLOR           c
        ) : pos(v),col(c)
    {
    }
    D3DXVECTOR3 pos;
    D3DCOLOR col;
};
void VisualizeRay (
    D3DXVECTOR3 rayStartW,
    D3DXVECTOR3 rayDirW,
    D3DXCOLOR   color
    );
void VisualizeLineSegment (
    D3DXVECTOR3 startW,
    D3DXVECTOR3 endW,
    D3DXCOLOR   color
    );
void VisualizeBox (
    struct AABB* box,
    D3DXCOLOR color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f )
    );
void VisualizeBox (
    struct OBB* box,
    D3DXCOLOR color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f )
    );
void VisualizeQuad (
    D3DXVECTOR3 topLeft,
    D3DXVECTOR3 bottomRight,
    D3DXCOLOR color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f )
    );
void VisualizeFrustum (
    D3DXVECTOR3* corners,
    D3DXCOLOR    color
    );
void VisualizeRotation (
    D3DXVECTOR3 posW,
    D3DXQUATERNION rot,
    D3DXCOLOR colorX = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f),
    D3DXCOLOR colorY = D3DXCOLOR(1.0f, 1.0f, 0.0f, 1.0f),
    D3DXCOLOR colorZ = D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)
    );
void VisualizeRotation (
    D3DXVECTOR3 posW,
    D3DXMATRIX rot,
    D3DXCOLOR colorX = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f),
    D3DXCOLOR colorY = D3DXCOLOR(1.0f, 1.0f, 0.0f, 1.0f),
    D3DXCOLOR colorZ = D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)
    );
class CDebugDrawer : public btIDebugDraw
{
public:
    int m_debugMode;
    std::vector< VCol > m_vertices;
    CDebugDrawer();
    void DebugPresent ();
    virtual void drawLine (
        const btVector3& from,
        const btVector3& to,
        const btVector3& fromColor,
        const btVector3& toColor
        );
    virtual void drawLine (
        const btVector3& from,
        const btVector3& to,
        const btVector3& color
        );
    virtual void drawSphere (
        const btVector3& p,
        btScalar         radius,
        const btVector3& color
        );
    virtual void drawBox (
        const btVector3& boxMin,
        const btVector3& boxMax,
        const btVector3& color,
        btScalar         alpha
        );
    virtual void drawTriangle (
        const btVector3& a,
        const btVector3& b,
        const btVector3& c,
        const btVector3& color,
        btScalar         alpha
        );
    virtual void drawContactPoint (
        const btVector3& PointOnB,
        const btVector3& normalOnB,
        btScalar         distance,
        int              lifeTime,
        const btVector3& color
        );
    virtual void reportErrorWarning (const char* warningString);
    virtual void draw3dText (
        const btVector3& location,
        const char*      textString
        );
    virtual void setDebugMode (int debugMode);
    virtual int getDebugMode () const
    {
        return m_debugMode;
    }
};
//-----------------------------------------------------------------------------
// File: CDebugDrawer.cpp
//
// Purpose: A debug drawer used by the physics library.
//
// Copyright (c) 2007-2011 Steve Segreto. All rights reserved.
//-----------------------------------------------------------------------------
#include "Global.h"
#include "CRenderable.h"
#include "CVertexManager.h"
#include "CDebugDrawer.h"
extern CPhysicsEngine* g_pPhysics;
void VisualizeFrustum (
    D3DXVECTOR3* corners,
    D3DXCOLOR    color
    )
{
    VisualizeLineSegment( corners[ 4 ], corners[ 5 ], color );
    VisualizeLineSegment( corners[ 7 ], corners[ 6 ], color );
    VisualizeLineSegment( corners[ 4 ], corners[ 7 ], color );
    VisualizeLineSegment( corners[ 5 ], corners[ 6 ], color );
    VisualizeLineSegment( corners[ 0 ], corners[ 1 ], color );
    VisualizeLineSegment( corners[ 3 ], corners[ 2 ], color );
    VisualizeLineSegment( corners[ 0 ], corners[ 3 ], color );
    VisualizeLineSegment( corners[ 1 ], corners[ 2 ], color );
    VisualizeLineSegment( corners[ 0 ], corners[ 4 ], color );
    VisualizeLineSegment( corners[ 1 ], corners[ 5 ], color );
    VisualizeLineSegment( corners[ 2 ], corners[ 6 ], color );
    VisualizeLineSegment( corners[ 3 ], corners[ 7 ], color );
}

void VisualizeRay (
    D3DXVECTOR3 rayStartW,
    D3DXVECTOR3 rayDirW,
    D3DXCOLOR   color
    )
{
    D3DXVECTOR3 rayToW = (rayDirW * 1000) + rayStartW;

    g_pPhysics->m_pDebugDrawer->m_vertices.clear();
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( rayStartW.x, rayStartW.y,
                                                     rayStartW.z ),
                                          btVector3( rayToW.x, rayToW.y,
                                                     rayToW.z ),
                                          btVector3( color.r, color.g, color.b ),
                                          btVector3( color.r, color.g, color.b ) );
    g_pPhysics->m_pDebugDrawer->DebugPresent();
}

void VisualizeBox (
    AABB*     box,
    D3DXCOLOR color
    )
{
    //
    // Draw a box using 4 quads
    //
    D3DXVECTOR3 c0 = D3DXVECTOR3( box->maxPt.x, box->maxPt.y, box->maxPt.z );
    D3DXVECTOR3 c1 = D3DXVECTOR3( box->maxPt.x, box->minPt.y, box->maxPt.z );
    D3DXVECTOR3 c2 = D3DXVECTOR3( box->maxPt.x, box->maxPt.y, box->minPt.z );
    D3DXVECTOR3 c3 = D3DXVECTOR3( box->minPt.x, box->maxPt.y, box->maxPt.z );
    D3DXVECTOR3 c4 = D3DXVECTOR3( box->maxPt.x, box->minPt.y, box->minPt.z );
    D3DXVECTOR3 c5 = D3DXVECTOR3( box->minPt.x, box->maxPt.y, box->minPt.z );
    D3DXVECTOR3 c6 = D3DXVECTOR3( box->minPt.x, box->minPt.y, box->maxPt.z );
    D3DXVECTOR3 c7 = D3DXVECTOR3( box->minPt.x, box->minPt.y, box->minPt.z );

    VisualizeLineSegment( c0, c3, color );
    VisualizeLineSegment( c0, c1, color );
    VisualizeLineSegment( c0, c2, color );
    VisualizeLineSegment( c3, c5, color );
    VisualizeLineSegment( c3, c6, color );
    VisualizeLineSegment( c1, c4, color );
    VisualizeLineSegment( c1, c6, color );
    VisualizeLineSegment( c2, c5, color );
    VisualizeLineSegment( c2, c4, color );
    VisualizeLineSegment( c4, c7, color );
    VisualizeLineSegment( c5, c7, color );
    VisualizeLineSegment( c6, c7, color );
}

void VisualizeBox (
    OBB*      box,
    D3DXCOLOR color
    )
{
    //
    // Draw a box using 4 quads
    //
    D3DXVECTOR3 c0 = box->m_objectBounds[ 7 ];
    D3DXVECTOR3 c1 = box->m_objectBounds[ 5 ];
    D3DXVECTOR3 c2 = box->m_objectBounds[ 3 ];
    D3DXVECTOR3 c3 = box->m_objectBounds[ 6 ];
    D3DXVECTOR3 c4 = box->m_objectBounds[ 1 ];
    D3DXVECTOR3 c5 = box->m_objectBounds[ 2 ];
    D3DXVECTOR3 c6 = box->m_objectBounds[ 4 ];
    D3DXVECTOR3 c7 = box->m_objectBounds[ 0 ];

    VisualizeLineSegment( c0, c3, color );
    VisualizeLineSegment( c0, c1, color );
    VisualizeLineSegment( c0, c2, color );
    VisualizeLineSegment( c3, c5, color );
    VisualizeLineSegment( c3, c6, color );
    VisualizeLineSegment( c1, c4, color );
    VisualizeLineSegment( c1, c6, color );
    VisualizeLineSegment( c2, c5, color );
    VisualizeLineSegment( c2, c4, color );
    VisualizeLineSegment( c4, c7, color );
    VisualizeLineSegment( c5, c7, color );
    VisualizeLineSegment( c6, c7, color );
}

void VisualizeQuad (
    D3DXVECTOR3 topLeft,
    D3DXVECTOR3 bottomRight,
    D3DXCOLOR   color
    )
{
    //
    // Draw a quad between topLeft and bottomRight.
    //
    VisualizeLineSegment( topLeft,
                          D3DXVECTOR3( topLeft.x,
                                       bottomRight.y,
                                       topLeft.z ), color );
    VisualizeLineSegment( D3DXVECTOR3( topLeft.x,
                                       bottomRight.y,
                                       topLeft.z ), bottomRight, color );
    VisualizeLineSegment( bottomRight,
                          D3DXVECTOR3( bottomRight.x,
                                       topLeft.y,
                                       bottomRight.z ), color );
    VisualizeLineSegment( D3DXVECTOR3( bottomRight.x,
                                       topLeft.y,
                                       bottomRight.z ), topLeft, color );
}

void VisualizeLineSegment (
    D3DXVECTOR3 startW,
    D3DXVECTOR3 endW,
    D3DXCOLOR   color
    )
{
    g_pPhysics->m_pDebugDrawer->m_vertices.clear();
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( startW.x, startW.y,
                                                     startW.z ),
                                          btVector3( endW.x, endW.y, endW.z ),
                                          btVector3( color.r, color.g, color.b ),
                                          btVector3( color.r, color.g, color.b ) );
    g_pPhysics->m_pDebugDrawer->DebugPresent();
}

void VisualizeRotation (
    D3DXVECTOR3    posW,
    D3DXQUATERNION rot,
    D3DXCOLOR      colorX,
    D3DXCOLOR      colorY,
    D3DXCOLOR      colorZ
    )
{
    D3DXMATRIX m;

    D3DXMatrixRotationQuaternion( &m, &rot );
    VisualizeRotation( posW, m, colorX, colorY, colorZ );
}

void VisualizeRotation (
    D3DXVECTOR3 posW,
    D3DXMATRIX  m,
    D3DXCOLOR   colorX,
    D3DXCOLOR   colorY,
    D3DXCOLOR   colorZ
    )
{
    D3DXVECTOR3 xAxis = (D3DXVECTOR3( m._11, m._12, m._13 ) * 1) + posW;
    D3DXVECTOR3 yAxis = (D3DXVECTOR3( m._21, m._22, m._23 ) * 1) + posW;
    D3DXVECTOR3 zAxis = (D3DXVECTOR3( m._31, m._32, m._33 ) * 1) + posW;

    g_pPhysics->m_pDebugDrawer->m_vertices.clear();
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( posW.x, posW.y, posW.z ),
                                          btVector3( xAxis.x, xAxis.y, xAxis.z ),
                                          btVector3( colorX.r, colorX.g,
                                                     colorX.b ),
                                          btVector3( colorX.r, colorX.g,
                                                     colorX.b ) );
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( posW.x, posW.y, posW.z ),
                                          btVector3( yAxis.x, yAxis.y, yAxis.z ),
                                          btVector3( colorY.r, colorY.g,
                                                     colorY.b ),
                                          btVector3( colorY.r, colorY.g,
                                                     colorY.b ) );
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( posW.x, posW.y, posW.z ),
                                          btVector3( zAxis.x, zAxis.y, zAxis.z ),
                                          btVector3( colorZ.r, colorZ.g,
                                                     colorZ.b ),
                                          btVector3( colorZ.r, colorZ.g,
                                                     colorZ.b ) );
    g_pPhysics->m_pDebugDrawer->DebugPresent();
}

CDebugDrawer::CDebugDrawer() : m_debugMode(0)
{
}

void CDebugDrawer::DebugPresent ()
{
    if ( !m_vertices.size() )
    {
        return;
    }

    D3DXMATRIX world;
    D3DXMatrixIdentity( &world );
    g_d3dDevice->SetTransform(D3DTS_WORLD, &world);
    HR( g_pRenderStateMgr->SetVertexShader( NULL ) );
    HR( g_pRenderStateMgr->SetPixelShader( NULL ) );
    DWORD m_renderStates[ 256 ];
    g_pRenderStateMgr->SetToDefaults( m_renderStates );
    g_pRenderStateMgr->PostStates( m_renderStates );
    g_pRenderStateMgr->SetRenderState( D3DRS_LIGHTING, FALSE );
    HR( g_pRenderStateMgr->SetVertexDeclaration( VertexCol::Decl ) );
    DWORD vertsToDraw = (DWORD)m_vertices.size();
    DWORD vertOffset = 0;
    DWORD vertChunk;
    while (vertsToDraw)
    {
        vertChunk = min( 16, vertsToDraw );
        g_d3dDevice->DrawPrimitiveUP( D3DPT_LINELIST, (UINT)vertChunk / 2,
                                      &m_vertices[vertOffset],
                                      sizeof(VCol) );
        vertsToDraw -= vertChunk;
        vertOffset += vertChunk;
    }

    m_vertices.clear();
}

void CDebugDrawer::drawLine (
    const btVector3& from,
    const btVector3& to,
    const btVector3& fromColor,
    const btVector3& toColor
    )
{
    D3DXVECTOR3 vFrom, vTo, vCFrom, vCTo;

    memcpy( &vFrom,  &from,      sizeof( D3DXVECTOR3 ) );
    memcpy( &vTo,    &to,        sizeof( D3DXVECTOR3 ) );
    memcpy( &vCFrom, &fromColor, sizeof( D3DXVECTOR3 ) );
    memcpy( &vCTo,   &toColor,   sizeof( D3DXVECTOR3 ) );
    D3DCOLOR cFrom, cTo;
    cFrom =
        D3DCOLOR_ARGB( 0xFF, (DWORD)(vCFrom.x * 255), (DWORD)(vCFrom.y * 255),
                       (DWORD)(vCFrom.z * 255) );
    cTo =
        D3DCOLOR_ARGB( 0xFF, (DWORD)(vCTo.x * 255), (DWORD)(vCTo.y * 255),
                       (DWORD)(vCTo.z * 255) );
    VCol vert[] = {VCol(vFrom, cFrom), VCol(vTo, cTo)};
    m_vertices.push_back( vert[0] );
    m_vertices.push_back( vert[1] );
}

void CDebugDrawer::drawLine (
    const btVector3& from,
    const btVector3& to,
    const btVector3& color
    )
{
    drawLine(from, to, color, color);
}

void CDebugDrawer::drawSphere (
    const btVector3& p,
    btScalar         radius,
    const btVector3& color
    )
{
#if 0
    glColor4f ( color.getX(), color.getY(), color.getZ(), btScalar(1.0f) );
    glPushMatrix ();
    glTranslatef ( p.getX(), p.getY(), p.getZ() );
    int lats = 5;
    int longs = 5;
    int i, j;
    for(i = 0; i <= lats; i++)
    {
        btScalar lat0 = SIMD_PI * (-btScalar(0.5) + (btScalar) (i - 1) / lats);
        btScalar z0 = radius * sin(lat0);
        btScalar zr0 = radius * cos(lat0);
        btScalar lat1 = SIMD_PI * (-btScalar(0.5) + (btScalar) i / lats);
        btScalar z1 = radius * sin(lat1);
        btScalar zr1 = radius * cos(lat1);
        glBegin(GL_QUAD_STRIP);
        for(j = 0; j <= longs; j++)
        {
            btScalar lng = 2 * SIMD_PI * (btScalar) (j - 1) / longs;
            btScalar x = cos(lng);
            btScalar y = sin(lng);
            glNormal3f(x * zr0, y * zr0, z0);
            glVertex3f(x * zr0, y * zr0, z0);
            glNormal3f(x * zr1, y * zr1, z1);
            glVertex3f(x * zr1, y * zr1, z1);
        }

        glEnd();
    }

    glPopMatrix();
#endif
}

void CDebugDrawer::drawBox (
    const btVector3& boxMin,
    const btVector3& boxMax,
    const btVector3& color,
    btScalar         alpha
    )
{
#if 0
    btVector3 halfExtent = (boxMax - boxMin) * btScalar(0.5f);
    btVector3 center = (boxMax + boxMin) * btScalar(0.5f);
    glColor4f (color.getX(), color.getY(), color.getZ(), alpha);
    glPushMatrix ();
    glTranslatef ( center.getX(), center.getY(), center.getZ() );
    glScaled(2 * halfExtent[0], 2 * halfExtent[1], 2 * halfExtent[2]);
    glPopMatrix ();
#endif
}

void CDebugDrawer::drawTriangle (
    const btVector3& a,
    const btVector3& b,
    const btVector3& c,
    const btVector3& color,
    btScalar         alpha
    )
{
#if 0
    const btVector3 n = btCross(b - a,c - a).normalized();
    glBegin(GL_TRIANGLES);
    glColor4f(color.getX(), color.getY(), color.getZ(),alpha);
    glNormal3d( n.getX(),n.getY(),n.getZ() );
    glVertex3d( a.getX(),a.getY(),a.getZ() );
    glVertex3d( b.getX(),b.getY(),b.getZ() );
    glVertex3d( c.getX(),c.getY(),c.getZ() );
    glEnd();
#endif
}

void CDebugDrawer::setDebugMode (int debugMode)
{
    m_debugMode = debugMode;
}

void CDebugDrawer::draw3dText (
    const btVector3& location,
    const char*      textString
    )
{
#if 0
    glRasterPos3f( location.x(),  location.y(),  location.z() );
#endif
}

void CDebugDrawer::reportErrorWarning (const char* warningString)
{
    OutputDebugStringA( warningString );
    OutputDebugStringA( "\n" );
}

void CDebugDrawer::drawContactPoint (
    const btVector3& pointOnB,
    const btVector3& normalOnB,
    btScalar         distance,
    int              lifeTime,
    const btVector3& color
    )
{
#if 0
    btVector3 to = pointOnB + normalOnB * distance;
    const btVector3&from = pointOnB;
    glColor4f(color.getX(), color.getY(), color.getZ(),1.f);
    glBegin(GL_LINES);
    glVertex3d( from.getX(), from.getY(), from.getZ() );
    glVertex3d( to.getX(), to.getY(), to.getZ() );
    glEnd();
    glRasterPos3f( from.x(),  from.y(),  from.z() );
    char buf[12];
    sprintf(buf," %d",lifeTime);
#endif
}

You can create collision objects from your own model data in many ways. One way to do it is to treat your models as indexed triangle lists and use. Be aware that your indices must match the size given below (i.e. either 16 or 32-bit indices - the example below uses 16-bit).

 

pMesh->m_pTriMesh = new btTriangleIndexVertexArray();
btIndexedMesh iMesh;
iMesh.m_numTriangles = pMesh->m_numFaces;
iMesh.m_triangleIndexBase = (const unsigned char *)pMesh->m_pIndices;
iMesh.m_triangleIndexStride = 3 * sizeof(IndexFormat);
iMesh.m_numVertices = pMesh->m_numVertices;
iMesh.m_vertexBase = (const unsigned char *)pMesh->m_pVertices;
iMesh.m_vertexStride = sizeof(D3DXVECTOR3);
pMesh->m_pTriMesh->addIndexedMesh( iMesh, PHY_SHORT );
pMesh->m_pTriShape = new btBvhTriangleMeshShape( pMesh->m_pTriMesh, false, true );

 

The basic process is to create a CollisionShape and then insert that as a rigid body as mentioned above. Other possible collision shapes are:

 

btHeightfieldTerrainShape,

btScaledBvhTriangleMeshShape

 

and of course the primitive shapes, btSphereShape, btCylinderShape, btBoxShape, etc.


#3Steve_Segreto

Posted 03 April 2013 - 12:12 AM

I have integrated Bullet Physics into a D3D9 class engine and it is not that difficult. Let me share an overview of Bullet, I may be glossing over many details, please refer to the Wiki page and other web resources as well.

 

You start by creating an object that derives from btCollisionWorld, like btDiscreteDynamicsWorld. You can tick this object using the stepSimulation member, which will basically identify all contacts between "collision" objects and update their positions based on physical properties like gravity, mass, etc.

 

Collision objects fall into two classes (well three if you consider the character controller), rigid bodies, soft bodies and kinematic objects. You can add immovable (static) collision objects by setting the mass to a special constant (0.0f). You add rigid bodies using the addRigidBody member of your collision world object. You can do ray testing against the objects in your world using the rayTest() member of the collision world object.

 

When first creating your collision world, you need to select and specify a collision dispatcher, a broadphase object, a constraint solver and some config data. Your program needs to allocate and de-allocate all objects and memory passed to Bullet, the library does not own any pointers provided to it.

 

The choice of broadphase object can determine how well the collision world responds to very dynamic rigid bodies changing position every frame. You can overload both broadphase and nearphase collision responses and filters (so you can make a player rigid body collide with nothing but the ground, but make every other rigid body bounce off the player, for instance).

 

You can also declare a debug drawer and provide a D3D9 implementation to help you visualize the collision world and the collision objects as you place them in the world.

 

Here's the debug drawer I use, maybe it would help you?

 

//-----------------------------------------------------------------------------
// File: CDebugDrawer.h
//
// Purpose: A debug drawer used by the physics library.
//
// Copyright (c) 2007-2011 Steve Segreto. All rights reserved.
//-----------------------------------------------------------------------------
#pragma once
#include "LinearMath/btIDebugDraw.h"
#include <vector>
struct VCol
{
    VCol(
        const D3DXVECTOR3& v,
        D3DCOLOR           c
        ) : pos(v),col(c)
    {
    }
    D3DXVECTOR3 pos;
    D3DCOLOR col;
};
void VisualizeRay (
    D3DXVECTOR3 rayStartW,
    D3DXVECTOR3 rayDirW,
    D3DXCOLOR   color
    );
void VisualizeLineSegment (
    D3DXVECTOR3 startW,
    D3DXVECTOR3 endW,
    D3DXCOLOR   color
    );
void VisualizeBox (
    struct AABB* box,
    D3DXCOLOR color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f )
    );
void VisualizeBox (
    struct OBB* box,
    D3DXCOLOR color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f )
    );
void VisualizeQuad (
    D3DXVECTOR3 topLeft,
    D3DXVECTOR3 bottomRight,
    D3DXCOLOR color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f )
    );
void VisualizeFrustum (
    D3DXVECTOR3* corners,
    D3DXCOLOR    color
    );
void VisualizeRotation (
    D3DXVECTOR3 posW,
    D3DXQUATERNION rot,
    D3DXCOLOR colorX = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f),
    D3DXCOLOR colorY = D3DXCOLOR(1.0f, 1.0f, 0.0f, 1.0f),
    D3DXCOLOR colorZ = D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)
    );
void VisualizeRotation (
    D3DXVECTOR3 posW,
    D3DXMATRIX rot,
    D3DXCOLOR colorX = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f),
    D3DXCOLOR colorY = D3DXCOLOR(1.0f, 1.0f, 0.0f, 1.0f),
    D3DXCOLOR colorZ = D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)
    );
class CDebugDrawer : public btIDebugDraw
{
public:
    int m_debugMode;
    std::vector< VCol > m_vertices;
    CDebugDrawer();
    void DebugPresent ();
    virtual void drawLine (
        const btVector3& from,
        const btVector3& to,
        const btVector3& fromColor,
        const btVector3& toColor
        );
    virtual void drawLine (
        const btVector3& from,
        const btVector3& to,
        const btVector3& color
        );
    virtual void drawSphere (
        const btVector3& p,
        btScalar         radius,
        const btVector3& color
        );
    virtual void drawBox (
        const btVector3& boxMin,
        const btVector3& boxMax,
        const btVector3& color,
        btScalar         alpha
        );
    virtual void drawTriangle (
        const btVector3& a,
        const btVector3& b,
        const btVector3& c,
        const btVector3& color,
        btScalar         alpha
        );
    virtual void drawContactPoint (
        const btVector3& PointOnB,
        const btVector3& normalOnB,
        btScalar         distance,
        int              lifeTime,
        const btVector3& color
        );
    virtual void reportErrorWarning (const char* warningString);
    virtual void draw3dText (
        const btVector3& location,
        const char*      textString
        );
    virtual void setDebugMode (int debugMode);
    virtual int getDebugMode () const
    {
        return m_debugMode;
    }
};
//-----------------------------------------------------------------------------
// File: CDebugDrawer.cpp
//
// Purpose: A debug drawer used by the physics library.
//
// Copyright (c) 2007-2011 Steve Segreto. All rights reserved.
//-----------------------------------------------------------------------------
#include "Global.h"
#include "CRenderable.h"
#include "CVertexManager.h"
#include "CDebugDrawer.h"
extern CPhysicsEngine* g_pPhysics;
void VisualizeFrustum (
    D3DXVECTOR3* corners,
    D3DXCOLOR    color
    )
{
    VisualizeLineSegment( corners[ 4 ], corners[ 5 ], color );
    VisualizeLineSegment( corners[ 7 ], corners[ 6 ], color );
    VisualizeLineSegment( corners[ 4 ], corners[ 7 ], color );
    VisualizeLineSegment( corners[ 5 ], corners[ 6 ], color );
    VisualizeLineSegment( corners[ 0 ], corners[ 1 ], color );
    VisualizeLineSegment( corners[ 3 ], corners[ 2 ], color );
    VisualizeLineSegment( corners[ 0 ], corners[ 3 ], color );
    VisualizeLineSegment( corners[ 1 ], corners[ 2 ], color );
    VisualizeLineSegment( corners[ 0 ], corners[ 4 ], color );
    VisualizeLineSegment( corners[ 1 ], corners[ 5 ], color );
    VisualizeLineSegment( corners[ 2 ], corners[ 6 ], color );
    VisualizeLineSegment( corners[ 3 ], corners[ 7 ], color );
}

void VisualizeRay (
    D3DXVECTOR3 rayStartW,
    D3DXVECTOR3 rayDirW,
    D3DXCOLOR   color
    )
{
    D3DXVECTOR3 rayToW = (rayDirW * 1000) + rayStartW;

    g_pPhysics->m_pDebugDrawer->m_vertices.clear();
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( rayStartW.x, rayStartW.y,
                                                     rayStartW.z ),
                                          btVector3( rayToW.x, rayToW.y,
                                                     rayToW.z ),
                                          btVector3( color.r, color.g, color.b ),
                                          btVector3( color.r, color.g, color.b ) );
    g_pPhysics->m_pDebugDrawer->DebugPresent();
}

void VisualizeBox (
    AABB*     box,
    D3DXCOLOR color
    )
{
    //
    // Draw a box using 4 quads
    //
    D3DXVECTOR3 c0 = D3DXVECTOR3( box->maxPt.x, box->maxPt.y, box->maxPt.z );
    D3DXVECTOR3 c1 = D3DXVECTOR3( box->maxPt.x, box->minPt.y, box->maxPt.z );
    D3DXVECTOR3 c2 = D3DXVECTOR3( box->maxPt.x, box->maxPt.y, box->minPt.z );
    D3DXVECTOR3 c3 = D3DXVECTOR3( box->minPt.x, box->maxPt.y, box->maxPt.z );
    D3DXVECTOR3 c4 = D3DXVECTOR3( box->maxPt.x, box->minPt.y, box->minPt.z );
    D3DXVECTOR3 c5 = D3DXVECTOR3( box->minPt.x, box->maxPt.y, box->minPt.z );
    D3DXVECTOR3 c6 = D3DXVECTOR3( box->minPt.x, box->minPt.y, box->maxPt.z );
    D3DXVECTOR3 c7 = D3DXVECTOR3( box->minPt.x, box->minPt.y, box->minPt.z );

    VisualizeLineSegment( c0, c3, color );
    VisualizeLineSegment( c0, c1, color );
    VisualizeLineSegment( c0, c2, color );
    VisualizeLineSegment( c3, c5, color );
    VisualizeLineSegment( c3, c6, color );
    VisualizeLineSegment( c1, c4, color );
    VisualizeLineSegment( c1, c6, color );
    VisualizeLineSegment( c2, c5, color );
    VisualizeLineSegment( c2, c4, color );
    VisualizeLineSegment( c4, c7, color );
    VisualizeLineSegment( c5, c7, color );
    VisualizeLineSegment( c6, c7, color );
}

void VisualizeBox (
    OBB*      box,
    D3DXCOLOR color
    )
{
    //
    // Draw a box using 4 quads
    //
    D3DXVECTOR3 c0 = box->m_objectBounds[ 7 ];
    D3DXVECTOR3 c1 = box->m_objectBounds[ 5 ];
    D3DXVECTOR3 c2 = box->m_objectBounds[ 3 ];
    D3DXVECTOR3 c3 = box->m_objectBounds[ 6 ];
    D3DXVECTOR3 c4 = box->m_objectBounds[ 1 ];
    D3DXVECTOR3 c5 = box->m_objectBounds[ 2 ];
    D3DXVECTOR3 c6 = box->m_objectBounds[ 4 ];
    D3DXVECTOR3 c7 = box->m_objectBounds[ 0 ];

    VisualizeLineSegment( c0, c3, color );
    VisualizeLineSegment( c0, c1, color );
    VisualizeLineSegment( c0, c2, color );
    VisualizeLineSegment( c3, c5, color );
    VisualizeLineSegment( c3, c6, color );
    VisualizeLineSegment( c1, c4, color );
    VisualizeLineSegment( c1, c6, color );
    VisualizeLineSegment( c2, c5, color );
    VisualizeLineSegment( c2, c4, color );
    VisualizeLineSegment( c4, c7, color );
    VisualizeLineSegment( c5, c7, color );
    VisualizeLineSegment( c6, c7, color );
}

void VisualizeQuad (
    D3DXVECTOR3 topLeft,
    D3DXVECTOR3 bottomRight,
    D3DXCOLOR   color
    )
{
    //
    // Draw a quad between topLeft and bottomRight.
    //
    VisualizeLineSegment( topLeft,
                          D3DXVECTOR3( topLeft.x,
                                       bottomRight.y,
                                       topLeft.z ), color );
    VisualizeLineSegment( D3DXVECTOR3( topLeft.x,
                                       bottomRight.y,
                                       topLeft.z ), bottomRight, color );
    VisualizeLineSegment( bottomRight,
                          D3DXVECTOR3( bottomRight.x,
                                       topLeft.y,
                                       bottomRight.z ), color );
    VisualizeLineSegment( D3DXVECTOR3( bottomRight.x,
                                       topLeft.y,
                                       bottomRight.z ), topLeft, color );
}

void VisualizeLineSegment (
    D3DXVECTOR3 startW,
    D3DXVECTOR3 endW,
    D3DXCOLOR   color
    )
{
    g_pPhysics->m_pDebugDrawer->m_vertices.clear();
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( startW.x, startW.y,
                                                     startW.z ),
                                          btVector3( endW.x, endW.y, endW.z ),
                                          btVector3( color.r, color.g, color.b ),
                                          btVector3( color.r, color.g, color.b ) );
    g_pPhysics->m_pDebugDrawer->DebugPresent();
}

void VisualizeRotation (
    D3DXVECTOR3    posW,
    D3DXQUATERNION rot,
    D3DXCOLOR      colorX,
    D3DXCOLOR      colorY,
    D3DXCOLOR      colorZ
    )
{
    D3DXMATRIX m;

    D3DXMatrixRotationQuaternion( &m, &rot );
    VisualizeRotation( posW, m, colorX, colorY, colorZ );
}

void VisualizeRotation (
    D3DXVECTOR3 posW,
    D3DXMATRIX  m,
    D3DXCOLOR   colorX,
    D3DXCOLOR   colorY,
    D3DXCOLOR   colorZ
    )
{
    D3DXVECTOR3 xAxis = (D3DXVECTOR3( m._11, m._12, m._13 ) * 1) + posW;
    D3DXVECTOR3 yAxis = (D3DXVECTOR3( m._21, m._22, m._23 ) * 1) + posW;
    D3DXVECTOR3 zAxis = (D3DXVECTOR3( m._31, m._32, m._33 ) * 1) + posW;

    g_pPhysics->m_pDebugDrawer->m_vertices.clear();
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( posW.x, posW.y, posW.z ),
                                          btVector3( xAxis.x, xAxis.y, xAxis.z ),
                                          btVector3( colorX.r, colorX.g,
                                                     colorX.b ),
                                          btVector3( colorX.r, colorX.g,
                                                     colorX.b ) );
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( posW.x, posW.y, posW.z ),
                                          btVector3( yAxis.x, yAxis.y, yAxis.z ),
                                          btVector3( colorY.r, colorY.g,
                                                     colorY.b ),
                                          btVector3( colorY.r, colorY.g,
                                                     colorY.b ) );
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( posW.x, posW.y, posW.z ),
                                          btVector3( zAxis.x, zAxis.y, zAxis.z ),
                                          btVector3( colorZ.r, colorZ.g,
                                                     colorZ.b ),
                                          btVector3( colorZ.r, colorZ.g,
                                                     colorZ.b ) );
    g_pPhysics->m_pDebugDrawer->DebugPresent();
}

CDebugDrawer::CDebugDrawer() : m_debugMode(0)
{
}

void CDebugDrawer::DebugPresent ()
{
    if ( !m_vertices.size() )
    {
        return;
    }

    D3DXMATRIX world;
    D3DXMatrixIdentity( &world );
    g_d3dDevice->SetTransform(D3DTS_WORLD, &world);
    HR( g_pRenderStateMgr->SetVertexShader( NULL ) );
    HR( g_pRenderStateMgr->SetPixelShader( NULL ) );
    DWORD m_renderStates[ 256 ];
    g_pRenderStateMgr->SetToDefaults( m_renderStates );
    g_pRenderStateMgr->PostStates( m_renderStates );
    g_pRenderStateMgr->SetRenderState( D3DRS_LIGHTING, FALSE );
    HR( g_pRenderStateMgr->SetVertexDeclaration( VertexCol::Decl ) );
    DWORD vertsToDraw = (DWORD)m_vertices.size();
    DWORD vertOffset = 0;
    DWORD vertChunk;
    while (vertsToDraw)
    {
        vertChunk = min( 16, vertsToDraw );
        g_d3dDevice->DrawPrimitiveUP( D3DPT_LINELIST, (UINT)vertChunk / 2,
                                      &m_vertices[vertOffset],
                                      sizeof(VCol) );
        vertsToDraw -= vertChunk;
        vertOffset += vertChunk;
    }

    m_vertices.clear();
}

void CDebugDrawer::drawLine (
    const btVector3& from,
    const btVector3& to,
    const btVector3& fromColor,
    const btVector3& toColor
    )
{
    D3DXVECTOR3 vFrom, vTo, vCFrom, vCTo;

    memcpy( &vFrom,  &from,      sizeof( D3DXVECTOR3 ) );
    memcpy( &vTo,    &to,        sizeof( D3DXVECTOR3 ) );
    memcpy( &vCFrom, &fromColor, sizeof( D3DXVECTOR3 ) );
    memcpy( &vCTo,   &toColor,   sizeof( D3DXVECTOR3 ) );
    D3DCOLOR cFrom, cTo;
    cFrom =
        D3DCOLOR_ARGB( 0xFF, (DWORD)(vCFrom.x * 255), (DWORD)(vCFrom.y * 255),
                       (DWORD)(vCFrom.z * 255) );
    cTo =
        D3DCOLOR_ARGB( 0xFF, (DWORD)(vCTo.x * 255), (DWORD)(vCTo.y * 255),
                       (DWORD)(vCTo.z * 255) );
    VCol vert[] = {VCol(vFrom, cFrom), VCol(vTo, cTo)};
    m_vertices.push_back( vert[0] );
    m_vertices.push_back( vert[1] );
}

void CDebugDrawer::drawLine (
    const btVector3& from,
    const btVector3& to,
    const btVector3& color
    )
{
    drawLine(from, to, color, color);
}

void CDebugDrawer::drawSphere (
    const btVector3& p,
    btScalar         radius,
    const btVector3& color
    )
{
#if 0
    glColor4f ( color.getX(), color.getY(), color.getZ(), btScalar(1.0f) );
    glPushMatrix ();
    glTranslatef ( p.getX(), p.getY(), p.getZ() );
    int lats = 5;
    int longs = 5;
    int i, j;
    for(i = 0; i <= lats; i++)
    {
        btScalar lat0 = SIMD_PI * (-btScalar(0.5) + (btScalar) (i - 1) / lats);
        btScalar z0 = radius * sin(lat0);
        btScalar zr0 = radius * cos(lat0);
        btScalar lat1 = SIMD_PI * (-btScalar(0.5) + (btScalar) i / lats);
        btScalar z1 = radius * sin(lat1);
        btScalar zr1 = radius * cos(lat1);
        glBegin(GL_QUAD_STRIP);
        for(j = 0; j <= longs; j++)
        {
            btScalar lng = 2 * SIMD_PI * (btScalar) (j - 1) / longs;
            btScalar x = cos(lng);
            btScalar y = sin(lng);
            glNormal3f(x * zr0, y * zr0, z0);
            glVertex3f(x * zr0, y * zr0, z0);
            glNormal3f(x * zr1, y * zr1, z1);
            glVertex3f(x * zr1, y * zr1, z1);
        }

        glEnd();
    }

    glPopMatrix();
#endif
}

void CDebugDrawer::drawBox (
    const btVector3& boxMin,
    const btVector3& boxMax,
    const btVector3& color,
    btScalar         alpha
    )
{
#if 0
    btVector3 halfExtent = (boxMax - boxMin) * btScalar(0.5f);
    btVector3 center = (boxMax + boxMin) * btScalar(0.5f);
    glColor4f (color.getX(), color.getY(), color.getZ(), alpha);
    glPushMatrix ();
    glTranslatef ( center.getX(), center.getY(), center.getZ() );
    glScaled(2 * halfExtent[0], 2 * halfExtent[1], 2 * halfExtent[2]);
    glPopMatrix ();
#endif
}

void CDebugDrawer::drawTriangle (
    const btVector3& a,
    const btVector3& b,
    const btVector3& c,
    const btVector3& color,
    btScalar         alpha
    )
{
#if 0
    const btVector3 n = btCross(b - a,c - a).normalized();
    glBegin(GL_TRIANGLES);
    glColor4f(color.getX(), color.getY(), color.getZ(),alpha);
    glNormal3d( n.getX(),n.getY(),n.getZ() );
    glVertex3d( a.getX(),a.getY(),a.getZ() );
    glVertex3d( b.getX(),b.getY(),b.getZ() );
    glVertex3d( c.getX(),c.getY(),c.getZ() );
    glEnd();
#endif
}

void CDebugDrawer::setDebugMode (int debugMode)
{
    m_debugMode = debugMode;
}

void CDebugDrawer::draw3dText (
    const btVector3& location,
    const char*      textString
    )
{
#if 0
    glRasterPos3f( location.x(),  location.y(),  location.z() );
#endif
}

void CDebugDrawer::reportErrorWarning (const char* warningString)
{
    OutputDebugStringA( warningString );
    OutputDebugStringA( "\n" );
}

void CDebugDrawer::drawContactPoint (
    const btVector3& pointOnB,
    const btVector3& normalOnB,
    btScalar         distance,
    int              lifeTime,
    const btVector3& color
    )
{
#if 0
    btVector3 to = pointOnB + normalOnB * distance;
    const btVector3&from = pointOnB;
    glColor4f(color.getX(), color.getY(), color.getZ(),1.f);
    glBegin(GL_LINES);
    glVertex3d( from.getX(), from.getY(), from.getZ() );
    glVertex3d( to.getX(), to.getY(), to.getZ() );
    glEnd();
    glRasterPos3f( from.x(),  from.y(),  from.z() );
    char buf[12];
    sprintf(buf," %d",lifeTime);
#endif
}

You can create collision objects from your own model data in many ways. One way to do it is to treat your models as indexed triangle lists and use. Be aware that your indices must match the size given below (i.e. either 16 or 32-bit indices - the example below uses 16-bit).

 

[code[

pMesh->m_pTriMesh = new btTriangleIndexVertexArray();

btIndexedMesh iMesh;

iMesh.m_numTriangles = pMesh->m_numFaces;

iMesh.m_triangleIndexBase = (const unsigned char *)pMesh->m_pIndices;

iMesh.m_triangleIndexStride = 3 * sizeof(IndexFormat);

iMesh.m_numVertices = pMesh->m_numVertices;

iMesh.m_vertexBase = (const unsigned char *)pMesh->m_pVertices;

iMesh.m_vertexStride = sizeof(D3DXVECTOR3);

pMesh->m_pTriMesh->addIndexedMesh( iMesh, PHY_SHORT );

pMesh->m_pTriShape = new btBvhTriangleMeshShape( pMesh->m_pTriMesh, false, true );

[/code]

 

The basic process is to create a CollisionShape and then insert that as a rigid body as mentioned above. Other possible collision shapes are:

 

btHeightfieldTerrainShape,

btScaledBvhTriangleMeshShape

 

and of course the primitive shapes, btSphereShape, btCylinderShape, btBoxShape, etc.


#2Steve_Segreto

Posted 03 April 2013 - 12:02 AM

I have integrated Bullet Physics into a D3D9 class engine and it is not that difficult. Let me share an overview of Bullet, I may be glossing over many details, please refer to the Wiki page and other web resources as well.

 

You start by creating an object that derives from btCollisionWorld, like btDiscreteDynamicsWorld. You can tick this object using the stepSimulation member, which will basically identify all contacts between "collision" objects and update their positions based on physical properties like gravity, mass, etc.

 

Collision objects fall into two classes (well three if you consider the character controller), rigid bodies, soft bodies and kinematic objects. You can add immovable (static) collision objects by setting the mass to a special constant (0.0f). You add rigid bodies using the addRigidBody member of your collision world object. You can do ray testing against the objects in your world using the rayTest() member of the collision world object.

 

When first creating your collision world, you need to select and specify a collision dispatcher, a broadphase object, a constraint solver and some config data. Your program needs to allocate and de-allocate all objects and memory passed to Bullet, the library does not own any pointers provided to it.

 

The choice of broadphase object can determine how well the collision world responds to very dynamic rigid bodies changing position every frame. You can overload both broadphase and nearphase collision responses and filters (so you can make a player rigid body collide with nothing but the ground, but make every other rigid body bounce off the player, for instance).

 

You can also declare a debug drawer and provide a D3D9 implementation to help you visualize the collision world and the collision objects as you place them in the world.

 

Here's the debug drawer I use, maybe it would help you?

 

//-----------------------------------------------------------------------------
// File: CDebugDrawer.h
//
// Purpose: A debug drawer used by the physics library.
//
// Copyright (c) 2007-2011 Steve Segreto. All rights reserved.
//-----------------------------------------------------------------------------
#pragma once
#include "LinearMath/btIDebugDraw.h"
#include <vector>
struct VCol
{
    VCol(
        const D3DXVECTOR3& v,
        D3DCOLOR           c
        ) : pos(v),col(c)
    {
    }
    D3DXVECTOR3 pos;
    D3DCOLOR col;
};
void VisualizeRay (
    D3DXVECTOR3 rayStartW,
    D3DXVECTOR3 rayDirW,
    D3DXCOLOR   color
    );
void VisualizeLineSegment (
    D3DXVECTOR3 startW,
    D3DXVECTOR3 endW,
    D3DXCOLOR   color
    );
void VisualizeBox (
    struct AABB* box,
    D3DXCOLOR color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f )
    );
void VisualizeBox (
    struct OBB* box,
    D3DXCOLOR color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f )
    );
void VisualizeQuad (
    D3DXVECTOR3 topLeft,
    D3DXVECTOR3 bottomRight,
    D3DXCOLOR color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f )
    );
void VisualizeFrustum (
    D3DXVECTOR3* corners,
    D3DXCOLOR    color
    );
void VisualizeRotation (
    D3DXVECTOR3 posW,
    D3DXQUATERNION rot,
    D3DXCOLOR colorX = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f),
    D3DXCOLOR colorY = D3DXCOLOR(1.0f, 1.0f, 0.0f, 1.0f),
    D3DXCOLOR colorZ = D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)
    );
void VisualizeRotation (
    D3DXVECTOR3 posW,
    D3DXMATRIX rot,
    D3DXCOLOR colorX = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f),
    D3DXCOLOR colorY = D3DXCOLOR(1.0f, 1.0f, 0.0f, 1.0f),
    D3DXCOLOR colorZ = D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)
    );
class CDebugDrawer : public btIDebugDraw
{
public:
    int m_debugMode;
    std::vector< VCol > m_vertices;
    CDebugDrawer();
    void DebugPresent ();
    virtual void drawLine (
        const btVector3& from,
        const btVector3& to,
        const btVector3& fromColor,
        const btVector3& toColor
        );
    virtual void drawLine (
        const btVector3& from,
        const btVector3& to,
        const btVector3& color
        );
    virtual void drawSphere (
        const btVector3& p,
        btScalar         radius,
        const btVector3& color
        );
    virtual void drawBox (
        const btVector3& boxMin,
        const btVector3& boxMax,
        const btVector3& color,
        btScalar         alpha
        );
    virtual void drawTriangle (
        const btVector3& a,
        const btVector3& b,
        const btVector3& c,
        const btVector3& color,
        btScalar         alpha
        );
    virtual void drawContactPoint (
        const btVector3& PointOnB,
        const btVector3& normalOnB,
        btScalar         distance,
        int              lifeTime,
        const btVector3& color
        );
    virtual void reportErrorWarning (const char* warningString);
    virtual void draw3dText (
        const btVector3& location,
        const char*      textString
        );
    virtual void setDebugMode (int debugMode);
    virtual int getDebugMode () const
    {
        return m_debugMode;
    }
};
//-----------------------------------------------------------------------------
// File: CDebugDrawer.cpp
//
// Purpose: A debug drawer used by the physics library.
//
// Copyright (c) 2007-2011 Steve Segreto. All rights reserved.
//-----------------------------------------------------------------------------
#include "Global.h"
#include "CRenderable.h"
#include "CVertexManager.h"
#include "CDebugDrawer.h"
extern CPhysicsEngine* g_pPhysics;
void VisualizeFrustum (
    D3DXVECTOR3* corners,
    D3DXCOLOR    color
    )
{
    VisualizeLineSegment( corners[ 4 ], corners[ 5 ], color );
    VisualizeLineSegment( corners[ 7 ], corners[ 6 ], color );
    VisualizeLineSegment( corners[ 4 ], corners[ 7 ], color );
    VisualizeLineSegment( corners[ 5 ], corners[ 6 ], color );
    VisualizeLineSegment( corners[ 0 ], corners[ 1 ], color );
    VisualizeLineSegment( corners[ 3 ], corners[ 2 ], color );
    VisualizeLineSegment( corners[ 0 ], corners[ 3 ], color );
    VisualizeLineSegment( corners[ 1 ], corners[ 2 ], color );
    VisualizeLineSegment( corners[ 0 ], corners[ 4 ], color );
    VisualizeLineSegment( corners[ 1 ], corners[ 5 ], color );
    VisualizeLineSegment( corners[ 2 ], corners[ 6 ], color );
    VisualizeLineSegment( corners[ 3 ], corners[ 7 ], color );
}

void VisualizeRay (
    D3DXVECTOR3 rayStartW,
    D3DXVECTOR3 rayDirW,
    D3DXCOLOR   color
    )
{
    D3DXVECTOR3 rayToW = (rayDirW * 1000) + rayStartW;

    g_pPhysics->m_pDebugDrawer->m_vertices.clear();
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( rayStartW.x, rayStartW.y,
                                                     rayStartW.z ),
                                          btVector3( rayToW.x, rayToW.y,
                                                     rayToW.z ),
                                          btVector3( color.r, color.g, color.b ),
                                          btVector3( color.r, color.g, color.b ) );
    g_pPhysics->m_pDebugDrawer->DebugPresent();
}

void VisualizeBox (
    AABB*     box,
    D3DXCOLOR color
    )
{
    //
    // Draw a box using 4 quads
    //
    D3DXVECTOR3 c0 = D3DXVECTOR3( box->maxPt.x, box->maxPt.y, box->maxPt.z );
    D3DXVECTOR3 c1 = D3DXVECTOR3( box->maxPt.x, box->minPt.y, box->maxPt.z );
    D3DXVECTOR3 c2 = D3DXVECTOR3( box->maxPt.x, box->maxPt.y, box->minPt.z );
    D3DXVECTOR3 c3 = D3DXVECTOR3( box->minPt.x, box->maxPt.y, box->maxPt.z );
    D3DXVECTOR3 c4 = D3DXVECTOR3( box->maxPt.x, box->minPt.y, box->minPt.z );
    D3DXVECTOR3 c5 = D3DXVECTOR3( box->minPt.x, box->maxPt.y, box->minPt.z );
    D3DXVECTOR3 c6 = D3DXVECTOR3( box->minPt.x, box->minPt.y, box->maxPt.z );
    D3DXVECTOR3 c7 = D3DXVECTOR3( box->minPt.x, box->minPt.y, box->minPt.z );

    VisualizeLineSegment( c0, c3, color );
    VisualizeLineSegment( c0, c1, color );
    VisualizeLineSegment( c0, c2, color );
    VisualizeLineSegment( c3, c5, color );
    VisualizeLineSegment( c3, c6, color );
    VisualizeLineSegment( c1, c4, color );
    VisualizeLineSegment( c1, c6, color );
    VisualizeLineSegment( c2, c5, color );
    VisualizeLineSegment( c2, c4, color );
    VisualizeLineSegment( c4, c7, color );
    VisualizeLineSegment( c5, c7, color );
    VisualizeLineSegment( c6, c7, color );
}

void VisualizeBox (
    OBB*      box,
    D3DXCOLOR color
    )
{
    //
    // Draw a box using 4 quads
    //
    D3DXVECTOR3 c0 = box->m_objectBounds[ 7 ];
    D3DXVECTOR3 c1 = box->m_objectBounds[ 5 ];
    D3DXVECTOR3 c2 = box->m_objectBounds[ 3 ];
    D3DXVECTOR3 c3 = box->m_objectBounds[ 6 ];
    D3DXVECTOR3 c4 = box->m_objectBounds[ 1 ];
    D3DXVECTOR3 c5 = box->m_objectBounds[ 2 ];
    D3DXVECTOR3 c6 = box->m_objectBounds[ 4 ];
    D3DXVECTOR3 c7 = box->m_objectBounds[ 0 ];

    VisualizeLineSegment( c0, c3, color );
    VisualizeLineSegment( c0, c1, color );
    VisualizeLineSegment( c0, c2, color );
    VisualizeLineSegment( c3, c5, color );
    VisualizeLineSegment( c3, c6, color );
    VisualizeLineSegment( c1, c4, color );
    VisualizeLineSegment( c1, c6, color );
    VisualizeLineSegment( c2, c5, color );
    VisualizeLineSegment( c2, c4, color );
    VisualizeLineSegment( c4, c7, color );
    VisualizeLineSegment( c5, c7, color );
    VisualizeLineSegment( c6, c7, color );
}

void VisualizeQuad (
    D3DXVECTOR3 topLeft,
    D3DXVECTOR3 bottomRight,
    D3DXCOLOR   color
    )
{
    //
    // Draw a quad between topLeft and bottomRight.
    //
    VisualizeLineSegment( topLeft,
                          D3DXVECTOR3( topLeft.x,
                                       bottomRight.y,
                                       topLeft.z ), color );
    VisualizeLineSegment( D3DXVECTOR3( topLeft.x,
                                       bottomRight.y,
                                       topLeft.z ), bottomRight, color );
    VisualizeLineSegment( bottomRight,
                          D3DXVECTOR3( bottomRight.x,
                                       topLeft.y,
                                       bottomRight.z ), color );
    VisualizeLineSegment( D3DXVECTOR3( bottomRight.x,
                                       topLeft.y,
                                       bottomRight.z ), topLeft, color );
}

void VisualizeLineSegment (
    D3DXVECTOR3 startW,
    D3DXVECTOR3 endW,
    D3DXCOLOR   color
    )
{
    g_pPhysics->m_pDebugDrawer->m_vertices.clear();
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( startW.x, startW.y,
                                                     startW.z ),
                                          btVector3( endW.x, endW.y, endW.z ),
                                          btVector3( color.r, color.g, color.b ),
                                          btVector3( color.r, color.g, color.b ) );
    g_pPhysics->m_pDebugDrawer->DebugPresent();
}

void VisualizeRotation (
    D3DXVECTOR3    posW,
    D3DXQUATERNION rot,
    D3DXCOLOR      colorX,
    D3DXCOLOR      colorY,
    D3DXCOLOR      colorZ
    )
{
    D3DXMATRIX m;

    D3DXMatrixRotationQuaternion( &m, &rot );
    VisualizeRotation( posW, m, colorX, colorY, colorZ );
}

void VisualizeRotation (
    D3DXVECTOR3 posW,
    D3DXMATRIX  m,
    D3DXCOLOR   colorX,
    D3DXCOLOR   colorY,
    D3DXCOLOR   colorZ
    )
{
    D3DXVECTOR3 xAxis = (D3DXVECTOR3( m._11, m._12, m._13 ) * 1) + posW;
    D3DXVECTOR3 yAxis = (D3DXVECTOR3( m._21, m._22, m._23 ) * 1) + posW;
    D3DXVECTOR3 zAxis = (D3DXVECTOR3( m._31, m._32, m._33 ) * 1) + posW;

    g_pPhysics->m_pDebugDrawer->m_vertices.clear();
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( posW.x, posW.y, posW.z ),
                                          btVector3( xAxis.x, xAxis.y, xAxis.z ),
                                          btVector3( colorX.r, colorX.g,
                                                     colorX.b ),
                                          btVector3( colorX.r, colorX.g,
                                                     colorX.b ) );
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( posW.x, posW.y, posW.z ),
                                          btVector3( yAxis.x, yAxis.y, yAxis.z ),
                                          btVector3( colorY.r, colorY.g,
                                                     colorY.b ),
                                          btVector3( colorY.r, colorY.g,
                                                     colorY.b ) );
    g_pPhysics->m_pDebugDrawer->drawLine( btVector3( posW.x, posW.y, posW.z ),
                                          btVector3( zAxis.x, zAxis.y, zAxis.z ),
                                          btVector3( colorZ.r, colorZ.g,
                                                     colorZ.b ),
                                          btVector3( colorZ.r, colorZ.g,
                                                     colorZ.b ) );
    g_pPhysics->m_pDebugDrawer->DebugPresent();
}

CDebugDrawer::CDebugDrawer() : m_debugMode(0)
{
}

void CDebugDrawer::DebugPresent ()
{
    if ( !m_vertices.size() )
    {
        return;
    }

    D3DXMATRIX world;
    D3DXMatrixIdentity( &world );
    g_d3dDevice->SetTransform(D3DTS_WORLD, &world);
    HR( g_pRenderStateMgr->SetVertexShader( NULL ) );
    HR( g_pRenderStateMgr->SetPixelShader( NULL ) );
    DWORD m_renderStates[ 256 ];
    g_pRenderStateMgr->SetToDefaults( m_renderStates );
    g_pRenderStateMgr->PostStates( m_renderStates );
    g_pRenderStateMgr->SetRenderState( D3DRS_LIGHTING, FALSE );
    HR( g_pRenderStateMgr->SetVertexDeclaration( VertexCol::Decl ) );
    DWORD vertsToDraw = (DWORD)m_vertices.size();
    DWORD vertOffset = 0;
    DWORD vertChunk;
    while (vertsToDraw)
    {
        vertChunk = min( 16, vertsToDraw );
        g_d3dDevice->DrawPrimitiveUP( D3DPT_LINELIST, (UINT)vertChunk / 2,
                                      &m_vertices[vertOffset],
                                      sizeof(VCol) );
        vertsToDraw -= vertChunk;
        vertOffset += vertChunk;
    }

    m_vertices.clear();
}

void CDebugDrawer::drawLine (
    const btVector3& from,
    const btVector3& to,
    const btVector3& fromColor,
    const btVector3& toColor
    )
{
    D3DXVECTOR3 vFrom, vTo, vCFrom, vCTo;

    memcpy( &vFrom,  &from,      sizeof( D3DXVECTOR3 ) );
    memcpy( &vTo,    &to,        sizeof( D3DXVECTOR3 ) );
    memcpy( &vCFrom, &fromColor, sizeof( D3DXVECTOR3 ) );
    memcpy( &vCTo,   &toColor,   sizeof( D3DXVECTOR3 ) );
    D3DCOLOR cFrom, cTo;
    cFrom =
        D3DCOLOR_ARGB( 0xFF, (DWORD)(vCFrom.x * 255), (DWORD)(vCFrom.y * 255),
                       (DWORD)(vCFrom.z * 255) );
    cTo =
        D3DCOLOR_ARGB( 0xFF, (DWORD)(vCTo.x * 255), (DWORD)(vCTo.y * 255),
                       (DWORD)(vCTo.z * 255) );
    VCol vert[] = {VCol(vFrom, cFrom), VCol(vTo, cTo)};
    m_vertices.push_back( vert[0] );
    m_vertices.push_back( vert[1] );
}

void CDebugDrawer::drawLine (
    const btVector3& from,
    const btVector3& to,
    const btVector3& color
    )
{
    drawLine(from, to, color, color);
}

void CDebugDrawer::drawSphere (
    const btVector3& p,
    btScalar         radius,
    const btVector3& color
    )
{
#if 0
    glColor4f ( color.getX(), color.getY(), color.getZ(), btScalar(1.0f) );
    glPushMatrix ();
    glTranslatef ( p.getX(), p.getY(), p.getZ() );
    int lats = 5;
    int longs = 5;
    int i, j;
    for(i = 0; i <= lats; i++)
    {
        btScalar lat0 = SIMD_PI * (-btScalar(0.5) + (btScalar) (i - 1) / lats);
        btScalar z0 = radius * sin(lat0);
        btScalar zr0 = radius * cos(lat0);
        btScalar lat1 = SIMD_PI * (-btScalar(0.5) + (btScalar) i / lats);
        btScalar z1 = radius * sin(lat1);
        btScalar zr1 = radius * cos(lat1);
        glBegin(GL_QUAD_STRIP);
        for(j = 0; j <= longs; j++)
        {
            btScalar lng = 2 * SIMD_PI * (btScalar) (j - 1) / longs;
            btScalar x = cos(lng);
            btScalar y = sin(lng);
            glNormal3f(x * zr0, y * zr0, z0);
            glVertex3f(x * zr0, y * zr0, z0);
            glNormal3f(x * zr1, y * zr1, z1);
            glVertex3f(x * zr1, y * zr1, z1);
        }

        glEnd();
    }

    glPopMatrix();
#endif
}

void CDebugDrawer::drawBox (
    const btVector3& boxMin,
    const btVector3& boxMax,
    const btVector3& color,
    btScalar         alpha
    )
{
#if 0
    btVector3 halfExtent = (boxMax - boxMin) * btScalar(0.5f);
    btVector3 center = (boxMax + boxMin) * btScalar(0.5f);
    glColor4f (color.getX(), color.getY(), color.getZ(), alpha);
    glPushMatrix ();
    glTranslatef ( center.getX(), center.getY(), center.getZ() );
    glScaled(2 * halfExtent[0], 2 * halfExtent[1], 2 * halfExtent[2]);
    glPopMatrix ();
#endif
}

void CDebugDrawer::drawTriangle (
    const btVector3& a,
    const btVector3& b,
    const btVector3& c,
    const btVector3& color,
    btScalar         alpha
    )
{
#if 0
    const btVector3 n = btCross(b - a,c - a).normalized();
    glBegin(GL_TRIANGLES);
    glColor4f(color.getX(), color.getY(), color.getZ(),alpha);
    glNormal3d( n.getX(),n.getY(),n.getZ() );
    glVertex3d( a.getX(),a.getY(),a.getZ() );
    glVertex3d( b.getX(),b.getY(),b.getZ() );
    glVertex3d( c.getX(),c.getY(),c.getZ() );
    glEnd();
#endif
}

void CDebugDrawer::setDebugMode (int debugMode)
{
    m_debugMode = debugMode;
}

void CDebugDrawer::draw3dText (
    const btVector3& location,
    const char*      textString
    )
{
#if 0
    glRasterPos3f( location.x(),  location.y(),  location.z() );
#endif
}

void CDebugDrawer::reportErrorWarning (const char* warningString)
{
    OutputDebugStringA( warningString );
    OutputDebugStringA( "\n" );
}

void CDebugDrawer::drawContactPoint (
    const btVector3& pointOnB,
    const btVector3& normalOnB,
    btScalar         distance,
    int              lifeTime,
    const btVector3& color
    )
{
#if 0
    btVector3 to = pointOnB + normalOnB * distance;
    const btVector3&from = pointOnB;
    glColor4f(color.getX(), color.getY(), color.getZ(),1.f);
    glBegin(GL_LINES);
    glVertex3d( from.getX(), from.getY(), from.getZ() );
    glVertex3d( to.getX(), to.getY(), to.getZ() );
    glEnd();
    glRasterPos3f( from.x(),  from.y(),  from.z() );
    char buf[12];
    sprintf(buf," %d",lifeTime);
#endif
}

 


#1Steve_Segreto

Posted 02 April 2013 - 11:58 PM

I have integrated Bullet Physics into a D3D9 class engine and it is not that difficult. Let me share an overview of Bullet, I may be glossing over many details, please refer to the Wiki page and other web resources as well.

 

You start by creating an object that derives from btCollisionWorld, like btDiscreteDynamicsWorld. You can tick this object using the stepSimulation member, which will basically identify all contacts between "collision" objects and update their positions based on physical properties like gravity, mass, etc.

 

Collision objects fall into two classes (well three if you consider the character controller), rigid bodies, soft bodies and kinematic objects. You can add immovable (static) collision objects by setting the mass to a special constant (0.0f). You add rigid bodies using the addRigidBody member of your collision world object. You can do ray testing against the objects in your world using the rayTest() member of the collision world object.

 

When first creating your collision world, you need to select and specify a collision dispatcher, a broadphase object, a constraint solver and some config data. Your program needs to allocate and de-allocate all objects and memory passed to Bullet, the library does not own any pointers provided to it.

 

The choice of broadphase object can determine how well the collision world responds to very dynamic rigid bodies changing position every frame. You can overload both broadphase and nearphase collision responses and filters (so you can make a player rigid body collide with nothing but the ground, but make every other rigid body bounce off the player, for instance).

 

You can also declare a debug drawer and provide a D3D9 implementation to help you visualize the collision world and the collision objects as you place them in the world.

 

Here's the debug drawer I use, maybe it would help you?

 

//-----------------------------------------------------------------------------
// File: CDebugDrawer.h
//
// Purpose: A debug drawer used by the physics library.
//
// Copyright (c) 2007-2011 Steve Segreto. All rights reserved.
//-----------------------------------------------------------------------------
#pragma
once
#include
"LinearMath/btIDebugDraw.h"
#include
<vector>
struct
VCol
{
VCol(
const D3DXVECTOR3& v,
D3DCOLOR c
) : pos(v),col(c)
{
}
D3DXVECTOR3 pos;
D3DCOLOR col;
};
void
VisualizeRay (
D3DXVECTOR3 rayStartW,
D3DXVECTOR3 rayDirW,
D3DXCOLOR color
);
void
VisualizeLineSegment (
D3DXVECTOR3 startW,
D3DXVECTOR3 endW,
D3DXCOLOR color
);
void
VisualizeBox (
struct AABB* box,
D3DXCOLOR color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f )
);
void
VisualizeBox (
struct OBB* box,
D3DXCOLOR color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f )
);
void
VisualizeQuad (
D3DXVECTOR3 topLeft,
D3DXVECTOR3 bottomRight,
D3DXCOLOR color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f )
);
void
VisualizeFrustum (
D3DXVECTOR3* corners,
D3DXCOLOR color
);
void
VisualizeRotation (
D3DXVECTOR3 posW,
D3DXQUATERNION rot,
D3DXCOLOR colorX = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f),
D3DXCOLOR colorY = D3DXCOLOR(1.0f, 1.0f, 0.0f, 1.0f),
D3DXCOLOR colorZ = D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)
);
void
VisualizeRotation (
D3DXVECTOR3 posW,
D3DXMATRIX rot,
D3DXCOLOR colorX = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f),
D3DXCOLOR colorY = D3DXCOLOR(1.0f, 1.0f, 0.0f, 1.0f),
D3DXCOLOR colorZ = D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)
);
class
CDebugDrawer : public btIDebugDraw
{
public
:
int m_debugMode;
std::vector< VCol > m_vertices;
CDebugDrawer();
void DebugPresent ();
virtual void drawLine (
const btVector3& from,
const btVector3& to,
const btVector3& fromColor,
const btVector3& toColor
);
virtual void drawLine (
const btVector3& from,
const btVector3& to,
const btVector3& color
);
virtual void drawSphere (
const btVector3& p,
btScalar radius,
const btVector3& color
);
virtual void drawBox (
const btVector3& boxMin,
const btVector3& boxMax,
const btVector3& color,
btScalar alpha
);
virtual void drawTriangle (
const btVector3& a,
const btVector3& b,
const btVector3& c,
const btVector3& color,
btScalar alpha
);
virtual void drawContactPoint (
const btVector3& PointOnB,
const btVector3& normalOnB,
btScalar distance,
int lifeTime,
const btVector3& color
);
virtual void reportErrorWarning (const char* warningString);
virtual void draw3dText (
const btVector3& location,
const char* textString
);
virtual void setDebugMode (int debugMode);
virtual int getDebugMode () const
{
return m_debugMode;
}
};

 

//-----------------------------------------------------------------------------
// File: CDebugDrawer.cpp
//
// Purpose: A debug drawer used by the physics library.
//
// Copyright (c) 2007-2011 Steve Segreto. All rights reserved.
//-----------------------------------------------------------------------------
#include
"Global.h"
#include
"CRenderable.h"
#include
"CVertexManager.h"
#include
"CDebugDrawer.h"
extern
CPhysicsEngine* g_pPhysics;
void
VisualizeFrustum (
D3DXVECTOR3* corners,
D3DXCOLOR color
)
{
VisualizeLineSegment( corners[ 4 ], corners[ 5 ], color );
VisualizeLineSegment( corners[ 7 ], corners[ 6 ], color );
VisualizeLineSegment( corners[ 4 ], corners[ 7 ], color );
VisualizeLineSegment( corners[ 5 ], corners[ 6 ], color );
VisualizeLineSegment( corners[ 0 ], corners[ 1 ], color );
VisualizeLineSegment( corners[ 3 ], corners[ 2 ], color );
VisualizeLineSegment( corners[ 0 ], corners[ 3 ], color );
VisualizeLineSegment( corners[ 1 ], corners[ 2 ], color );
VisualizeLineSegment( corners[ 0 ], corners[ 4 ], color );
VisualizeLineSegment( corners[ 1 ], corners[ 5 ], color );
VisualizeLineSegment( corners[ 2 ], corners[ 6 ], color );
VisualizeLineSegment( corners[ 3 ], corners[ 7 ], color );
}
void
VisualizeRay (
D3DXVECTOR3 rayStartW,
D3DXVECTOR3 rayDirW,
D3DXCOLOR color
)
{
D3DXVECTOR3 rayToW = (rayDirW * 1000) + rayStartW;
g_pPhysics->m_pDebugDrawer->m_vertices.clear();
g_pPhysics->m_pDebugDrawer->drawLine( btVector3( rayStartW.x, rayStartW.y,
rayStartW.z ),
btVector3( rayToW.x, rayToW.y,
rayToW.z ),
btVector3( color.r, color.g, color.b ),
btVector3( color.r, color.g, color.b ) );
g_pPhysics->m_pDebugDrawer->DebugPresent();
}
void
VisualizeBox (
AABB* box,
D3DXCOLOR color
)
{
//
// Draw a box using 4 quads
//
D3DXVECTOR3 c0 = D3DXVECTOR3( box->maxPt.x, box->maxPt.y, box->maxPt.z );
D3DXVECTOR3 c1 = D3DXVECTOR3( box->maxPt.x, box->minPt.y, box->maxPt.z );
D3DXVECTOR3 c2 = D3DXVECTOR3( box->maxPt.x, box->maxPt.y, box->minPt.z );
D3DXVECTOR3 c3 = D3DXVECTOR3( box->minPt.x, box->maxPt.y, box->maxPt.z );
D3DXVECTOR3 c4 = D3DXVECTOR3( box->maxPt.x, box->minPt.y, box->minPt.z );
D3DXVECTOR3 c5 = D3DXVECTOR3( box->minPt.x, box->maxPt.y, box->minPt.z );
D3DXVECTOR3 c6 = D3DXVECTOR3( box->minPt.x, box->minPt.y, box->maxPt.z );
D3DXVECTOR3 c7 = D3DXVECTOR3( box->minPt.x, box->minPt.y, box->minPt.z );
VisualizeLineSegment( c0, c3, color );
VisualizeLineSegment( c0, c1, color );
VisualizeLineSegment( c0, c2, color );
VisualizeLineSegment( c3, c5, color );
VisualizeLineSegment( c3, c6, color );
VisualizeLineSegment( c1, c4, color );
VisualizeLineSegment( c1, c6, color );
VisualizeLineSegment( c2, c5, color );
VisualizeLineSegment( c2, c4, color );
VisualizeLineSegment( c4, c7, color );
VisualizeLineSegment( c5, c7, color );
VisualizeLineSegment( c6, c7, color );
}
void
VisualizeBox (
OBB* box,
D3DXCOLOR color
)
{
//
// Draw a box using 4 quads
//
D3DXVECTOR3 c0 = box->m_objectBounds[ 7 ];
D3DXVECTOR3 c1 = box->m_objectBounds[ 5 ];
D3DXVECTOR3 c2 = box->m_objectBounds[ 3 ];
D3DXVECTOR3 c3 = box->m_objectBounds[ 6 ];
D3DXVECTOR3 c4 = box->m_objectBounds[ 1 ];
D3DXVECTOR3 c5 = box->m_objectBounds[ 2 ];
D3DXVECTOR3 c6 = box->m_objectBounds[ 4 ];
D3DXVECTOR3 c7 = box->m_objectBounds[ 0 ];
VisualizeLineSegment( c0, c3, color );
VisualizeLineSegment( c0, c1, color );
VisualizeLineSegment( c0, c2, color );
VisualizeLineSegment( c3, c5, color );
VisualizeLineSegment( c3, c6, color );
VisualizeLineSegment( c1, c4, color );
VisualizeLineSegment( c1, c6, color );
VisualizeLineSegment( c2, c5, color );
VisualizeLineSegment( c2, c4, color );
VisualizeLineSegment( c4, c7, color );
VisualizeLineSegment( c5, c7, color );
VisualizeLineSegment( c6, c7, color );
}
void
VisualizeQuad (
D3DXVECTOR3 topLeft,
D3DXVECTOR3 bottomRight,
D3DXCOLOR color
)
{
//
// Draw a quad between topLeft and bottomRight.
//
VisualizeLineSegment( topLeft,
D3DXVECTOR3( topLeft.x,
bottomRight.y,
topLeft.z ), color );
VisualizeLineSegment( D3DXVECTOR3( topLeft.x,
bottomRight.y,
topLeft.z ), bottomRight, color );
VisualizeLineSegment( bottomRight,
D3DXVECTOR3( bottomRight.x,
topLeft.y,
bottomRight.z ), color );
VisualizeLineSegment( D3DXVECTOR3( bottomRight.x,
topLeft.y,
bottomRight.z ), topLeft, color );
}
void
VisualizeLineSegment (
D3DXVECTOR3 startW,
D3DXVECTOR3 endW,
D3DXCOLOR color
)
{
g_pPhysics->m_pDebugDrawer->m_vertices.clear();
g_pPhysics->m_pDebugDrawer->drawLine( btVector3( startW.x, startW.y,
startW.z ),
btVector3( endW.x, endW.y, endW.z ),
btVector3( color.r, color.g, color.b ),
btVector3( color.r, color.g, color.b ) );
g_pPhysics->m_pDebugDrawer->DebugPresent();
}
void
VisualizeRotation (
D3DXVECTOR3 posW,
D3DXQUATERNION rot,
D3DXCOLOR colorX,
D3DXCOLOR colorY,
D3DXCOLOR colorZ
)
{
D3DXMATRIX m;
D3DXMatrixRotationQuaternion( &m, &rot );
VisualizeRotation( posW, m, colorX, colorY, colorZ );
}
void
VisualizeRotation (
D3DXVECTOR3 posW,
D3DXMATRIX m,
D3DXCOLOR colorX,
D3DXCOLOR colorY,
D3DXCOLOR colorZ
)
{
D3DXVECTOR3 xAxis = (D3DXVECTOR3( m._11, m._12, m._13 ) * 1) + posW;
D3DXVECTOR3 yAxis = (D3DXVECTOR3( m._21, m._22, m._23 ) * 1) + posW;
D3DXVECTOR3 zAxis = (D3DXVECTOR3( m._31, m._32, m._33 ) * 1) + posW;
g_pPhysics->m_pDebugDrawer->m_vertices.clear();
g_pPhysics->m_pDebugDrawer->drawLine( btVector3( posW.x, posW.y, posW.z ),
btVector3( xAxis.x, xAxis.y, xAxis.z ),
btVector3( colorX.r, colorX.g,
colorX.b ),
btVector3( colorX.r, colorX.g,
colorX.b ) );
g_pPhysics->m_pDebugDrawer->drawLine( btVector3( posW.x, posW.y, posW.z ),
btVector3( yAxis.x, yAxis.y, yAxis.z ),
btVector3( colorY.r, colorY.g,
colorY.b ),
btVector3( colorY.r, colorY.g,
colorY.b ) );
g_pPhysics->m_pDebugDrawer->drawLine( btVector3( posW.x, posW.y, posW.z ),
btVector3( zAxis.x, zAxis.y, zAxis.z ),
btVector3( colorZ.r, colorZ.g,
colorZ.b ),
btVector3( colorZ.r, colorZ.g,
colorZ.b ) );
g_pPhysics->m_pDebugDrawer->DebugPresent();
}
CDebugDrawer::CDebugDrawer() : m_debugMode(0)
{
}
void
CDebugDrawer::DebugPresent ()
{
if ( !m_vertices.size() )
{
return;
}
D3DXMATRIX world;
D3DXMatrixIdentity( &world );
g_d3dDevice->SetTransform(D3DTS_WORLD, &world);
HR( g_pRenderStateMgr->SetVertexShader( NULL ) );
HR( g_pRenderStateMgr->SetPixelShader( NULL ) );
DWORD m_renderStates[ 256 ];
g_pRenderStateMgr->SetToDefaults( m_renderStates );
g_pRenderStateMgr->PostStates( m_renderStates );
g_pRenderStateMgr->SetRenderState( D3DRS_LIGHTING, FALSE );
HR( g_pRenderStateMgr->SetVertexDeclaration( VertexCol::Decl ) );
DWORD vertsToDraw = (DWORD)m_vertices.size();
DWORD vertOffset = 0;
DWORD vertChunk;
while (vertsToDraw)
{
vertChunk = min( 16, vertsToDraw );
g_d3dDevice->DrawPrimitiveUP( D3DPT_LINELIST, (UINT)vertChunk / 2,
&m_vertices[vertOffset],
sizeof(VCol) );
vertsToDraw -= vertChunk;
vertOffset += vertChunk;
}
m_vertices.clear();
}
void
CDebugDrawer::drawLine (
const btVector3& from,
const btVector3& to,
const btVector3& fromColor,
const btVector3& toColor
)
{
D3DXVECTOR3 vFrom, vTo, vCFrom, vCTo;
memcpy( &vFrom, &from, sizeof( D3DXVECTOR3 ) );
memcpy( &vTo, &to, sizeof( D3DXVECTOR3 ) );
memcpy( &vCFrom, &fromColor, sizeof( D3DXVECTOR3 ) );
memcpy( &vCTo, &toColor, sizeof( D3DXVECTOR3 ) );
D3DCOLOR cFrom, cTo;
cFrom =
D3DCOLOR_ARGB( 0xFF, (DWORD)(vCFrom.x * 255), (DWORD)(vCFrom.y * 255),
(DWORD)(vCFrom.z * 255) );
cTo =
D3DCOLOR_ARGB( 0xFF, (DWORD)(vCTo.x * 255), (DWORD)(vCTo.y * 255),
(DWORD)(vCTo.z * 255) );
VCol vert[] = {VCol(vFrom, cFrom), VCol(vTo, cTo)};
m_vertices.push_back( vert[0] );
m_vertices.push_back( vert[1] );
}
void
CDebugDrawer::drawLine (
const btVector3& from,
const btVector3& to,
const btVector3& color
)
{
drawLine(from, to, color, color);
}
void
CDebugDrawer::drawSphere (
const btVector3& p,
btScalar radius,
const btVector3& color
)
{
#if
0
glColor4f ( color.getX(), color.getY(), color.getZ(), btScalar(1.0f) );
glPushMatrix ();
glTranslatef ( p.getX(), p.getY(), p.getZ() );
int lats = 5;
int longs = 5;
int i, j;
for(i = 0; i <= lats; i++)
{
btScalar lat0 = SIMD_PI * (-btScalar(0.5) + (btScalar) (i - 1) / lats);
btScalar z0 = radius * sin(lat0);
btScalar zr0 = radius * cos(lat0);
btScalar lat1 = SIMD_PI * (-btScalar(0.5) + (btScalar) i / lats);
btScalar z1 = radius * sin(lat1);
btScalar zr1 = radius * cos(lat1);
glBegin(GL_QUAD_STRIP);
for(j = 0; j <= longs; j++)
{
btScalar lng = 2 * SIMD_PI * (btScalar) (j - 1) / longs;
btScalar x = cos(lng);
btScalar y = sin(lng);
glNormal3f(x * zr0, y * zr0, z0);
glVertex3f(x * zr0, y * zr0, z0);
glNormal3f(x * zr1, y * zr1, z1);
glVertex3f(x * zr1, y * zr1, z1);
}
glEnd();
}
glPopMatrix();
#endif
}
void
CDebugDrawer::drawBox (
const btVector3& boxMin,
const btVector3& boxMax,
const btVector3& color,
btScalar alpha
)
{
#if
0
btVector3 halfExtent = (boxMax - boxMin) * btScalar(0.5f);
btVector3 center = (boxMax + boxMin) * btScalar(0.5f);
glColor4f (color.getX(), color.getY(), color.getZ(), alpha);
glPushMatrix ();
glTranslatef ( center.getX(), center.getY(), center.getZ() );
glScaled(2 * halfExtent[0], 2 * halfExtent[1], 2 * halfExtent[2]);
glPopMatrix ();
#endif
}
void
CDebugDrawer::drawTriangle (
const btVector3& a,
const btVector3& b,
const btVector3& c,
const btVector3& color,
btScalar alpha
)
{
#if
0
const btVector3 n = btCross(b - a,c - a).normalized();
glBegin(GL_TRIANGLES);
glColor4f(color.getX(), color.getY(), color.getZ(),alpha);
glNormal3d( n.getX(),n.getY(),n.getZ() );
glVertex3d( a.getX(),a.getY(),a.getZ() );
glVertex3d( b.getX(),b.getY(),b.getZ() );
glVertex3d( c.getX(),c.getY(),c.getZ() );
glEnd();
#endif
}
void
CDebugDrawer::setDebugMode (int debugMode)
{
m_debugMode = debugMode;
}
void
CDebugDrawer::draw3dText (
const btVector3& location,
const char* textString
)
{
#if
0
glRasterPos3f( location.x(), location.y(), location.z() );
#endif
}
void
CDebugDrawer::reportErrorWarning (const char* warningString)
{
OutputDebugStringA( warningString );
OutputDebugStringA( "\n" );
}
void
CDebugDrawer::drawContactPoint (
const btVector3& pointOnB,
const btVector3& normalOnB,
btScalar distance,
int lifeTime,
const btVector3& color
)
{
#if
0
btVector3 to = pointOnB + normalOnB * distance;
const btVector3&from = pointOnB;
glColor4f(color.getX(), color.getY(), color.getZ(),1.f);
glBegin(GL_LINES);
glVertex3d( from.getX(), from.getY(), from.getZ() );
glVertex3d( to.getX(), to.getY(), to.getZ() );
glEnd();
glRasterPos3f( from.x(), from.y(), from.z() );
char buf[12];
sprintf(buf," %d",lifeTime);
#endif
}

PARTNERS