Răsfoiți Sursa

Added PLC_Navigation hint for gathering navmesh polygon data.

Daniel Buckmaster 12 ani în urmă
părinte
comite
d9c731b73f

+ 23 - 0
Engine/source/T3D/convexShape.cpp

@@ -653,6 +653,29 @@ bool ConvexShape::buildPolyList( PolyListContext context, AbstractPolyList *plis
 
    const Vector< ConvexShape::Face > faceList = mGeometry.faces;
 
+   if(context == PLC_Navigation)
+   {
+      for(S32 i = 0; i < faceList.size(); i++)
+      {
+         const ConvexShape::Face &face = faceList[i];
+
+         S32 s = face.triangles.size();
+         for(S32 j = 0; j < s; j++)
+         {
+            plist->begin(0, s*i + j);
+
+            plist->plane(PlaneF(face.centroid, face.normal));
+
+            plist->vertex(base + face.points[face.triangles[j].p0]);
+            plist->vertex(base + face.points[face.triangles[j].p1]);
+            plist->vertex(base + face.points[face.triangles[j].p2]);
+
+            plist->end();
+         }
+      }
+      return true;
+   }
+
    for ( S32 i = 0; i < faceList.size(); i++ )
    {
       const ConvexShape::Face &face = faceList[i];		

+ 35 - 1
Engine/source/T3D/groundPlane.cpp

@@ -288,11 +288,45 @@ void GroundPlane::buildConvex( const Box3F& box, Convex* convex )
    }
 }
 
-bool GroundPlane::buildPolyList( PolyListContext context, AbstractPolyList* polyList, const Box3F&, const SphereF& )
+bool GroundPlane::buildPolyList( PolyListContext context, AbstractPolyList* polyList, const Box3F& box, const SphereF& )
 {
    polyList->setObject( this );
    polyList->setTransform( &MatrixF::Identity, Point3F( 1.0f, 1.0f, 1.0f ) );
 
+   if(context == PLC_Navigation)
+   {
+      F32 z = getPosition().z;
+      Point3F
+         p0(box.minExtents.x, box.maxExtents.y, z),
+         p1(box.maxExtents.x, box.maxExtents.y, z),
+         p2(box.maxExtents.x, box.minExtents.y, z),
+         p3(box.minExtents.x, box.minExtents.y, z);
+
+      // Add vertices to poly list.
+      U32 v0 = polyList->addPoint(p0);
+      polyList->addPoint(p1);
+      polyList->addPoint(p2);
+      polyList->addPoint(p3);
+
+      // Add plane between first three vertices.
+      polyList->begin(0, 0);
+      polyList->vertex(v0);
+      polyList->vertex(v0+1);
+      polyList->vertex(v0+2);
+      polyList->plane(v0, v0+1, v0+2);
+      polyList->end();
+
+      // Add plane between last three vertices.
+      polyList->begin(0, 1);
+      polyList->vertex(v0+2);
+      polyList->vertex(v0+3);
+      polyList->vertex(v0);
+      polyList->plane(v0+2, v0+3, v0);
+      polyList->end();
+
+      return true;
+   }
+
    Box3F planeBox = getPlaneBox();
    polyList->addBox( planeBox, mMaterial );
 

+ 5 - 0
Engine/source/scene/sceneContainer.h

@@ -96,6 +96,11 @@ enum PolyListContext
    /// selection from an editor or other tool.
    PLC_Selection,
 
+   /// A hint that the polylist is used for
+   /// building a representation of the environment
+   /// used for navigation.
+   PLC_Navigation,
+
    /// A hint that the polyist will be used
    /// to export geometry and would like to have
    /// texture coords and materials.   

+ 14 - 1
Engine/source/terrain/terrCollision.cpp

@@ -480,7 +480,7 @@ static void clrbuf(U32* p, U32 s)
       *p++ = U32_MAX;
 }
 
-bool TerrainBlock::buildPolyList(PolyListContext, AbstractPolyList* polyList, const Box3F &box, const SphereF&)
+bool TerrainBlock::buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF&)
 {
 	PROFILE_SCOPE( TerrainBlock_buildPolyList );
 
@@ -530,12 +530,25 @@ bool TerrainBlock::buildPolyList(PolyListContext, AbstractPolyList* polyList, co
 
       swap(vb[0],vb[1]);
       clrbuf(vb[1],xExt + 1);
+
+      F32 wy1 = y * mSquareSize, wy2 = (y + 1) * mSquareSize;
+      if(context == PLC_Navigation &&
+         ((wy1 > osBox.maxExtents.y && wy2 > osBox.maxExtents.y) ||
+          (wy1 < osBox.minExtents.y && wy2 < osBox.minExtents.y)))
+         continue;
+
       //
       for (S32 x = xStart; x < xEnd; x++) 
       {
          S32 xi = x & BlockMask;
          const TerrainSquare *sq = mFile->findSquare( 0, xi, yi );
 
+         F32 wx1 = x * mSquareSize, wx2 = (x + 1) * mSquareSize;
+         if(context == PLC_Navigation &&
+            ((wx1 > osBox.maxExtents.x && wx2 > osBox.maxExtents.x) ||
+             (wx1 < osBox.minExtents.x && wx2 < osBox.minExtents.x)))
+            continue;
+
          if ( x != xi || y != yi )
             continue;