Пример #1
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;
}
			U1 Resource::CreateHardwareBuff( MeshHDBuffer* pOutBuff,CalCoreMesh* pInMesh ){
				std::vector<ABuff>	vertexData;
				std::vector<UInt>								indexData;
	
				SInt	iMeshCount	=	pInMesh->getCoreSubmeshCount();
				SInt	iVertexCount	=	0;
				SInt	iIndexCount		=	0;
				//首先计算顶点数 和 索引数
				for(SInt i=0;i<iMeshCount;i++){
					CalCoreSubmesh*	pSubMesh	=	pInMesh->getCoreSubmesh(i);
					iVertexCount	+=	pSubMesh->getVectorVertex().size();
					iIndexCount		+=	pSubMesh->getFaceCount()*3;
				}
				if(	iVertexCount	==	0	||
					iIndexCount		==	0)
				{
					return	false;
				}
				//分配空间
				vertexData.resize(iVertexCount);
				indexData.resize(iIndexCount);
	
				SInt	iV	=	0;
				SInt	iI	=	0;
	
				
				for(SInt i=0;i<iMeshCount;i++){
					CalCoreSubmesh*	pSubMesh							=	pInMesh->getCoreSubmesh(i);
					//计算切线
					pSubMesh->enableTangents(0,true);
	
					std::vector<CalCoreSubmesh::Vertex>&							lstVector	=	pSubMesh->getVectorVertex();
					std::vector<std::vector<CalCoreSubmesh::TangentSpace> >&		lstTangent	=	pSubMesh->getVectorVectorTangentSpace();
					std::vector<std::vector<CalCoreSubmesh::TextureCoordinate> >&	lstTexcoord	=	pSubMesh->getVectorVectorTextureCoordinate();
					std::vector<CalCoreSubmesh::Face>&								lstFace		=	pSubMesh->getVectorFace();
					
					SInt iFaceCount	=	lstFace.size();
					//索引缓冲
					for(SInt	j=0;j<iFaceCount;j++){
						indexData[iI]	=	lstFace[j].vertexId[0]	+	iV;
						indexData[iI+1]	=	lstFace[j].vertexId[1]	+	iV;
						indexData[iI+2]	=	lstFace[j].vertexId[2]	+	iV;
						iI	+=	3;
					}
					
					//顶点缓冲数据
					for(SInt j=0;j<iVertexCount;j++){
						CalCoreSubmesh::Vertex&				ver		=	lstVector[j];
						CalCoreSubmesh::TangentSpace		tang	=	lstTangent[0][j];
						CalCoreSubmesh::TextureCoordinate	uv		=	lstTexcoord[0][j];
		
						//位置
						vertexData[iV].Position		=	Float3(ver.position.x,ver.position.y,ver.position.z);


						SInt	iBoneCount	=	ver.vectorInfluence.size();
						for(SInt	k=0;k<4;k++){
							if(k<iBoneCount){
 								vertexData[iV].BoneWeight[k]	=	ver.vectorInfluence[k].weight*255.0f;
								//如果只传递自己需要的矩阵 
								//骨骼索引变成0~n
 								vertexData[iV].BoneIndex[k]		=	ver.vectorInfluence[k].boneId;
							}else{
								vertexData[iV].BoneWeight[k]	=	0;
								vertexData[iV].BoneIndex[k]		=	0;

							}

						}

						//法线
						vertexData[iV].Normal		=	Float3(ver.normal.x,ver.normal.y,ver.normal.z);
						//UV
						vertexData[iV].UV.x		=	uv.u;
						vertexData[iV].UV.y		=	uv.v;
						//切线
						vertexData[iV].Tangent.x		=	tang.tangent.x;
						vertexData[iV].Tangent.y		=	tang.tangent.y;
						vertexData[iV].Tangent.z		=	tang.tangent.z;
	
	
	
						iV++;
					}
					AString	strName	=	m_strProductName	+	pInMesh->getName();
					Render::Vertex::IDeclare::Info	dInfo;
					dInfo.SetPNTT_Animation();
 					pOutBuff->pVertexDeclare	=	Render::System::GetSingleton()->CreateProduct<Render::Vertex::IDeclare>("PNTTANIM",&dInfo);
					Render::Buffer::Info		vInfo;
					vInfo.SetVertexBuffer(iVertexCount,52);
					vInfo.InitData			=	&vertexData[0];
					pOutBuff->pVertexBuff		=	Render::System::GetSingleton()->CreateProduct<Render::Buffer>(strName+"VB",&vInfo);

					vInfo.SetIndexBuffer32(iFaceCount*3);
					vInfo.InitData			=	&indexData[0];
					pOutBuff->pIndexBuff		=	Render::System::GetSingleton()->CreateProduct<Render::Buffer>(strName+"IB",&vInfo);

				}
				return	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
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;
}  
Пример #5
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;
}
Пример #6
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 );
	}
}