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