void ClippedPolyList::generateNormals()
{
   PROFILE_SCOPE( ClippedPolyList_GenerateNormals );

   AssertFatal(mNormalList.size() == mVertexList.size(), "Normals count does not match vertex count!");    

   U32 i, polyCount;
   VectorF normal;
   PolyListIterator polyIter;
   IndexListIterator indexIter;

   Vector<VectorF>::iterator normalIter = mNormalList.begin();
   U32 n = 0;
   for ( ; normalIter != mNormalList.end(); normalIter++, n++ )
   {
       // Skip normals that already have values.
       if ( !normalIter->isZero() )
           continue;

      // Average all the face normals which 
      // share this vertex index.
      indexIter = mIndexList.begin();
      normal.zero();
      polyCount = 0;
      i = 0;

      for ( ; indexIter != mIndexList.end(); indexIter++, i++ )
      {
         if ( n != *indexIter )
            continue;

         polyIter = mPolyList.begin();
         for ( ; polyIter != mPolyList.end(); polyIter++ )
         {
            const Poly& poly = *polyIter;
            if ( i < poly.vertexStart || i > poly.vertexStart + poly.vertexCount )
               continue;

            ++polyCount;
            normal += poly.plane;
         }        
      }

      // Average it.
      if ( polyCount > 0 )
         normal /= (F32)polyCount;

      // Note: we use a temporary for the normal averaging 
      // then copy the result to limit the number of arrays
      // we're touching during the innermost loop.
      *normalIter = normal;
   }
}
Ejemplo n.º 2
0
void ConvexFeature::testEdge(ConvexFeature* cf,const Point3F& s1, const Point3F& e1, CollisionList* cList, F32 tol)
{
   F32 tolSquared = tol*tol;

   // Test edges against edges
   const Edge* edge = mEdgeList.begin();
   const Edge* end  = mEdgeList.end();
   for (; edge != end; edge++) {
      if (cList->getCount() >= CollisionList::MaxCollisions)
         return;

      const Point3F& s2 = mVertexList[edge->vertex[0]];
      const Point3F& e2 = mVertexList[edge->vertex[1]];

      // Get the distance and closest points
      Point3F i1,i2;
      F32 distance = sqrDistanceEdges(s1, e1, s2, e2, &i1, &i2);
      if (distance > tolSquared)
         continue;
      distance = mSqrt(distance);

      // Need to figure out how to orient the collision normal.
      // The current test involves checking to see whether the collision
      // points are contained within the convex volumes, which is slow.
      if (inVolume(i1) || cf->inVolume(i2))
         distance = -distance;

      // Contact normal
      VectorF normal = i1 - i2;
      if ( mIsZero( distance ) )
         normal.zero();
      else
         normal *= 1 / distance;

      // Return a collision
      Collision& info = cList->increment();
      info.point    = i1;
      info.normal   = normal;
      info.distance = distance;
      info.material = material;
      info.object   = object;
   }
}