示例#1
0
void mCSkin::LimitNumInfluencingBonesPerVert( MIUInt const a_uMax )
{
    mTArray< MIUInt >  arrVertexIndices( m_arrVertexIndices.GetCount() );
    mTArray< MIUInt >  arrBoneIndices( m_arrBoneIndices.GetCount() );
    mTArray< MIFloat > arrWeights( m_arrWeights.GetCount() );
    mTArray< MIUInt >  arrVertWeightIndices( 0, 100 );
    MIUInt * pVertWeightIndices = arrVertWeightIndices.AccessBuffer();
    for ( MIUInt u = 0, ue = GetNumVerts(); u != ue; ++u )
    {
        MIUInt uWeightCount = GetNumInfluencingBones( u );
        MIFloat fWeightSum = 0.0f;
        s_pWeights = &m_arrWeights[ m_arrFirstWeightIndexPerVertex[ u ] ];
        for ( MIUInt v = uWeightCount; v--; pVertWeightIndices[ v ] = v );
        qsort( pVertWeightIndices, uWeightCount, sizeof( *pVertWeightIndices ), &CompareVretWeightIndices );
        uWeightCount = g_min( uWeightCount, a_uMax );
        for ( MIUInt v = 0; v != uWeightCount; ++v )
        {
            arrVertexIndices.Add( u );
            arrBoneIndices.Add( GetBoneIndex( u, pVertWeightIndices[ v ] ) );
            arrWeights.Add( s_pWeights[ pVertWeightIndices[ v ] ] );
            fWeightSum += s_pWeights[ pVertWeightIndices[ v ] ];
        }
        for ( MIFloat * pWeights = &arrWeights.Back(), * pEnd = pWeights - uWeightCount; pWeights != pEnd; *pWeights-- /= fWeightSum );
    }
    arrVertexIndices.UnReserve();
    arrBoneIndices.UnReserve();
    arrWeights.UnReserve();
    mCSkin skinResult;
    skinResult.InitSwapping( GetNumVerts(), m_arrBoneIDs, arrVertexIndices, arrBoneIndices, arrWeights );
    Swap( skinResult );
}
示例#2
0
/*!
 * \param [in] v the vertex to add, Vector3<float>
 * \param [out] indx  the index to the vertex, unsigned int
 * \return a bool indicating whether the HalfEdgeMesh::Vertex was successfully inserted (true) or already existed (false)
 */
bool HalfEdgeMesh::AddVertex(const Vector3<float> & v, unsigned int &indx){
  std::map<Vector3<float>,unsigned int>::iterator it = mUniqueVerts.find(v);
  if (it != mUniqueVerts.end()){
    indx = (*it).second; // get the index of the already existing vertex
    return false;
  }

  mUniqueVerts[v] = indx = GetNumVerts(); // op. [ ] constructs a new entry in map
  Vertex vert;
  vert.pos = v;
  mVerts.push_back(vert); // add it to the vertex list

  return true;
}
示例#3
0
MIUInt mCSkin::GetNumInfluencingBones( MIUInt a_uVertexIndex ) const
{
    MIUInt const uNextFirstIndex = ( a_uVertexIndex + 1 < GetNumVerts() ) ? m_arrFirstWeightIndexPerVertex[ a_uVertexIndex + 1 ] : GetNumWeights();
    return uNextFirstIndex - m_arrFirstWeightIndexPerVertex[ a_uVertexIndex ];
}
示例#4
0
void HalfEdgeMesh::Update() {
  // Calculate and store all differentials and area

  // First update all face normals and triangle areas
  for(unsigned int i = 0; i < GetNumFaces(); i++){
    f(i).normal = FaceNormal(i);
  }
  // Then update all vertex normals and curvature
  for(unsigned int i = 0; i < GetNumVerts(); i++){
    // Vertex normals are just weighted averages
    mVerts.at(i).normal = VertexNormal(i);
  }

  // Then update vertex curvature
  for(unsigned int i = 0; i < GetNumVerts(); i++){
    mVerts.at(i).curvature = VertexCurvature(i);
    //    std::cerr <<   mVerts.at(i).curvature << "\n";
  }

  // Finally update face curvature
  for(unsigned int i = 0; i < GetNumFaces(); i++){
    f(i).curvature = FaceCurvature(i);
  }

  std::cerr << "Area: " << Area() << ".\n";
  std::cerr << "Volume: " << Volume() << ".\n";

  // Update vertex and face colors
  if (mVisualizationMode == CurvatureVertex) {
    std::vector<Vertex>::iterator iter = mVerts.begin();
    std::vector<Vertex>::iterator iend = mVerts.end();
    float minCurvature = (std::numeric_limits<float>::max)();
    float maxCurvature = -(std::numeric_limits<float>::max)();
    while (iter != iend) {
      if (minCurvature > (*iter).curvature)  minCurvature = (*iter).curvature;
      if (maxCurvature < (*iter).curvature)  maxCurvature = (*iter).curvature;
      iter++;
    }
    std::cerr << "Mapping color based on vertex curvature with range [" << minCurvature << "," << maxCurvature << "]" << std::endl;
    iter = mVerts.begin();
    while (iter != iend) {
      (*iter).color = mColorMap->Map((*iter).curvature, minCurvature, maxCurvature);
      iter++;
    }
  }
  else if (mVisualizationMode == CurvatureFace) {
    std::vector<Face>::iterator iter = mFaces.begin();
    std::vector<Face>::iterator iend = mFaces.end();
    float minCurvature = (std::numeric_limits<float>::max)();
    float maxCurvature = -(std::numeric_limits<float>::max)();
    while (iter != iend) {
      if (minCurvature > (*iter).curvature)  minCurvature = (*iter).curvature;
      if (maxCurvature < (*iter).curvature)  maxCurvature = (*iter).curvature;
      iter++;
    }
    std::cerr << "Mapping color based on face curvature with range [" << minCurvature << "," << maxCurvature << "]" << std::endl;
    iter = mFaces.begin();
    while (iter != iend) {
      (*iter).color = mColorMap->Map((*iter).curvature, minCurvature, maxCurvature);
      iter++;
    }
  }

}
示例#5
0
/*! Proceeds to check if the mesh is valid. All indices are inspected and
 * checked to see that they are initialized. The method checks: mEdges, mFaces and mVerts.
 * Also checks to see if all verts have a neighborhood using the findNeighbourFaces method.
 */
