⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loader.cpp

📁 Cal3D实现虚拟角色 Cal3D实现虚拟角色
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  // allocate a new core keyframe instance  CalCoreKeyframe *pCoreKeyframe = new CalCoreKeyframe();  if(pCoreKeyframe == 0)  {    CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__);    return 0;  }  // create the core keyframe instance  if(!pCoreKeyframe->create())  {    delete pCoreKeyframe;    return 0;  }  // set all attributes of the keyframe  pCoreKeyframe->setTime(time);  pCoreKeyframe->setTranslation(CalVector(tx, ty, tz));  pCoreKeyframe->setRotation(CalQuaternion(rx, ry, rz, rw));  return pCoreKeyframe;} /*****************************************************************************//** Loads a core submesh instance.  *  * This function loads a core submesh instance from a data source.  *  * @param dataSrc The data source to load the core submesh instance from.  *  * @return One of the following values:  *         \li a pointer to the core submesh  *         \li \b 0 if an error happened  *****************************************************************************/CalCoreSubmesh *CalLoader::loadCoreSubmesh(CalDataSource& dataSrc){	if(!dataSrc.ok())	{		dataSrc.setError();		return 0;	}	// get the material thread id of the submesh	int coreMaterialThreadId;	dataSrc.readInteger(coreMaterialThreadId);	// get the number of vertices, faces, level-of-details and springs	int vertexCount;	dataSrc.readInteger(vertexCount);	int faceCount;	dataSrc.readInteger(faceCount);	int lodCount;	dataSrc.readInteger(lodCount);	int springCount;	dataSrc.readInteger(springCount);	// get the number of texture coordinates per vertex	int textureCoordinateCount;	dataSrc.readInteger(textureCoordinateCount);	// check if an error happened	if(!dataSrc.ok())	{		dataSrc.setError();		return 0;	}	// allocate a new core submesh instance	CalCoreSubmesh *pCoreSubmesh;	pCoreSubmesh = new CalCoreSubmesh();	if(pCoreSubmesh == 0)	{		CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__);		return 0;	}	// set the LOD step count	pCoreSubmesh->setLodCount(lodCount);	// set the core material id	pCoreSubmesh->setCoreMaterialThreadId(coreMaterialThreadId);	// reserve memory for all the submesh data	if(!pCoreSubmesh->reserve(vertexCount, textureCoordinateCount, faceCount, springCount))	{		CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__);		delete pCoreSubmesh;		return 0;	}	// load the tangent space enable flags.	int textureCoordinateId;	for (textureCoordinateId = 0; textureCoordinateId < textureCoordinateCount; textureCoordinateId++)	{		pCoreSubmesh->enableTangents(textureCoordinateId, false);	}	// load all vertices and their influences	int vertexId;	for(vertexId = 0; vertexId < vertexCount; ++vertexId)	{		CalCoreSubmesh::Vertex vertex;		// load data of the vertex		dataSrc.readFloat(vertex.position.x);		dataSrc.readFloat(vertex.position.y);		dataSrc.readFloat(vertex.position.z);		dataSrc.readFloat(vertex.normal.x);		dataSrc.readFloat(vertex.normal.y);		dataSrc.readFloat(vertex.normal.z);		dataSrc.readInteger(vertex.collapseId);		dataSrc.readInteger(vertex.faceCollapseCount);		// check if an error happened		if(!dataSrc.ok())		{			dataSrc.setError();			delete pCoreSubmesh;			return 0;		}		// load all texture coordinates of the vertex		int textureCoordinateId;		for(textureCoordinateId = 0; textureCoordinateId < textureCoordinateCount; ++textureCoordinateId)		{			CalCoreSubmesh::TextureCoordinate textureCoordinate;			// load data of the influence			dataSrc.readFloat(textureCoordinate.u);			dataSrc.readFloat(textureCoordinate.v);			if (loadingMode & LOADER_INVERT_V_COORD)			{				textureCoordinate.v = 1.0f - textureCoordinate.v;			}			// check if an error happened			if(!dataSrc.ok())			{				dataSrc.setError();				delete pCoreSubmesh;				return 0;			}			// set texture coordinate in the core submesh instance			pCoreSubmesh->setTextureCoordinate(vertexId, textureCoordinateId, textureCoordinate);		}		// get the number of influences		int influenceCount;		if(!dataSrc.readInteger(influenceCount) || (influenceCount < 0))		{			dataSrc.setError();			delete pCoreSubmesh;			return 0;		}		// reserve memory for the influences in the vertex		vertex.vectorInfluence.reserve(influenceCount);		vertex.vectorInfluence.resize(influenceCount);		// load all influences of the vertex		int influenceId;		for(influenceId = 0; influenceId < influenceCount; ++influenceId)		{			// load data of the influence			dataSrc.readInteger(vertex.vectorInfluence[influenceId].boneId),			dataSrc.readFloat(vertex.vectorInfluence[influenceId].weight);			// check if an error happened			if(!dataSrc.ok())			{				dataSrc.setError();				delete pCoreSubmesh;				return 0;			}		}		// set vertex in the core submesh instance		pCoreSubmesh->setVertex(vertexId, vertex);		// load the physical property of the vertex if there are springs in the core submesh		if(springCount > 0)		{			CalCoreSubmesh::PhysicalProperty physicalProperty;			// load data of the physical property			dataSrc.readFloat(physicalProperty.weight);			// check if an error happened			if(!dataSrc.ok())			{				dataSrc.setError();				delete pCoreSubmesh;				return 0;			}			// set the physical property in the core submesh instance			pCoreSubmesh->setPhysicalProperty(vertexId, physicalProperty);		}	}	// load all springs	int springId;	for(springId = 0; springId < springCount; ++springId)	{		CalCoreSubmesh::Spring spring;		// load data of the spring		dataSrc.readInteger(spring.vertexId[0]);		dataSrc.readInteger(spring.vertexId[1]);		dataSrc.readFloat(spring.springCoefficient);		dataSrc.readFloat(spring.idleLength);		// check if an error happened		if(!dataSrc.ok())		{			dataSrc.setError();			delete pCoreSubmesh;			return 0;		}		// set spring in the core submesh instance		pCoreSubmesh->setSpring(springId, spring);	}	// load all faces	int faceId;	int justOnce = 0;	bool flipModel = false;	for(faceId = 0; faceId < faceCount; ++faceId)	{		CalCoreSubmesh::Face face;		// load data of the face		int tmp[4];		dataSrc.readInteger(tmp[0]);		dataSrc.readInteger(tmp[1]);		dataSrc.readInteger(tmp[2]);		if(sizeof(CalIndex)==2)		{			if(tmp[0]>65535 || tmp[1]>65535 || tmp[2]>65535)			{      				CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__);				delete pCoreSubmesh;				return 0;			}		}		face.vertexId[0]=tmp[0];		face.vertexId[1]=tmp[1];		face.vertexId[2]=tmp[2];		// check if an error happened		if(!dataSrc.ok())		{			dataSrc.setError();			delete pCoreSubmesh;			return 0;		}		// check if left-handed coord system is used by the object		// can be done only once since the object has one system for all faces		if (justOnce==0)		{			// get vertexes of first face			std::vector<CalCoreSubmesh::Vertex>& vectorVertex = pCoreSubmesh->getVectorVertex();			CalCoreSubmesh::Vertex& v1 = vectorVertex[tmp[0]];			CalCoreSubmesh::Vertex& v2 = vectorVertex[tmp[1]];			CalCoreSubmesh::Vertex& v3 = vectorVertex[tmp[2]];			CalVector point1 = CalVector(v1.position.x, v1.position.y, v1.position.z);			CalVector point2 = CalVector(v2.position.x, v2.position.y, v2.position.z);			CalVector point3 = CalVector(v3.position.x, v3.position.y, v3.position.z);			// gets vectors (v1-v2) and (v3-v2)			CalVector vect1 = point1 - point2;			CalVector vect2 = point3 - point2;			// calculates normal of face			CalVector cross = vect1 % vect2;			CalVector faceNormal = cross / cross.length();			// compare the calculated normal with the normal of a vertex			CalVector maxNorm = v1.normal;			// if the two vectors point to the same direction then the poly needs flipping			// so if the dot product > 0 it needs flipping			if (faceNormal*maxNorm>0)				flipModel = true;			// flip the winding order if the loading flags request it			if (loadingMode & LOADER_FLIP_WINDING)				flipModel = !flipModel;			justOnce = 1;		}		// flip if needed		if (flipModel) 		{			tmp[3] = face.vertexId[1];			face.vertexId[1]=face.vertexId[2];			face.vertexId[2]=tmp[3];		}		// set face in the core submesh instance		pCoreSubmesh->setFace(faceId, face);	}	return pCoreSubmesh;} /*****************************************************************************//** Loads a core track instance.  *  * This function loads a core track instance from a data source.  *  * @param dataSrc The data source to load the core track instance from.  *  * @return One of the following values:  *         \li a pointer to the core track  *         \li \b 0 if an error happened  *****************************************************************************/CalCoreTrack *CalLoader::loadCoreTrack(CalDataSource& dataSrc, CalCoreSkeleton *skel, float duration){  if(!dataSrc.ok())  {    dataSrc.setError();    return 0;  }  // read the bone id  int coreBoneId;  if(!dataSrc.readInteger(coreBoneId) || (coreBoneId < 0))  {    CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__);    return 0;  }  // allocate a new core track instance  CalCoreTrack *pCoreTrack;  pCoreTrack = new CalCoreTrack();  if(pCoreTrack == 0)  {    CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__);    return 0;  }  // create the core track instance  if(!pCoreTrack->create())  {    delete pCoreTrack;    return 0;  }  // link the core track to the appropriate core bone instance  pCoreTrack->setCoreBoneId(coreBoneId);  // read the number of keyframes  int keyframeCount;  if(!dataSrc.readInteger(keyframeCount) || (keyframeCount <= 0))  {    CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__);    return 0;  }  // load all core keyframes  int keyframeId;  for(keyframeId = 0; keyframeId < keyframeCount; ++keyframeId)  {    // load the core keyframe    CalCoreKeyframe *pCoreKeyframe = loadCoreKeyframe(dataSrc);    if(pCoreKeyframe == 0)    {      pCoreTrack->destroy();      delete pCoreTrack;      return 0;    }    if(loadingMode & LOADER_ROTATE_X_AXIS)    {      // Check for anim rotation      if (skel && skel->getCoreBone(coreBoneId)->getParentId() == -1)  // root bone      {        // rotate root bone quaternion        CalQuaternion rot = pCoreKeyframe->getRotation();        CalQuaternion x_axis_90(0.7071067811f,0.0f,0.0f,0.7071067811f);        rot *= x_axis_90;        pCoreKeyframe->setRotation(rot);        // rotate root bone displacement        CalVector vec = pCoreKeyframe->getTranslation();				vec *= x_axis_90;        pCoreKeyframe->setTranslation(vec);      }    }        // add the core keyframe to the core track instance    pCoreTrack->addCoreKeyframe(pCoreKeyframe);  }  return pCoreTrack;} /*****************************************************************************//** Loads a core skeleton instance from a XML file.  *  * This function loads a core skeleton instance from a XML file.  *  * @param strFilename The name of the file to load the core skeleton instance  *                    from.  *  * @return One of the following values:  *         \li a pointer to the core skeleton  *         \li \b 0 if an error happened  *****************************************************************************/CalCoreSkeletonPtr CalLoader::loadXmlCoreSkeleton(const std::string& strFilename){	std::stringstream str;	TiXmlDocument doc(strFilename);	if(!doc.LoadFile())	{		CalError::setLastError(CalError::FILE_NOT_FOUND, __FILE__, __LINE__, strFilename);		return 0;	}	TiXmlNode* node;	TiXmlElement*skeleton = doc.FirstChildElement();	if(!skeleton)	{		CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__, strFilename);		return 0;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -