Beispiel #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;
			}
Beispiel #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 );
                }
            }
        }
    }
Beispiel #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() );
    }
}
Beispiel #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;
}  
Beispiel #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;
}
Beispiel #7
0
bool CExporter::ExportMesh(const std::string& strFilename)
{
  // check if a valid interface is set
  if(m_pInterface == 0)
  {
    SetLastError("Invalid handle.", __FILE__, __LINE__);
    return false;
  }

  // build a mesh candidate
  CMeshCandidate meshCandidate;

  // build a skeleton candidate
  CSkeletonCandidate skeletonCandidate;

  // show export wizard sheet
  CMeshExportSheet sheet("Cal3D Mesh Export", m_pInterface->GetMainWnd());
  sheet.SetSkeletonCandidate(&skeletonCandidate);
  sheet.SetMeshCandidate(&meshCandidate);
  sheet.SetWizardMode();
  if(sheet.DoModal() != ID_WIZFINISH) return true;

  // create the core mesh instance
  CalCoreMeshPtr coreMesh = new CalCoreMesh;

  // get the submesh candidate vector
  std::vector<CSubmeshCandidate *>& vectorSubmeshCandidate = meshCandidate.GetVectorSubmeshCandidate();

  // start the progress info
  m_pInterface->StartProgressInfo("Exporting to mesh file...");

  for(size_t submeshCandidateId = 0; submeshCandidateId < vectorSubmeshCandidate.size(); submeshCandidateId++)
  {
    // update the progress info
    m_pInterface->SetProgressInfo(int(100.0f * (float)submeshCandidateId / (float)vectorSubmeshCandidate.size()));

    // get the submesh candidate
    CSubmeshCandidate *pSubmeshCandidate = vectorSubmeshCandidate[submeshCandidateId];

    // get the face vector
    std::vector<CSubmeshCandidate::Face>& vectorFace = pSubmeshCandidate->GetVectorFace();

    // check if the submesh actually contains faces
    if(vectorFace.size() > 0)
    {
      // allocate new core submesh instance
      CalCoreSubmesh *pCoreSubmesh = new CalCoreSubmesh();
      if(pCoreSubmesh == 0)
      {
        SetLastError("Memory allocation failed.", __FILE__, __LINE__);
        m_pInterface->StopProgressInfo();
        return false;
      }

      // set the core material id
      pCoreSubmesh->setCoreMaterialThreadId(pSubmeshCandidate->GetMaterialThreadId());

      // get the vertex candidate vector
      std::vector<CVertexCandidate *>& vectorVertexCandidate = pSubmeshCandidate->GetVectorVertexCandidate();

      // get the spring vector
      std::vector<CSubmeshCandidate::Spring>& vectorSpring = pSubmeshCandidate->GetVectorSpring();

      // reserve memory for all the submesh data
      if(!pCoreSubmesh->reserve(vectorVertexCandidate.size(), pSubmeshCandidate->GetMapCount(), vectorFace.size(), vectorSpring.size()))
      {
        SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__);
        delete pCoreSubmesh;
        m_pInterface->StopProgressInfo();
        return false;
      }

      for(size_t vertexCandidateId = 0; vertexCandidateId < vectorVertexCandidate.size(); vertexCandidateId++)
      {
        // get the vertex candidate
        CVertexCandidate *pVertexCandidate = vectorVertexCandidate[vertexCandidateId];

        CalCoreSubmesh::Vertex vertex;
        pVertexCandidate->GetPosition(vertex.position);
        pVertexCandidate->GetNormal(vertex.normal);
        vertex.collapseId = pVertexCandidate->GetCollapseId();
        vertex.faceCollapseCount = pVertexCandidate->GetFaceCollapseCount();

        // get the texture coordinate vector
        std::vector<CVertexCandidate::TextureCoordinate>& vectorTextureCoordinate = pVertexCandidate->GetVectorTextureCoordinate();

        // set all texture coordinates
        for(size_t textureCoordinateId = 0; textureCoordinateId < vectorTextureCoordinate.size(); textureCoordinateId++)
        {
          CalCoreSubmesh::TextureCoordinate textureCoordinate;
          textureCoordinate.u = vectorTextureCoordinate[textureCoordinateId].u;
          textureCoordinate.v = vectorTextureCoordinate[textureCoordinateId].v;

          // set texture coordinate
          pCoreSubmesh->setTextureCoordinate(pVertexCandidate->GetLodId(), textureCoordinateId, textureCoordinate);
        }

        // get the influence vector
        std::vector<CVertexCandidate::Influence>& vectorInfluence = pVertexCandidate->GetVectorInfluence();

        // reserve memory for the influences in the vertex
        vertex.vectorInfluence.reserve(vectorInfluence.size());
        vertex.vectorInfluence.resize(vectorInfluence.size());

        // set all influences
        for(size_t influenceId = 0; influenceId < vectorInfluence.size(); influenceId++)
        {
          vertex.vectorInfluence[influenceId].boneId = vectorInfluence[influenceId].boneId;
          vertex.vectorInfluence[influenceId].weight = vectorInfluence[influenceId].weight;
        }

        // set vertex in the core submesh instance
        pCoreSubmesh->setVertex(pVertexCandidate->GetLodId(), vertex);

        // set the physical property if there is a spring system
        if(vectorSpring.size() > 0)
        {
          // get the physical property vector
          CVertexCandidate::PhysicalProperty physicalPropertyCandidate;
          pVertexCandidate->GetPhysicalProperty(physicalPropertyCandidate);

          CalCoreSubmesh::PhysicalProperty physicalProperty;
          physicalProperty.weight = physicalPropertyCandidate.weight;

          // set the physical property in the core submesh instance
          pCoreSubmesh->setPhysicalProperty(vertexCandidateId, physicalProperty);

        }
      }

      for(size_t faceId = 0; faceId < vectorFace.size(); faceId++)
      {
        CalCoreSubmesh::Face face;

        // set the vertex ids
        face.vertexId[0] = vectorFace[faceId].vertexLodId[0];
        face.vertexId[1] = vectorFace[faceId].vertexLodId[1];
        face.vertexId[2] = vectorFace[faceId].vertexLodId[2];

        // set face in the core submesh instance
        pCoreSubmesh->setFace(vectorFace[faceId].lodId, face);
      }

      for(size_t springId = 0; springId < vectorSpring.size(); springId++)
      {
        CalCoreSubmesh::Spring spring;

        // set the vertex ids
        spring.vertexId[0] = vectorSpring[springId].vertexId[0];
        spring.vertexId[1] = vectorSpring[springId].vertexId[1];
        spring.springCoefficient = vectorSpring[springId].springCoefficient;
        spring.idleLength = vectorSpring[springId].idleLength;

        // set face in the core submesh instance
        pCoreSubmesh->setSpring(springId, spring);
      }

      // set the LOD step count
      pCoreSubmesh->setLodCount(pSubmeshCandidate->GetLodCount());

      // add the core submesh to the core mesh instance
      coreMesh->addCoreSubmesh(pCoreSubmesh);
    }
  }

  // stop the progress info
  m_pInterface->StopProgressInfo();

  // save core mesh to the file
  if(!CalSaver::saveCoreMesh(strFilename, coreMesh.get()))
  {
    SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__);
    return false;
  }

  return true;
}
Beispiel #8
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 );
	}
}