void HalfEdgeMesh::Validate()
{
  std::vector<HalfEdge>::iterator iterEdge = mEdges.begin();
  std::vector<HalfEdge>::iterator iterEdgeEnd = mEdges.end();
  while (iterEdge != iterEdgeEnd) {
    if ((*iterEdge).face == UNINITIALIZED ||
        (*iterEdge).next == UNINITIALIZED ||
        (*iterEdge).pair == UNINITIALIZED ||
        (*iterEdge).prev == UNINITIALIZED ||
        (*iterEdge).vert == UNINITIALIZED)
        std::cerr << "HalfEdge " << iterEdge - mEdges.begin() << " not properly initialized" << std::endl;

    iterEdge++;
  }
  std::cerr << "Done with edge check (checked " << GetNumEdges() << " edges)" << std::endl;

  std::vector<Face>::iterator iterTri = mFaces.begin();
  std::vector<Face>::iterator iterTriEnd = mFaces.end();
  while (iterTri != iterTriEnd) {
    if ((*iterTri).edge == UNINITIALIZED)
        std::cerr << "Tri " << iterTri - mFaces.begin() << " not properly initialized" << std::endl;

    iterTri++;
  }
  std::cerr << "Done with face check (checked " << GetNumFaces() << " faces)" << std::endl;

  std::vector<Vertex>::iterator iterVertex = mVerts.begin();
  std::vector<Vertex>::iterator iterVertexEnd = mVerts.end();
  while (iterVertex != iterVertexEnd) {
    if ((*iterVertex).edge == UNINITIALIZED)
        std::cerr << "Vertex " << iterVertex - mVerts.begin() << " not properly initialized" << std::endl;

    iterVertex++;
  }
  std::cerr << "Done with vertex check (checked " << GetNumVerts() << " vertices)" << std::endl;

  std::cerr << "Looping through triangle neighborhood of each vertex... ";
  iterVertex = mVerts.begin();
  iterVertexEnd = mVerts.end();
  int emptyCount = 0;
  std::vector<unsigned int> problemVerts;
  while (iterVertex != iterVertexEnd) {
    std::vector<unsigned int> foundFaces = FindNeighborFaces(iterVertex - mVerts.begin());
    std::vector<unsigned int> foundVerts = FindNeighborVertices(iterVertex - mVerts.begin());
    if (foundFaces.empty() || foundVerts.empty())
      emptyCount++;
    std::set<unsigned int> uniqueFaces(foundFaces.begin(), foundFaces.end());
    std::set<unsigned int> uniqueVerts(foundVerts.begin(), foundVerts.end());
        if ( foundFaces.size() != uniqueFaces.size() ||
         foundVerts.size() != uniqueVerts.size() )
      problemVerts.push_back(iterVertex - mVerts.begin());
    iterVertex++;
  }
  std::cerr << std::endl << "Done: " << emptyCount << " isolated vertices found" << std::endl;
  if(problemVerts.size()){
    std::cerr << std::endl << "Found " << problemVerts.size() << " duplicate faces in vertices: ";
    std::copy(problemVerts.begin(), problemVerts.end(), std::ostream_iterator<unsigned int>(std::cerr, ", "));
    std::cerr << "\n";
  }
  std::cerr << std::endl << "The mesh has genus " << Genus() << ", and consists of " << Shells() << " shells.\n";
}
示例#6
0
int StaticMesh::GetAvailableVertexSpace() const
{
    return MAX_VERTICES - GetNumVerts();
}
示例#7
0
int MyMeshText::CreateString(bool concat, float fontheight, float x, float y, float z, float rotz, unsigned char justificationflags, ColorByte color, Vector2 size, const char* text, ...)
{
    assert( m_pFont && m_pFont->m_pFont );

    if( strlen( text ) == 0 )
        return 0;

    const char* stringtodraw = text;
    if( g_pLanguageTable != 0 && text[0] == '.' )
        stringtodraw = g_pLanguageTable->LookUp( text );

    int numlines = 0;

    if( concat == false )
    {
        ClearText();
    }

    bool moretexttocome = true;
    const char* stringpos = stringtodraw;

    while( moretexttocome )
    {
        numlines++;

        char singlelinebuffer[300];
        singlelinebuffer[0] = 0;
        char* singlelinebufferpos = singlelinebuffer;

        // word wrap if width of text is not 0.
        if( size.x != 0 )
        {
            float linewidth = -1;// = GetStringSize( fontheight, Vector2(0,0), singlelinebuffer ).x;
            while( linewidth < size.x &&
                    *stringpos != 0 )
            {
                *singlelinebufferpos = *stringpos;
                singlelinebufferpos++;
                *singlelinebufferpos = 0;
                stringpos++;

                linewidth = GetStringSize( fontheight, Vector2(0,0), singlelinebuffer ).x;

                assert( singlelinebufferpos < singlelinebuffer + 300 );
            }

            int numcharswewentback = 0;
            while( ( *(singlelinebufferpos-1) != ' ' && *stringpos != 0 ) &&
                    singlelinebufferpos > singlelinebuffer )
            {
                singlelinebufferpos--;
                numcharswewentback++;
            }

            if( singlelinebufferpos != singlelinebuffer )
            {
                *singlelinebufferpos = 0;
                stringpos -= numcharswewentback;
            }

            if( *stringpos == 0 )
                moretexttocome = false;

            stringtodraw = singlelinebuffer;
        }
        else
        {
            moretexttocome = false;
        }
            
        //// don't bother drawing if fontheight is zero... still doing logic above so the currect number of lines will be returned.
        //if( g_pRTQGlobals->m_WordWrapCountLinesOnly )
        //    continue;

        Vertex_XYZUV_RGBA* pVertsToDraw = (Vertex_XYZUV_RGBA*)GetVerts( true );

        int newverts = (int)strlen( stringtodraw ) * 4;
#if _DEBUG
        m_MostLettersAttemptedToDrawThisFrame += newverts/4;
        if( m_MostLettersAttemptedToDrawThisFrame > m_MostLettersAttemptedToDrawEver )
            m_MostLettersAttemptedToDrawEver = m_MostLettersAttemptedToDrawThisFrame;
#endif

        if( m_NumVertsToDraw + newverts > GetNumVerts() )
        {
#if _DEBUG
            LOGInfo( LOGTag, "TextMesh buffer isn't big enough for string (%s) - %d of %d letters used - most letters needed (%d)\n", stringtodraw, m_NumVertsToDraw/4, GetNumVerts()/4, m_MostLettersAttemptedToDrawEver );
#endif
            //assert( false ); // drawing more than we have room for.
            return 0;
        }

        pVertsToDraw += m_NumVertsToDraw;

        unsigned int textstrlen = m_pFont->m_pFont->GenerateVerts( stringtodraw, true, pVertsToDraw, fontheight, GL_TRIANGLES, justificationflags, color );

        m_NumVertsToDraw += (unsigned short)(textstrlen * 4);
        m_NumIndicesToDraw += textstrlen * 6;

        MyMatrix position;
        position.SetIdentity();
        position.Rotate( rotz, 0, 0, 1 );
        position.SetPosition( x, y - (numlines-1)*fontheight, z );
        //position.SetPosition( x, y - (numlines-1)*g_pRTQGlobals->m_WordWrapLineIncSize, z );
        //position.SetPosition( x, y, z );

        for( unsigned int i=0; i<textstrlen*4; i++ )
        {
            Vector3 out = position.TransformVector3( *(Vector3*)&pVertsToDraw[i].x );
            pVertsToDraw[i].x = out.x;
            pVertsToDraw[i].y = out.y;
            pVertsToDraw[i].z = out.z;
        }
    }

    return numlines;
}