For what we understand Quake BSP file are very wide spread and there is even an official free open source code download from the developer, so extracting the information is a matter of analyzing the original source of the BSP parcel.
The format of the collision tree in newton is quite simple, the application only need to submit the polygons in a vertex array for each polygon and there engine takes case of all the housework to organize the data the way that best fix the engine.
Nevertheless even with this simplicity some users keep getting problems with these BSP files in particular, Here is a code fragment that seems to works correctly at extracting the polygons from the quake BSP file
For reading the faces from the BSP:
- Code: Select all
void Physics::CreateLevelBody (const CQuake3BSP& level)
{
int i;
float* ptr;
NewtonBody* body;
NewtonCollision* collision;
// create a collision object
collision = NewtonCreateTreeCollision (m_world, NULL);
NewtonTreeCollisionBeginBuild (collision);
// interate over the faces of the BSP level
for (i = 0; i < level.m_numOfFaces; i ++)
{
tBSPFace& face = level.m_pFaces[i];
// if a face is a polygon
if (face.type == FACE_POLYGON)
{
// add this face to the collision tree;
ptr = &level.m_pVerts[face.startVertIndex].vPosition.x;
NewtonTreeCollisionAddFace (collision, face.numOfVerts, ptr, sizeof (tBSPVertex), 0);
}
}
//close the collision mesh
// optionally the collision mesh can be optimized,
NewtonTreeCollisionEndBuild (collision, 0);
body = NewtonCreateBody (m_world, collision);
NewtonReleaseCollision (m_world, collision);
}
For reading paches:
- Code: Select all
/*This code actually depends how your Bezier patches are sorted, for me they were tri-strips which didn’t work to well just chucking them into Newton, so I came up with this algorithm to convert them to raw triangles.*/
// Convert Patch Data from Tri Strips to Raw Triangles for Newton
for ( int i = 0; i < m_numOfPatches; i++ )
{
for( int j = 0; j < m_pPatches[i].numQuadraticPatches; j++ )
{
int tesselation = m_pPatches[i].quadraticPatches[j].tesselation;
for( int row = 0; row < tesselation; row++ )
{
int numtri = m_pPatches[i].quadraticPatches[j].trianglesPerRow[row];
unsigned int r1 = m_pPatches[i].quadraticPatches[j].rowIndexPointers[row][0];
unsigned int r2 = m_pPatches[i].quadraticPatches[j].rowIndexPointers[row][1];
unsigned int r3 = m_pPatches[i].quadraticPatches[j].rowIndexPointers[row][2];
trisoup.push_back(m_pPatches[i].quadraticPatches[j].vertices[r1].vPosition);
trisoup.push_back(m_pPatches[i].quadraticPatches[j].vertices[r2].vPosition);
trisoup.push_back(m_pPatches[i].quadraticPatches[j].vertices[r3].vPosition);
bool flipped = false;
for ( int tri = 2; tri < numtri; tri++ )
{
unsigned int rnew1 = m_pPatches[i].quadraticPatches[j].rowIndexPointers[row][tri-2];
unsigned int rnew2 = m_pPatches[i].quadraticPatches[j].rowIndexPointers[row][tri-1];
unsigned int rnew3 = m_pPatches[i].quadraticPatches[j].rowIndexPointers[row][tri+0];
if ( flipped )
{
trisoup.push_back(m_pPatches[i].quadraticPatches[j].vertices[rnew3].vPosition);
trisoup.push_back(m_pPatches[i].quadraticPatches[j].vertices[rnew2].vPosition);
trisoup.push_back(m_pPatches[i].quadraticPatches[j].vertices[rnew1].vPosition);
}
else
{
trisoup.push_back(m_pPatches[i].quadraticPatches[j].vertices[rnew1].vPosition);
trisoup.push_back(m_pPatches[i].quadraticPatches[j].vertices[rnew2].vPosition);
trisoup.push_back(m_pPatches[i].quadraticPatches[j].vertices[rnew3].vPosition);
}
flipped = !flipped;
}
}
}
}
//Now we simply iterate through the triangle soup (which is STL vector btw)
CVector3D vectorTemp[3];
for ( int i = 0; i < trisoup.size(); i+=3 )
{
vectorTemp[0] = trisoup[i+0];
vectorTemp[1] = trisoup[i+1];
vectorTemp[2] = trisoup[i+2];
NewtonTreeCollisionAddFace(collision, 3, &vectorTemp[0][0], sizeof(CVector3D), 0);
}
This code fragment can be used for rendering the debug display:
- Code: Select all
// show collision geometry
void DebugShowGeometryCollision (const NewtonBody* body, int vertexCount, const dFloat* faceVertec, int id)
{
int i;
i = vertexCount - 1;
CVector3D p0 (faceVertec[i * 3 + 0], faceVertec[i * 3 + 1], faceVertec[i * 3 + 2]);
for (i = 0; i < vertexCount; i ++) {
CVector3D p1 (faceVertec[i * 3 + 0], faceVertec[i * 3 + 1], faceVertec[i * 3 + 2]);
glVertex3f (p0.x, p0.y, p0.z);
glVertex3f (p1.x, p1.y, p1.z);
p0 = p1;
}
}
// show rigid body collision geometry
void DebugShowBodyCollision (const NewtonBody* body)
{
NewtonBodyForEachPolygonDo (body, DebugShowGeometryCollision);
}
// show all collision geometry
void CQuake3BSP :: DebugShowCollision ()
{
glDisable (GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glColor3f(1.0f, 1.0f, 0.0f);
glBegin(GL_LINES);
NewtonWorldForEachBodyDo (nWorld, DebugShowBodyCollision);
glEnd();
}
I must say that I never tested this code, nor I even know if it is legal to post extract data from a proprietary file format, so use the code at your own risk.
This code fragment had been contributed by user Firefly and also with some input from user Koom wich had provide similar versions written in pascal,
For more information you can see threads:
http://www.physicsengine.com/forum/viewtopic.php?t=3233
http://www.physicsengine.com/forum/view ... sc&start=0