void Convert_shape_line_polygon_to_triangles( SHAPE_POLY_SET &aPolyList,
                                              CGENERICCONTAINER2D &aDstContainer,
                                              float aBiuTo3DunitsScale ,
                                              const BOARD_ITEM &aBoardItem )
{

    aPolyList.CacheTriangulation();
    const double conver_d = (double)aBiuTo3DunitsScale;

    for( unsigned int j = 0; j < aPolyList.TriangulatedPolyCount(); j++ )
    {
        auto triPoly = aPolyList.TriangulatedPolygon( j );

        for( size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
        {
            VECTOR2I a;
            VECTOR2I b;
            VECTOR2I c;
            triPoly->GetTriangle( i, a, b, c );

            aDstContainer.Add( new CTRIANGLE2D( SFVEC2F( a.x * conver_d,
                                                        -a.y * conver_d ),
                                                SFVEC2F( b.x * conver_d,
                                                        -b.y * conver_d ),
                                                SFVEC2F( c.x * conver_d,
                                                        -c.y * conver_d ),
                                                aBoardItem ) );
        }

    }
}
Exemple #2
0
// TODO: exploit a better algorithm, use vertex hash table/map.
//
void mxRenderMesh::WeldVertices()
{
	TArray< mxVertex >	newVerts;
	newVerts.Resize( GetVertexCount() );

	for ( u32 triIdx = 0; triIdx < GetTriangleCount(); triIdx++ )
	{
		IndexTriple & rTri = Triangles[ triIdx ];

		for ( TIndex i = 0; i < 3; i++ )
		{
			const mxVertex & rCurrVertex = Vertices[ rTri[i] ];

			s32  iExistingVertex = -1;
			for ( TIndex iVtx = 0; iVtx < newVerts.Num(); iVtx++ )
			{
				if ( VectorsEqual( newVerts[ iVtx ].Pos, rCurrVertex.Pos ) )
				{
					iExistingVertex = iVtx;
					break;
				}
			}

			if ( iExistingVertex != -1 ) {
				rTri[ i ] = iExistingVertex;
			} else {
				rTri[ i ] = newVerts.Append( mxVertex( rCurrVertex ) );
			}
		}
	}

	Vertices = newVerts;
}
Exemple #3
0
Void TriangleStripMesh::GetTriangle( UInt iTriangle, UInt & outA, UInt & outB, UInt & outC ) const
{
    Assert( iTriangle < GetTriangleCount() );

    outA = iTriangle;
    if ( iTriangle & 1 ) {
        outB = iTriangle + 2;
        outC = iTriangle + 1;
    } else {
        outB = iTriangle + 1;
        outC = iTriangle + 2;
    }

    if ( m_pIB == NULL )
        return;

    const Byte * pIndexA = m_pIB->GetData( m_iIndexOffset + outA );
    const Byte * pIndexB = m_pIB->GetData( m_iIndexOffset + outB );
    const Byte * pIndexC = m_pIB->GetData( m_iIndexOffset + outC );
    if ( m_pIB->UseShorts() ) {
        outA = *( (const Word*)pIndexA );
        outB = *( (const Word*)pIndexB );
        outC = *( (const Word*)pIndexC );
    } else {
        outA = *( (const DWord*)pIndexA );
        outB = *( (const DWord*)pIndexB );
        outC = *( (const DWord*)pIndexC );
    }
}
void SFObjectMD2::Render(LPDIRECT3DDEVICE9 RenderingDevice, float ElapsedSecs)
{
	if(isAnimated)
	{
		int play=-1;
		uint32 l = 0;

		//Loop through all animation names
		for (l=0;l<m_anim.size();l++)
		{
			if(strcmp (m_anim[l].name.c_str(), curr_animation) == 0)
			{
				if (Advance)
					m_anim[l].cur += m_anim[l].add;

				//restart animation
				if (m_anim[l].cur >= m_anim[l].end)
					m_anim[l].cur = (float)m_anim[l].start;

				play=l;
				
				break;
			}
		}
		sCore.DeviceHandler()->SetFVF (D3DFVF_MODELVERTEX);

		if (play==-1) return;
		if (play>=GetFrameCount()) return;

		sCore.DeviceHandler()->DrawPrimitiveUP(D3DPT_TRIANGLELIST, //Typ	
													GetTriangleCount (),		  //Anzahl
													(BYTE**)&m_data[int(m_anim[l].cur)].vertex[0],		  //Pointer auf Daten
													sizeof(MODELVERTEX));  //Größe Vertex
	}
	else
	{
		if( active_frame >= GetFrameCount()-1 )
			return;
		
		sCore.DeviceHandler()->SetFVF (D3DFVF_MODELVERTEX);

		sCore.DeviceHandler()->DrawPrimitiveUP(D3DPT_TRIANGLELIST, //Typ	
													GetTriangleCount (),		  //Anzahl
													(BYTE**)&m_data[active_frame].vertex[0],		  //Pointer auf Daten
													sizeof(MODELVERTEX));  //Größe Vertex
	}
}
Exemple #5
0
 void ChunkRenderer::Render(Tools::Gfx::Utils::DeferredShading& deferredShading, Common::Position const& position, glm::dmat4 const& viewProj)
 {
     this->_game.GetMap().GetChunkManager().ForeachIn(Tools::Frustum(viewProj),
         [&](Chunk& chunk)
         {
             auto mesh = chunk.GetMesh();
             if (mesh != 0 && mesh->GetTriangleCount() != 0)
             {
                 auto deltaPos = glm::fvec3(Common::GetChunkPosition(chunk.coords) - position);
                 mesh->Render(this->_renderer, deferredShading, glm::translate(deltaPos), Uint32(glm::lengthSquared(deltaPos)));
             }
         });
 }
int SFObjectMD2::Init() 
{
	// For each animation we use one SMesh
	for ( int i = 0; i < GetFrameCount(); i++ )
	{
		MODELVERTEX pVertex;
		
		D3DXCOLOR	LightColor(1.0f, 1.0f, 1.0f, 1.0f );
		for( int j = 0; j < GetTriangleCount(); j++) 
		{
			pVertex.m_vecPos.x = m_frame_list[i].vertex[m_index_list[j].a].x;
			pVertex.m_vecPos.y = m_frame_list[i].vertex[m_index_list[j].a].z;
			pVertex.m_vecPos.z = m_frame_list[i].vertex[m_index_list[j].a].y;
			pVertex.m_vecTex.x = m_index_list[j].a_s;
			pVertex.m_vecTex.y = m_index_list[j].a_t;
			pVertex.m_dwDiffuse = LightColor;
			m_data[i].vertex.push_back (pVertex);
			
			pVertex.m_vecPos.x = m_frame_list[i].vertex[m_index_list[j].b].x;
			pVertex.m_vecPos.y = m_frame_list[i].vertex[m_index_list[j].b].z;
			pVertex.m_vecPos.z = m_frame_list[i].vertex[m_index_list[j].b].y;
			pVertex.m_vecTex.x = m_index_list[j].b_s;
			pVertex.m_vecTex.y = m_index_list[j].b_t;
			pVertex.m_dwDiffuse = LightColor;
			m_data[i].vertex.push_back (pVertex);
			
			pVertex.m_vecPos.x = m_frame_list[i].vertex[m_index_list[j].c].x;
			pVertex.m_vecPos.y = m_frame_list[i].vertex[m_index_list[j].c].z;
			pVertex.m_vecPos.z = m_frame_list[i].vertex[m_index_list[j].c].y;
			pVertex.m_vecTex.x = m_index_list[j].c_s;
			pVertex.m_vecTex.y = m_index_list[j].c_t;
			pVertex.m_dwDiffuse = LightColor;
			m_data[i].vertex.push_back (pVertex);		
		}
	}
	return 1;
}
Exemple #7
0
Void TriangleListMesh::GetTriangle( UInt iTriangle, UInt & outA, UInt & outB, UInt & outC ) const
{
    Assert( iTriangle < GetTriangleCount() );

    outA = ( (iTriangle << 1) + iTriangle );
    outB = outA + 1;
    outC = outA + 2;

    if ( m_pIB == NULL )
        return;

    const Byte * pIndexA = m_pIB->GetData( m_iIndexOffset + outA );
    const Byte * pIndexB = m_pIB->GetData( m_iIndexOffset + outB );
    const Byte * pIndexC = m_pIB->GetData( m_iIndexOffset + outC );
    if ( m_pIB->UseShorts() ) {
        outA = *( (const Word*)pIndexA );
        outB = *( (const Word*)pIndexB );
        outC = *( (const Word*)pIndexC );
    } else {
        outA = *( (const DWord*)pIndexA );
        outB = *( (const DWord*)pIndexB );
        outC = *( (const DWord*)pIndexC );
    }
}
Exemple #8
0
Void TriangleMesh::UpdateTangentsFromTexCoords( GPUDeferredContext * pContext )
{
    Assert( m_pIL != NULL && m_pVB != NULL );
    Assert( m_pIL->IsBound() && m_pVB->IsBound() );

    Bool bHasNormals = m_pIL->HasField( GPUINPUTFIELD_SEMANTIC_NORMAL, 0 );
    Bool bHasTexCoords = m_pIL->HasField( GPUINPUTFIELD_SEMANTIC_TEXCOORD, 0 );
    if ( !bHasNormals || !bHasTexCoords )
        return;
    Bool bHasTangents =  m_pIL->HasField( GPUINPUTFIELD_SEMANTIC_TANGENT, 0 );
    Bool bHasBiNormals = m_pIL->HasField( GPUINPUTFIELD_SEMANTIC_BINORMAL, 0 );
    if ( !bHasTangents && !bHasBiNormals )
        return;

    // Begin update
    Byte * pFirstVertex = NULL;
    if ( m_pVB->CanUpdate() ) {
        Assert( m_pVB->HasCPUData() );
        pFirstVertex = m_pVB->GetData( m_iVertexOffset );
    } else {
        Assert( m_pVB->CanLock() );
        UInt iByteSize = 0;
        pFirstVertex = (Byte*)( m_pVB->Lock( GPURESOURCE_LOCK_WRITE, 0, &iByteSize, pContext ) );
        Assert( iByteSize == m_pVB->GetSize() );
    }

    // Update
    UInt iVertexSize = m_pVB->GetElementSize();

    UInt iOffset, iSize;
    const Byte * arrPositions = NULL;
    const Byte * arrNormals = NULL;
    const Byte * arrTexCoords = NULL;
    Byte * arrTangents = NULL;
    Byte * arrBiNormals = NULL;

    m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_POSITION, 0 );
    arrPositions = ( pFirstVertex + iOffset );
    m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_NORMAL, 0 );
    arrNormals = ( pFirstVertex + iOffset );
    m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_TEXCOORD, 0 );
    arrTexCoords = ( pFirstVertex + iOffset );
    if ( bHasTangents ) {
        m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_TANGENT, 0 );
        arrTangents = ( pFirstVertex + iOffset );
    }
    if ( bHasBiNormals ) {
        m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_BINORMAL, 0 );
        arrBiNormals = ( pFirstVertex + iOffset );
    }

    UInt i, iTriangleCount = GetTriangleCount();

        // Set all to null vector
    Byte *pCurTangent, *pCurBiNormal;
    Vector4 *pTangent, *pBiNormal;

    if ( bHasTangents ) {
        pCurTangent = arrTangents;
        for( i = 0; i < m_iVertexCount; ++i ) {
            pTangent = (Vector4*)pCurTangent;
            *pTangent = Vector4::Null;
            pCurTangent += iVertexSize;
        }
    } 
    if ( bHasBiNormals ) {
        pCurBiNormal = arrBiNormals;
        for( i = 0; i < m_iVertexCount; ++i ) {
            pBiNormal = (Vector4*)pCurBiNormal;
            *pBiNormal = Vector4::Null;
            pCurBiNormal += iVertexSize;
        }
    }

    // Visit all vertices
    UInt iA, iB, iC;
    const Vertex4 * arrPositionABC[3];
    const Vector4 * arrNormalABC[3];
    const TextureCoord2 * arrTexCoordABC[3];
    Vector4 * arrTangentABC[3];
    Vector4 * arrBiNormalABC[3];  

    UInt j, iNext, iPrev;
    Vector4 vCur;
    Vector4 vNormal, vTangent, vBiNormal;

    for( i = 0; i < iTriangleCount; ++i ) {
        GetTriangle( i, iA, iB, iC );
        iA *= iVertexSize;
        iB *= iVertexSize;
        iC *= iVertexSize;

        arrPositionABC[0] = (const Vertex4 *)( arrPositions + iA );
        arrPositionABC[1] = (const Vertex4 *)( arrPositions + iB );
        arrPositionABC[2] = (const Vertex4 *)( arrPositions + iC );
        arrNormalABC[0] = (const Vector4 *)( arrNormals + iA );
        arrNormalABC[1] = (const Vector4 *)( arrNormals + iB );
        arrNormalABC[2] = (const Vector4 *)( arrNormals + iC );
        arrTexCoordABC[0] = (const TextureCoord2 *)( arrTexCoords + iA );
        arrTexCoordABC[1] = (const TextureCoord2 *)( arrTexCoords + iB );
        arrTexCoordABC[2] = (const TextureCoord2 *)( arrTexCoords + iC );
        if ( bHasTangents ) {
            arrTangentABC[0] = (Vector4 *)( arrTangents + iA );
            arrTangentABC[1] = (Vector4 *)( arrTangents + iB );
            arrTangentABC[2] = (Vector4 *)( arrTangents + iC );
        }
        if ( bHasBiNormals ) {
            arrBiNormalABC[0] = (Vector4 *)( arrBiNormals + iA );
            arrBiNormalABC[1] = (Vector4 *)( arrBiNormals + iB );
            arrBiNormalABC[2] = (Vector4 *)( arrBiNormals + iC );
        }

        for( j = 0; j < 3; ++j ) {
            vCur = ( bHasTangents ) ? *(arrTangentABC[j]) : *(arrBiNormalABC[j]);
            if ( vCur.X != 0.0f || vCur.Y != 0.0f || vCur.Z != 0.0f )
                continue; // already visited

            iNext = (j+1) % 3;
            iPrev = (j+2) % 3;

            // Compute tangent & binormal
            vNormal = *( arrNormalABC[j] );            
            vTangent = _ComputeTexCoordTangent( *(arrPositionABC[j]), *(arrTexCoordABC[j]),
                                                *(arrPositionABC[iNext]), *(arrTexCoordABC[iNext]),
                                                *(arrPositionABC[iPrev]), *(arrTexCoordABC[iPrev]) );
            vTangent -= ( vNormal * (vNormal * vTangent) );
            vTangent.Normalize();
            vBiNormal = ( vNormal ^ vTangent );

            // Update
            if ( bHasTangents )
                *( arrTangentABC[j] ) = vTangent;
            if ( bHasBiNormals )
                *( arrBiNormalABC[j] ) = vBiNormal;
        }
    }

    // End update
    if ( m_pVB->CanUpdate() )
        m_pVB->Update( 0, INVALID_OFFSET, pContext );
    else
        m_pVB->UnLock( pContext );
}
Exemple #9
0
Void TriangleMesh::UpdateTangentsFromGeometry( GPUDeferredContext * pContext )
{
    Assert( m_pIL != NULL && m_pVB != NULL );
    Assert( m_pIL->IsBound() && m_pVB->IsBound() );

    Bool bHasNormals = m_pIL->HasField( GPUINPUTFIELD_SEMANTIC_NORMAL, 0 );
    if ( !bHasNormals )
        return;
    Bool bHasTangents =  m_pIL->HasField( GPUINPUTFIELD_SEMANTIC_TANGENT, 0 );
    Bool bHasBiNormals = m_pIL->HasField( GPUINPUTFIELD_SEMANTIC_BINORMAL, 0 );
    if ( !bHasTangents && !bHasBiNormals )
        return;

    // Begin update
    Byte * pFirstVertex = NULL;
    if ( m_pVB->CanUpdate() ) {
        Assert( m_pVB->HasCPUData() );
        pFirstVertex = m_pVB->GetData( m_iVertexOffset );
    } else {
        Assert( m_pVB->CanLock() );
        UInt iByteSize = 0;
        pFirstVertex = (Byte*)( m_pVB->Lock( GPURESOURCE_LOCK_WRITE, 0, &iByteSize, pContext ) );
        Assert( iByteSize == m_pVB->GetSize() );
    }

    // Update
    UInt iVertexSize = m_pVB->GetElementSize();

    UInt iOffset, iSize;
    const Byte * arrPositions = NULL;
    const Byte * arrNormals = NULL;
    Byte * arrTangents = NULL;
    Byte * arrBiNormals = NULL;

    m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_POSITION, 0 );
    arrPositions = ( pFirstVertex + iOffset );
    m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_NORMAL, 0 );
    arrNormals = ( pFirstVertex + iOffset );
    if ( bHasTangents ) {
        m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_TANGENT, 0 );
        arrTangents = ( pFirstVertex + iOffset );
    }
    if ( bHasBiNormals ) {
        m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_BINORMAL, 0 );
        arrBiNormals = ( pFirstVertex + iOffset );
    }

    UInt i, iTriangleCount = GetTriangleCount();

        // Start using temp storage
    RenderingFn->SelectMemory( TEXT("Scratch") );
    Matrix4 * arrDerivateNormals = New Matrix4[m_iVertexCount];

        // Compute derivate normals (dN/dX)
    _ComputeDerivateNormals( arrDerivateNormals, m_iVertexCount, iTriangleCount,
                             arrPositions, arrNormals, iVertexSize );

        // Perform update
    const Vector4 * pNormal;
    Vector4 *pTangent, *pBiNormal;

    Vector4 vU, vV;
    Scalar fS01, fS10, fSAvg;
    Matrix2 matS;
    Scalar fTrace, fDet, fDiscr, fRootDiscr;
    Scalar fMinCurvature; //, fMaxCurvature;
    Vector2 vEigen0, vEigen1;
    Vector4 vTangent, vBinormal;

    for( i = 0; i < m_iVertexCount; ++i ) {
        iOffset = ( i * iVertexSize );
        pNormal = (const Vector4 *)( arrNormals + iOffset );

        // Compute J = [U V] such that (U,V,N) is orthonormal
        Vector4::MakeComplementBasis( vU, vV, *pNormal );

        // Compute shape matrix S = tJ * dN/dX * J, enforce symmetry
        fS01 = ( vU * (arrDerivateNormals[i] * vV) );
        fS10 = ( vV * (arrDerivateNormals[i] * vU) );
        fSAvg = ( fS01 + fS10 ) * 0.5f;
        matS.m00 = ( vU * (arrDerivateNormals[i] * vU) ); matS.m01 = fSAvg;
        matS.m10 = fSAvg;                                 matS.m11 = ( vV * (arrDerivateNormals[i] * vV) );

        // Eigenvalues of S are principal curvatures (k0 and k1)
        fTrace = ( matS.m00 + matS.m11 );
        fDet = matS.Determinant();
        fDiscr = ( fTrace * fTrace - 4.0f * fDet );
        fRootDiscr = MathFn->Sqrt( MathFn->Abs(fDiscr) );
        fMinCurvature = (fTrace - fRootDiscr) * 0.5f;
        //fMaxCurvature = (fTrace + fRootDiscr) * 0.5f;

        // Eigenvectors of S (W0 and W1)
        vEigen0.X = matS.m01;
        vEigen0.Y = fMinCurvature - matS.m00;
        vEigen1.X = fMinCurvature - matS.m11;
        vEigen1.Y = matS.m10;

        // Deduce principal directions (S*W=k*W => k=J*W) and assign them as tangent & binormal
        if ( vEigen0.NormSqr() >= vEigen1.NormSqr() ) {
            vEigen0.Normalize();
            vTangent = ( (vU * vEigen0.X) + (vV * vEigen0.Y) );
            vBinormal = ( (*pNormal) ^ vTangent );
        } else {
            vEigen1.Normalize();
            vTangent = ( (vU * vEigen1.X) + (vV * vEigen1.Y) );
            vBinormal = ( (*pNormal) ^ vTangent );
        }

        // Update
        if ( bHasTangents ) {
            pTangent = (Vector4*)( arrTangents + iOffset );
            *pTangent = vTangent;
        }
        if ( bHasBiNormals ) {
            pBiNormal = (Vector4*)( arrBiNormals + iOffset );
            *pBiNormal = vBinormal;
        }
    }

        // End using temp storage
    DeleteA( arrDerivateNormals );

    RenderingFn->UnSelectMemory();

    // End update
    if ( m_pVB->CanUpdate() )
        m_pVB->Update( 0, INVALID_OFFSET, pContext );
    else
        m_pVB->UnLock( pContext );
}
Exemple #10
0
Void TriangleMesh::UpdateNormals( GPUDeferredContext * pContext )
{
    Assert( m_pIL != NULL && m_pVB != NULL );
    Assert( m_pIL->IsBound() && m_pVB->IsBound() );

    Bool bHasNormals = m_pIL->HasField( GPUINPUTFIELD_SEMANTIC_NORMAL, 0 );
    if ( !bHasNormals )
        return;

    // Begin update
    Byte * pFirstVertex = NULL;
    if ( m_pVB->CanUpdate() ) {
        Assert( m_pVB->HasCPUData() );
        pFirstVertex = m_pVB->GetData( m_iVertexOffset );
    } else {
        Assert( m_pVB->CanLock() );
        UInt iByteSize = 0;
        pFirstVertex = (Byte*)( m_pVB->Lock( GPURESOURCE_LOCK_WRITE, 0, &iByteSize, pContext ) );
        Assert( iByteSize == m_pVB->GetSize() );
    }

    // Update normals
    UInt iVertexSize = m_pVB->GetElementSize();

    UInt iOffset, iSize;
    const Byte * arrPositions = NULL;
    Byte * arrNormals = NULL;

    m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_POSITION, 0 );
    arrPositions = ( pFirstVertex + iOffset );
    m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_NORMAL, 0 );
    arrNormals = ( pFirstVertex + iOffset );

    UInt i, iTriangleCount = GetTriangleCount();

        // Set all normals to null vector
    Byte * pCurNormal = arrNormals;
    Vector4 * pNormal;

    for( i = 0; i < m_iVertexCount; ++i ) {
        pNormal = (Vector4*)pCurNormal;
        pNormal->X = 0.0f;
        pNormal->Y = 0.0f;
        pNormal->Z = 0.0f;
        pCurNormal += iVertexSize;
    }

        // Weighted sum of facet normals
    UInt iA, iB, iC;
    const Vertex4 *pA, *pB, *pC;

    Vector4 vAB, vAC, vFaceNormal;

    for( i = 0; i < iTriangleCount; ++i ) {
        GetTriangle( i, iA, iB, iC );
        iA *= iVertexSize;
        iB *= iVertexSize;
        iC *= iVertexSize;

        pA = (const Vertex4 *)( arrPositions + iA );
        pB = (const Vertex4 *)( arrPositions + iB );
        pC = (const Vertex4 *)( arrPositions + iC );

        vAB = ( *pB - *pA );
        vAC = ( *pC - *pA );
        vFaceNormal = ( vAB ^ vAC );
        vFaceNormal.Normalize();

        pNormal = (Vector4*)( arrNormals + iA );
        *pNormal += vFaceNormal;
        pNormal = (Vector4*)( arrNormals + iB );
        *pNormal += vFaceNormal;
        pNormal = (Vector4*)( arrNormals + iC );
        *pNormal += vFaceNormal;
    }

        // Normalize all again
    pCurNormal = arrNormals;
    for( i = 0; i < m_iVertexCount; ++i ) {
        pNormal = (Vector4*)pCurNormal;
        pNormal->Normalize();
        pCurNormal += iVertexSize;
    }

    // End update
    if ( m_pVB->CanUpdate() )
        m_pVB->Update( 0, INVALID_OFFSET, pContext );
    else
        m_pVB->UnLock( pContext );
}
 /// \brief
 ///   Return the number of triangle surface indices in this mesh.
 inline int GetTriSrfIndexCount() const 
 { 
   return m_pTriSrfIndices ? GetTriangleCount() : 0;
 }
