//---------------------------------------------------------------------------- void ExtractTrilinear::MakeUnique (V3Array& rkVA, T3Array& rkTA) { int iVQuantity = (int)rkVA.size(), iTQuantity = (int)rkTA.size(); if ( iVQuantity == 0 || iTQuantity == 0 ) return; // use a hash table to generate unique storage V3Map kVMap; V3MapIterator pkVIter; for (int iV = 0, iNextVertex = 0; iV < iVQuantity; iV++) { // keep only unique vertices pair<V3MapIterator,bool> kResult = kVMap.insert( make_pair(rkVA[iV],iNextVertex)); if ( kResult.second == true ) iNextVertex++; } // use a hash table to generate unique storage T3Map kTMap; T3MapIterator pkTIter; for (int iT = 0, iNextTriangle = 0; iT < iTQuantity; iT++) { // replace old vertex indices by new ones Triangle3& rkTri = rkTA[iT]; pkVIter = kVMap.find(rkVA[rkTri.i0]); assert( pkVIter != kVMap.end() ); rkTri.i0 = pkVIter->second; pkVIter = kVMap.find(rkVA[rkTri.i1]); assert( pkVIter != kVMap.end() ); rkTri.i1 = pkVIter->second; pkVIter = kVMap.find(rkVA[rkTri.i2]); assert( pkVIter != kVMap.end() ); rkTri.i2 = pkVIter->second; // keep only unique triangles pair<T3MapIterator,bool> kResult = kTMap.insert( make_pair(rkTri,iNextTriangle)); if ( kResult.second == true ) iNextTriangle++; } // pack the vertices rkVA.resize(kVMap.size()); for (pkVIter = kVMap.begin(); pkVIter != kVMap.end(); pkVIter++) rkVA[pkVIter->second] = pkVIter->first; // pack the triangles rkTA.resize(kTMap.size()); for (pkTIter = kTMap.begin(); pkTIter != kTMap.end(); pkTIter++) rkTA[pkTIter->second] = pkTIter->first; }
//---------------------------------------------------------------------------- void ExtractTrilinear::ComputeNormals (const V3Array& rkVA, const T3Array& rkTA, V3Array& rkNA) { // maintain a running sum of triangle normals at each vertex int iVQuantity = (int)rkVA.size(), iTQuantity = (int)rkTA.size(); rkNA.resize(iVQuantity); int i, j; for (i = 0; i < iVQuantity; i++) { rkNA[i].x = 0.0f; rkNA[i].y = 0.0f; rkNA[i].z = 0.0f; } for (i = 0, j = 0; i < iTQuantity; i++) { const Triangle3& rkT = rkTA[i]; Vertex3 kV0 = rkVA[rkT.i0]; Vertex3 kV1 = rkVA[rkT.i1]; Vertex3 kV2 = rkVA[rkT.i2]; // construct triangle normal float fEX1 = kV1.x - kV0.x; float fEY1 = kV1.y - kV0.y; float fEZ1 = kV1.z - kV0.z; float fEX2 = kV2.x - kV0.x; float fEY2 = kV2.y - kV0.y; float fEZ2 = kV2.z - kV0.z; float fNX = fEY1*fEZ2 - fEY2*fEZ1; float fNY = fEZ1*fEX2 - fEZ2*fEX1; float fNZ = fEX1*fEY2 - fEX2*fEY1; // maintain the sum of normals at each vertex rkNA[rkT.i0].x += fNX; rkNA[rkT.i0].y += fNY; rkNA[rkT.i0].z += fNZ; rkNA[rkT.i1].x += fNX; rkNA[rkT.i1].y += fNY; rkNA[rkT.i1].z += fNZ; rkNA[rkT.i2].x += fNX; rkNA[rkT.i2].y += fNY; rkNA[rkT.i2].z += fNZ; } // The normal vector storage was used to accumulate the sum of // triangle normals. Now these vectors must be rescaled to be // unit length. for (i = 0; i < iVQuantity; i++) { Vertex3& rkV = rkNA[i]; float fLength = sqrtf(rkV.x*rkV.x + rkV.y*rkV.y + rkV.z*rkV.z); if ( fLength > 1e-08f ) { float fInvLength = 1.0f/fLength; rkV.x *= fInvLength; rkV.y *= fInvLength; rkV.z *= fInvLength; } else { rkV.x = 0.0f; rkV.y = 0.0f; rkV.z = 0.0f; } } }