Пример #1
0
//----------------------------------------------------------------------------
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;
}
Пример #2
0
//----------------------------------------------------------------------------
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;
        }
    }
}