## How can I use Newton with quake BSP files?

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

### How can I use Newton with quake BSP files?

This is a problem that seems to happen very frequent. Unfortunately we do not know the internals of Quake of any other file format.
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);}`

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 geometryvoid 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 geometryvoid DebugShowBodyCollision (const NewtonBody* body){   NewtonBodyForEachPolygonDo (body, DebugShowGeometryCollision);}// show all collision geometryvoid  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,

http://www.physicsengine.com/forum/viewtopic.php?t=3233
http://www.physicsengine.com/forum/view ... sc&start=0
Julio Jerez
Moderator

Posts: 11153
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles