示例#1
0
文件: coremodel.cpp 项目: newobj/taz
int CalCoreModel::loadCoreMesh(const std::string& strFilename, const char* pbyBuffer, unsigned long nBufferSize)
{
  // the core skeleton has to be loaded already
  if(m_pCoreSkeleton == 0)
  {
    CalError::setLastError(CalError::INVALID_HANDLE, __FILE__, __LINE__);
    return -1;
  }

  // load a new core mesh
  CalLoader loader;
  CalCoreMesh *pCoreMesh;
  pCoreMesh = loader.loadCoreMesh(strFilename, pbyBuffer, nBufferSize);
  if(pCoreMesh == 0) return -1;

  // add core mesh to this core model
  int meshId;
  meshId = addCoreMesh(pCoreMesh);
  if(meshId == -1)
  {
    pCoreMesh->release();
    return -1;
  }

  return meshId;
}
示例#2
0
void CalCoreBone::calculateBoundingBox(CalCoreModel * pCoreModel)
{
   int boneId = m_pCoreSkeleton->getCoreBoneId(m_strName);
   bool bBoundsComputed = false;
   
   initBoundingBox();
   
   int meshId;
   for(meshId=0; meshId < pCoreModel->getCoreMeshCount(); ++meshId)
   {
       CalCoreMesh * pCoreMesh = pCoreModel->getCoreMesh(meshId);

       int submeshId;
       for(submeshId=0;submeshId<pCoreMesh->getCoreSubmeshCount();submeshId++)
       {
         CalCoreSubmesh *pCoreSubmesh = pCoreMesh->getCoreSubmesh(submeshId);

         if(pCoreSubmesh->getSpringCount()==0)
         {
            std::vector<CalCoreSubmesh::Vertex>& vectorVertex =  pCoreSubmesh->getVectorVertex();
            for(size_t vertexId=0;vertexId <vectorVertex.size(); ++vertexId)
            {
               for(size_t influenceId=0;influenceId<vectorVertex[vertexId].vectorInfluence.size();++influenceId)
               {
                  CalCoreSubmesh::Influence &influence = vectorVertex[vertexId].vectorInfluence[influenceId];
                  if(influence.boneId == boneId && influence.weight > 0.5f)
                  {
                     const bool updated = updateBoundingBox(vectorVertex[vertexId].position);
                     bBoundsComputed = bBoundsComputed || updated;
                  }
               }
            }   
         }
      }
   }

   // To handle bones with no vertices assigned (do not "optimize" this code away!)
   if(!bBoundsComputed)
   {
      for(int planeId = 0; planeId < 6; ++planeId)
      {
         m_boundingBox.plane[planeId].setPosition(m_translation);
         m_boundingPosition[planeId] = m_translation;
      }
   }

   m_boundingBoxPrecomputed = true;
}
示例#3
0
CalCoreModel*
osgCal::loadCoreModel( const std::string& cfgFileName,
                       float& scale,
                       bool ignoreMeshes )
    throw (std::runtime_error)
{
    // -- Initial loading of model --
    scale = 1.0f;
    bool bScale = false;

    FILE* f = fopen( cfgFileName.c_str(), "r" );
    if( !f )
    {
        throw std::runtime_error( "Can't open " + cfgFileName );
    }
    FileCloser closer( f );

    std::auto_ptr< CalCoreModel > calCoreModel( new CalCoreModel( "dummy" ) );

    // Extract path from fileName
    std::string dir = osgDB::getFilePath( cfgFileName );

    static const int LINE_BUFFER_SIZE = 4096;
    char buffer[LINE_BUFFER_SIZE];

    while ( fgets( buffer, LINE_BUFFER_SIZE,f ) )
    {
        // Ignore comments or empty lines
        if ( *buffer == '#' || *buffer == 0 )
            continue;

        char* equal = strchr( buffer, '=' );
        if ( equal )
        {
            // Terminates first token
            *equal++ = 0;
            // Removes ending newline ( CR & LF )
            {
                int last = strlen( equal ) - 1;
                if ( equal[last] == '\n' ) equal[last] = 0;
                if ( last > 0 && equal[last-1] == '\r' ) equal[last-1] = 0;
            }

            // extract file name. all animations, meshes and materials names
            // are taken from file name without extension
            std::string nameToLoad;
            char* point = strrchr( equal, '.' );
            if ( point )
            {
                nameToLoad = std::string( equal, point );
            }
            else
            {
                nameToLoad = equal;
            }

            std::string fullpath = dir + "/" + std::string( equal );

            // process .cfg parameters
            if ( !strcmp( buffer, "scale" ) )
            {
                bScale	= true;
                std::istringstream equal_stream(equal);
                equal_stream.imbue(std::locale::classic());
                equal_stream >> scale;
                continue;
            }

            if ( !strcmp( buffer, "skeleton" ) )
            {
                if( !calCoreModel->loadCoreSkeleton( fullpath ) )
                {
                    throw std::runtime_error(
                        "Can't load skeleton: "
                        + CalError::getLastErrorDescription() );
                }
            }
            else if ( !strcmp( buffer, "animation" ) )
            {
                int animationId = calCoreModel->loadCoreAnimation( fullpath );
                if( animationId < 0 )
                {
                    throw std::runtime_error(
                         "Can't load animation " + nameToLoad + ": "
                         + CalError::getLastErrorDescription() );
                }
                calCoreModel->getCoreAnimation(animationId)
                    ->setName( nameToLoad );
            }
            else if ( !strcmp( buffer, "mesh" ) )
            {
                if ( ignoreMeshes )
                {
                     // we don't need meshes since VBO data is already loaded
                     // from cache
                    continue;
                }

                int meshId = calCoreModel->loadCoreMesh( fullpath );
                if( meshId < 0 )
                {
                    throw std::runtime_error(
                        "Can't load mesh " + nameToLoad + ": "
                        + CalError::getLastErrorDescription() );
                }
                calCoreModel->getCoreMesh( meshId )->setName( nameToLoad );

                // -- Remove zero influence vertices --
                // warning: this is a temporary workaround and subject to
                // remove! (this actually must be fixed in blender exporter)
                CalCoreMesh* cm = calCoreModel->getCoreMesh( meshId );

                for ( int i = 0; i < cm->getCoreSubmeshCount(); i++ )
                {
                    CalCoreSubmesh* sm = cm->getCoreSubmesh( i );

                    std::vector< CalCoreSubmesh::Vertex >& v =
                        sm->getVectorVertex();

                    for ( size_t j = 0; j < v.size(); j++ )
                    {

                        std::vector< CalCoreSubmesh::Influence >& infl =
                             v[j].vectorInfluence;

                        std::vector< CalCoreSubmesh::Influence >::iterator it =
                            infl.begin();
                        for ( ;it != infl.end(); )
                        {
                            if ( it->weight <= 0.0001 ) it = infl.erase( it );
                            else ++it;
                        }

                        std::sort( infl.begin(), infl.end(),
                          DataCmp<CalCoreSubmesh::Influence,float>
                            (FIELD_OFFSET(CalCoreSubmesh::Influence,weight)) );
                    }
                }
            }
            else if ( !strcmp( buffer, "material" ) )
            {
                int materialId = calCoreModel->loadCoreMaterial( fullpath );

                if( materialId < 0 )
                {
                    throw std::runtime_error(
                        "Can't load material " + nameToLoad + ": "
                        + CalError::getLastErrorDescription() );
                }
                else
                {
                    calCoreModel->createCoreMaterialThread( materialId );
                    calCoreModel->setCoreMaterialId(
                        materialId, 0, materialId );

                    CalCoreMaterial* material =
                        calCoreModel->getCoreMaterial( materialId );
                    material->setName( nameToLoad );
                }
            }
        }
    }
示例#4
0
void
loadMeshes( CalCoreModel* calCoreModel,
            MeshesVector& meshes )
    throw (std::runtime_error)
{
    const int maxVertices = Constants::MAX_VERTEX_PER_MODEL;
    const int maxFaces    = Constants::MAX_VERTEX_PER_MODEL * 3;

    std::auto_ptr< CalHardwareModel > calHardwareModel( new CalHardwareModel( calCoreModel ) );
    
    osg::ref_ptr< VertexBuffer >      vertexBuffer( new VertexBuffer( maxVertices ) );
    osg::ref_ptr< WeightBuffer >      weightBuffer( new WeightBuffer( maxVertices ) );
    osg::ref_ptr< MatrixIndexBuffer > matrixIndexBuffer( new MatrixIndexBuffer( maxVertices ) );
    osg::ref_ptr< NormalBuffer >      normalBuffer( new NormalBuffer( maxVertices ) );
    osg::ref_ptr< NormalBuffer >      tangentBuffer( new NormalBuffer( maxVertices ) );
    osg::ref_ptr< NormalBuffer >      binormalBuffer( new NormalBuffer( maxVertices ) );
    osg::ref_ptr< TexCoordBuffer >    texCoordBuffer( new TexCoordBuffer( maxVertices ) );
    std::vector< CalIndex >           indexBuffer( maxFaces*3 );

    std::vector< float > floatMatrixIndexBuffer( maxVertices*4 );

    calHardwareModel->setVertexBuffer((char*)vertexBuffer->getDataPointer(),
                                      3*sizeof(float));
#ifdef OSG_CAL_BYTE_BUFFERS
    std::vector< float > floatNormalBuffer( getVertexCount()*3 );
    calHardwareModel->setNormalBuffer((char*)&floatNormalBuffer.begin(),
                                      3*sizeof(float));
#else
    calHardwareModel->setNormalBuffer((char*)normalBuffer->getDataPointer(),
                                      3*sizeof(float));
#endif
    calHardwareModel->setWeightBuffer((char*)weightBuffer->getDataPointer(),
                                      4*sizeof(float));
    calHardwareModel->setMatrixIndexBuffer((char*)&floatMatrixIndexBuffer.front(),
                                           4*sizeof(float));
    calHardwareModel->setTextureCoordNum( 1 );
    calHardwareModel->setTextureCoordBuffer(0, // texture stage #
                                            (char*)texCoordBuffer->getDataPointer(),
                                            2*sizeof(float));
    calHardwareModel->setIndexBuffer( &indexBuffer.front() );
    // calHardwareModel->setCoreMeshIds(_activeMeshes);
    // if ids not set all meshes will be used at load() time

    //std::cout << "calHardwareModel->load" << std::endl;
    calHardwareModel->load( 0, 0, Constants::MAX_BONES_PER_MESH );
    //std::cout << "calHardwareModel->load ok" << std::endl;

    int vertexCount = calHardwareModel->getTotalVertexCount();
//    int faceCount   = calHardwareModel->getTotalFaceCount();

//    std::cout << "vertexCount = " << vertexCount << "; faceCount = " << faceCount << std::endl;
    
    GLubyte* matrixIndexBufferData = (GLubyte*) matrixIndexBuffer->getDataPointer();

    for ( int i = 0; i < vertexCount*4; i++ )
    {
        matrixIndexBufferData[i] = static_cast< GLubyte >( floatMatrixIndexBuffer[i] );
    }

#ifdef OSG_CAL_BYTE_BUFFERS
    GLbyte* normals = (GLbyte*) normalBuffer->getDataPointer();

    for ( int i = 0; i < vertexCount*3; i++ )
    {
        normals[i]  = static_cast< GLbyte >( floatNormalBuffer[i]*127.0 );
    }
#endif

    // invert UVs for OpenGL (textures are inverted otherwise - for example, see abdulla/klinok)
    GLfloat* texCoordBufferData = (GLfloat*) texCoordBuffer->getDataPointer();

    for ( float* tcy = texCoordBufferData + 1;
          tcy < texCoordBufferData + 2*vertexCount;
          tcy += 2 )
    {
        *tcy = 1.0f - *tcy;
    }

    // -- And now create meshes data --
    int unriggedBoneIndex = calCoreModel->getCoreSkeleton()->getVectorCoreBone().size();
    // we add empty bone in ModelData to handle unrigged vertices;
    
    for( int hardwareMeshId = 0; hardwareMeshId < calHardwareModel->getHardwareMeshCount(); hardwareMeshId++ )
    {
        calHardwareModel->selectHardwareMesh(hardwareMeshId);
        int faceCount = calHardwareModel->getFaceCount();

        if ( faceCount == 0 )
        {
            continue; // we ignore empty meshes
        }
        
        CalHardwareModel::CalHardwareMesh* hardwareMesh =
            &calHardwareModel->getVectorHardwareMesh()[ hardwareMeshId ];

        osg::ref_ptr< MeshData > m( new MeshData );
        
        m->name = calCoreModel->getCoreMesh( hardwareMesh->meshId )->getName();
        m->coreMaterial = hardwareMesh->pCoreMaterial;
        if ( m->coreMaterial == NULL )
        {
            CalCoreMesh*    coreMesh    = calCoreModel->getCoreMesh( hardwareMesh->meshId );
            CalCoreSubmesh* coreSubmesh = coreMesh->getCoreSubmesh( hardwareMesh->submeshId );
            // hardwareMesh->pCoreMaterial =
            //   coreModel->getCoreMaterial( coreSubmesh->getCoreMaterialThreadId() );
            char buf[ 1024 ];
            snprintf( buf, 1024,
                      "pCoreMaterial == NULL for mesh '%s' (mesh material id = %d), verify your mesh file data",
                      m->name.c_str(),
                      coreSubmesh->getCoreMaterialThreadId() );
            throw std::runtime_error( buf );
        }

        // -- Create index buffer --
        int indexesCount = faceCount * 3;
        int startIndex = calHardwareModel->getStartIndex();

        if ( indexesCount <= 0x100 )
        {
            m->indexBuffer = new osg::DrawElementsUByte( osg::PrimitiveSet::TRIANGLES, indexesCount );

            GLubyte* data = (GLubyte*)m->indexBuffer->getDataPointer();
            const CalIndex* i    = &indexBuffer[ startIndex ];
            const CalIndex* iEnd = &indexBuffer[ startIndex + indexesCount ];
            while ( i < iEnd )
            {
                *data++ = (GLubyte)*i++;
            }
        }
        else if ( indexesCount <= 0x10000 )
        {
            m->indexBuffer = new osg::DrawElementsUShort( osg::PrimitiveSet::TRIANGLES, indexesCount );

            GLushort* data = (GLushort*)m->indexBuffer->getDataPointer();
            const CalIndex* i    = &indexBuffer[ startIndex ];
            const CalIndex* iEnd = &indexBuffer[ startIndex + indexesCount ];
            while ( i < iEnd )
            {
                *data++ = (GLushort)*i++;
            }
        }
        else
        {
            m->indexBuffer = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, indexesCount );

            GLuint* data = (GLuint*)m->indexBuffer->getDataPointer();
            const CalIndex* i    = &indexBuffer[ startIndex ];
            const CalIndex* iEnd = &indexBuffer[ startIndex + indexesCount ];
            while ( i < iEnd )
            {
                *data++ = (GLuint)*i++;
            }
        }

        // -- Create other buffers --
        int vertexCount = calHardwareModel->getVertexCount();
        int baseVertexIndex = calHardwareModel->getBaseVertexIndex();

#define SUB_BUFFER( _type, _name )                                  \
        new _type( _name->begin() + baseVertexIndex,                \
                   _name->begin() + baseVertexIndex + vertexCount )
        
        m->vertexBuffer = SUB_BUFFER( VertexBuffer, vertexBuffer );
        m->weightBuffer = SUB_BUFFER( WeightBuffer, weightBuffer );
        m->matrixIndexBuffer = SUB_BUFFER( MatrixIndexBuffer, matrixIndexBuffer );
        m->normalBuffer = SUB_BUFFER( NormalBuffer, normalBuffer );
        m->texCoordBuffer = SUB_BUFFER( TexCoordBuffer, texCoordBuffer );

        // -- Parameters and buffers setup --
        m->boundingBox = calculateBoundingBox( m->vertexBuffer.get() );

        m->bonesIndices = hardwareMesh->m_vectorBonesIndices;

        checkRigidness( m.get(), unriggedBoneIndex );
        checkForEmptyTexCoord( m.get() );
        generateTangentAndHandednessBuffer( m.get(), &indexBuffer[ startIndex ] );

        meshes.push_back( m.get() );
    }
}
示例#5
0
bool CalHardwareModel::load(int baseVertexIndex, int startIndex,int maxBonesPerMesh)
{
  if(m_pVertexBuffer==NULL ||  m_pNormalBuffer ==NULL|| m_pWeightBuffer ==NULL || m_pMatrixIndexBuffer ==NULL)
  {
    CalError::setLastError(CalError::INVALID_HANDLE, __FILE__, __LINE__);
    return false;   
  }

  int mapId;
  for(mapId = 0; mapId < m_textureCoordNum; mapId++)
  {
    if(m_pTextureCoordBuffer[mapId]==NULL)
    {
      CalError::setLastError(CalError::INVALID_HANDLE, __FILE__, __LINE__);
      return false;         
    }  
  } 
  
  m_vectorVertexIndiceUsed.resize(50000);
  int vertexCount=baseVertexIndex;
  int faceIndexCount = startIndex;
        
        // unused.
  //CalCoreSkeleton * pCoreSkeleton = m_pCoreModel->getCoreSkeleton();
  //std::vector< CalCoreBone *>& vectorBone = pCoreSkeleton->getVectorCoreBone();

  // if unspecified, fill with all core mesh ids
  if(m_coreMeshIds.empty())
  {
    for(int coreMeshId = 0; coreMeshId < m_pCoreModel->getCoreMeshCount(); coreMeshId++)
      m_coreMeshIds.push_back(coreMeshId);
  }
    
  for(std::vector<int>::iterator meshIdIt = m_coreMeshIds.begin();meshIdIt != m_coreMeshIds.end(); meshIdIt++)
  {
    int meshId = *meshIdIt;
    CalCoreMesh *pCoreMesh = m_pCoreModel->getCoreMesh(meshId);
    int submeshCount= pCoreMesh->getCoreSubmeshCount();
    int submeshId;
    for(submeshId = 0 ;submeshId < submeshCount ; submeshId++)
    {     
      CalCoreSubmesh *pCoreSubmesh = pCoreMesh->getCoreSubmesh(submeshId);
      
      std::vector<CalCoreSubmesh::Vertex>& vectorVertex = pCoreSubmesh->getVectorVertex();
      std::vector<CalCoreSubmesh::Face>& vectorFace = pCoreSubmesh->getVectorFace();
                        // unused.
      //std::vector< std::vector<CalCoreSubmesh::TextureCoordinate> >& vectorTex = pCoreSubmesh->getVectorVectorTextureCoordinate();
      
      CalHardwareMesh hardwareMesh;

      hardwareMesh.meshId = meshId;
      hardwareMesh.submeshId = submeshId;
      
      hardwareMesh.baseVertexIndex=vertexCount;     
      hardwareMesh.startIndex=faceIndexCount;
      hardwareMesh.m_vectorBonesIndices.clear();          
      
      hardwareMesh.vertexCount=0;
      hardwareMesh.faceCount=0;     
      
      int startIndex=hardwareMesh.startIndex;
      
      int faceId;     
      for( faceId =0 ;faceId<pCoreSubmesh->getFaceCount();faceId++)
      {
        if(canAddFace(hardwareMesh,vectorFace[faceId],vectorVertex,maxBonesPerMesh))
        {
          m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3]=   addVertex(hardwareMesh,vectorFace[faceId].vertexId[0],pCoreSubmesh,maxBonesPerMesh);
          m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+1]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[1],pCoreSubmesh,maxBonesPerMesh);
          m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+2]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[2],pCoreSubmesh,maxBonesPerMesh);
          hardwareMesh.faceCount++;
        }
        else
        {
          vertexCount+=hardwareMesh.vertexCount;
          faceIndexCount+=hardwareMesh.faceCount*3;
          hardwareMesh.pCoreMaterial= m_pCoreModel->getCoreMaterial(pCoreSubmesh->getCoreMaterialThreadId());
          
          m_vectorHardwareMesh.push_back(hardwareMesh);
          
          hardwareMesh.baseVertexIndex=vertexCount;
          hardwareMesh.startIndex=faceIndexCount;
          
          hardwareMesh.m_vectorBonesIndices.clear();
          hardwareMesh.vertexCount=0; 
          hardwareMesh.faceCount=0;
          
          startIndex=hardwareMesh.startIndex;
          
          m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3]=   addVertex(hardwareMesh,vectorFace[faceId].vertexId[0],pCoreSubmesh,maxBonesPerMesh);
          m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+1]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[1],pCoreSubmesh,maxBonesPerMesh);
          m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+2]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[2],pCoreSubmesh,maxBonesPerMesh);
          hardwareMesh.faceCount++;         
        }
      }
      
      vertexCount+=hardwareMesh.vertexCount;
      faceIndexCount+=hardwareMesh.faceCount*3;
      hardwareMesh.pCoreMaterial= m_pCoreModel->getCoreMaterial(pCoreSubmesh->getCoreMaterialThreadId());
      
      m_vectorHardwareMesh.push_back(hardwareMesh);
      
    }
  }
  
    m_vectorVertexIndiceUsed.clear();


  m_totalFaceCount=0;
  m_totalVertexCount=0;

  for(size_t hardwareMeshId = 0; hardwareMeshId <  m_vectorHardwareMesh.size(); hardwareMeshId++)
  {
    m_totalFaceCount+=m_vectorHardwareMesh[hardwareMeshId].faceCount;
    m_totalVertexCount+=m_vectorHardwareMesh[hardwareMeshId].vertexCount;
  }

    
    return true;
}  
示例#6
0
void CalCoreBone::calculateBoundingBox(CalCoreModel * pCoreModel)
{
   int boneId =  m_pCoreSkeleton->getCoreBoneId(m_strName);
   bool bBoundsComputed=false;
   int planeId;
   
   CalQuaternion rot;
   rot=m_rotationBoneSpace;   
  
   rot.invert();
   
   CalVector dir = CalVector(1.0f,0.0f,0.0f);
   dir*=rot;
   m_boundingBox.plane[0].setNormal(dir);

   dir = CalVector(-1.0f,0.0f,0.0f);
   dir*=rot;
   m_boundingBox.plane[1].setNormal(dir);

   dir = CalVector(0.0f,1.0f,0.0f);
   dir*=rot;
   m_boundingBox.plane[2].setNormal(dir);

   dir = CalVector(0.0f,-1.0f,0.0f);
   dir*=rot;
   m_boundingBox.plane[3].setNormal(dir);

   dir = CalVector(0.0f,0.0f,1.0f);
   dir*=rot;
   m_boundingBox.plane[4].setNormal(dir);

   dir = CalVector(0.0f,0.0f,-1.0f);
   dir*=rot;
   m_boundingBox.plane[5].setNormal(dir);
   
   int meshId;
   for(meshId=0; meshId < pCoreModel->getCoreMeshCount(); ++meshId)
   {
       CalCoreMesh * pCoreMesh = pCoreModel->getCoreMesh(meshId);
	   
       int submeshId;
       for(submeshId=0;submeshId<pCoreMesh->getCoreSubmeshCount();submeshId++)
       {
		   CalCoreSubmesh *pCoreSubmesh = pCoreMesh->getCoreSubmesh(submeshId);
		   
		   if(pCoreSubmesh->getSpringCount()==0)
		   {
			   
			   std::vector<CalCoreSubmesh::Vertex>& vectorVertex =  pCoreSubmesh->getVectorVertex();
			   for(size_t vertexId=0;vertexId <vectorVertex.size(); ++vertexId)
			   {
				   for(size_t influenceId=0;influenceId<vectorVertex[vertexId].vectorInfluence.size();++influenceId)
				   {
					   if(vectorVertex[vertexId].vectorInfluence[influenceId].boneId == boneId && vectorVertex[vertexId].vectorInfluence[influenceId].weight > 0.5f)
					   {						   
						   for(planeId = 0; planeId < 6; ++planeId)
						   {
							   if(m_boundingBox.plane[planeId].eval(vectorVertex[vertexId].position) < 0.0f)
							   {
								   m_boundingBox.plane[planeId].setPosition(vectorVertex[vertexId].position);
								   m_boundingPosition[planeId]=vectorVertex[vertexId].position;
								   bBoundsComputed=true;
							   }
						   }
					   }
				   }
			   }	
		   }
	   }
   }

   // To handle bones with no vertices assigned 
   if(!bBoundsComputed) 
   { 
	   for(planeId = 0; planeId < 6; ++planeId) 
	   { 
		   m_boundingBox.plane[planeId].setPosition(m_translation); 
		   m_boundingPosition[planeId] = m_translation; 
	   } 
   } 
   
   m_boundingBoxPrecomputed = true;
}
示例#7
0
void CalCoreSkeleton::calculateBoundingBoxes(CalCoreModel *pCoreModel)
{
	size_t boneId;
	
	// First, find out whether all the bounding boxes have already been precomputed.
	// If so, we can bail out early.
	bool	alreadyComputed = true;
	for(boneId=0;boneId<m_vectorCoreBone.size();++boneId)
	{
		if (! m_vectorCoreBone[boneId]->isBoundingBoxPrecomputed())
		{
			alreadyComputed = false;
			break;
		}
	}
	if (alreadyComputed)
	{
		return;
	}
	
	// Initialize all bounding boxes empty.
	for(boneId=0;boneId<m_vectorCoreBone.size();++boneId)
	{
		m_vectorCoreBone[boneId]->initBoundingBox();
	}
	
	// Loop over all vertices updating bounding boxes.
	for(int meshId=0; meshId < pCoreModel->getCoreMeshCount(); ++meshId)
	{
		CalCoreMesh * pCoreMesh = pCoreModel->getCoreMesh(meshId);
		
		for(int submeshId=0;submeshId<pCoreMesh->getCoreSubmeshCount();submeshId++)
		{
			CalCoreSubmesh *pCoreSubmesh = pCoreMesh->getCoreSubmesh(submeshId);
			
			if(pCoreSubmesh->getSpringCount()==0)
			{
				std::vector<CalCoreSubmesh::Vertex>& vectorVertex =
					pCoreSubmesh->getVectorVertex();
				
				for(size_t vertexId=0;vertexId <vectorVertex.size(); ++vertexId)
				{
					for(size_t influenceId=0;
						influenceId < vectorVertex[vertexId].vectorInfluence.size();
						++influenceId)
					{
						if (vectorVertex[vertexId].vectorInfluence[influenceId].weight > 0.5f)
						{
							boneId = vectorVertex[vertexId].vectorInfluence[influenceId].boneId;
							
							m_vectorCoreBone[boneId]->updateBoundingBox(
								vectorVertex[vertexId].position );
							
							break;	// there can be at most one bone with majority influence
						}
					}
				}
			}
		}
	}

	// Mark bounding boxes as computed.
	for(boneId=0;boneId<m_vectorCoreBone.size();++boneId)
	{
		m_vectorCoreBone[boneId]->setBoundingBoxPrecomputed( true );
	}
}