FractureMesh *FractureMesh::Fracture()
{
    FractureMesh *fracMesh = new FractureMesh();

    std::vector<Vertex *>::iterator vIt = VertexIterBegin();
    //Used to determine where the ID values should start for the new vertices
    int maxVertIdx = -1;
    for(; vIt != VertexIterEnd(); ++vIt)
    {
        fracMesh->CopyAddVertex(*vIt);
        //Check if vertex's ID is the largest seen so far
        if((*vIt)->GetID() > maxVertIdx)
            maxVertIdx = (*vIt)->GetID();
    }
    //Increment so that the ID is now unique
    maxVertIdx++;

    int maxTexIdx = -1;
    std::vector<TexCoord *>::iterator texIt = TexCoordIterBegin();
    for(;texIt != TexCoordIterEnd(); ++texIt)
    {
        fracMesh->CopyAddTexCoord(*texIt);
        if((*texIt)->GetID() > maxTexIdx)
            maxTexIdx = (*texIt)->GetID();
    }
    //Increment so that the ID is now unique
    maxTexIdx++;

    //Reset visitation value for each triangle and
    //set to have no fracture
    std::vector<Triangle *>::iterator tIt = TriangleIterBegin();
    std::vector<Triangle *>::iterator triEnd = TriangleIterEnd();
    for(; tIt != triEnd; ++tIt)
    {
        (*tIt)->SetIsVisited(false);
    }
    //Clear fractures flag?


    //Loop through every triangle and calculate its MatchedTriangle
    tIt = TriangleIterBegin();
#if defined(_DEBUG) || defined(FORCE_DEBUG_PRINT)
    int debug = 0;
#endif
    float maxIterations = float((3 * GetTriangleCount()) + GetEdgeCount());
    float curIter = 0;
    DEBUG_PRINT("Matching fractures...\n");
    for(; tIt != triEnd; ++tIt)
    {
        Triangle *const curTri = *tIt;

        Global::gMainWindow->SetProgress((100.f * ++curIter) / maxIterations, 0);
        //Calculate the spans between fracture points along
        //the triangle's edges and inside
        curTri->CalcFractureMatches(mFracMap);
        //Initialize the triangle's FractureInfo. This includes
        //creating the actual inner Vertices
        curTri->InitFractureInfo(&maxVertIdx, &maxTexIdx, fracMesh);
    }

    std::vector<Edge *>::iterator eIt = EdgeIterBegin();
    std::vector<Edge *>::iterator edgeEnd = EdgeIterEnd();
#if defined(_DEBUG) || defined(FORCE_DEBUG_PRINT)
    debug = 0;
#endif
    DEBUG_PRINT("Resolving edges...\n");
    for (; eIt != edgeEnd; ++eIt)
    {
        //This resolves each FracHalfEdge into a single list of FracVerts
        //for the edge. This also creates the actual vertices/texcoords
        //and adds them to the fracMesh
        Global::gMainWindow->SetProgress((100.f * ++curIter) / maxIterations, 0);
        (*eIt)->ResolveFractureEdge(&maxVertIdx, &maxTexIdx, fracMesh);
    }

#if defined(_DEBUG) || defined(FORCE_DEBUG_PRINT)
    debug = 0;
#endif
    tIt = TriangleIterBegin();
    static int test = 0;
    DEBUG_PRINT("Triangulating...\n");
    for(; tIt != triEnd; ++tIt)
    {
        Global::gMainWindow->SetProgress((100.f * ++curIter) / maxIterations, 0);
        Triangle *const curTri = *tIt;
        if(curTri->RequiresTriangulation())
            curTri->TriangulateFractures(fracMesh);
        else
        {
            fracMesh->AddTriangle(
                curTri->GetVertex(0)->GetID(),
                curTri->GetVertex(1)->GetID(),
                curTri->GetVertex(2)->GetID(),
                curTri->GetTexCoord(0)->GetID(),
                curTri->GetTexCoord(1)->GetID(),
                curTri->GetTexCoord(2)->GetID(),
                curTri->GetNormal());
        }
    }

    ASSERT(fracMesh != NULL);
    return fracMesh;
}