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?

Postby Julio Jerez » Fri Jan 19, 2007 2:21 pm

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);
}



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
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 7 guests