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

📄 loader.cpp

📁 Cal3D实现虚拟角色 Cal3D实现虚拟角色
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  // set the duration in the core animation instance  pCoreAnimation->setDuration(duration);  // read the number of tracks  int trackCount;  if(!dataSrc.readInteger(trackCount) || (trackCount <= 0))  {    CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__);    return 0;  }  // load all core bones  int trackId;  for(trackId = 0; trackId < trackCount; ++trackId)  {    // load the core track    CalCoreTrack *pCoreTrack;    pCoreTrack = loadCoreTrack(dataSrc, skel, duration);    if(pCoreTrack == 0)    {      CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__);      return 0;    }    // add the core track to the core animation instance    pCoreAnimation->addCoreTrack(pCoreTrack);  }  return pCoreAnimation;} /*****************************************************************************//** Loads a core material instance.  *  * This function loads a core material instance from a data source.  *  * @param dataSrc The data source to load the core material instance from.  *  * @return One of the following values:  *         \li a pointer to the core material  *         \li \b 0 if an error happened  *****************************************************************************/CalCoreMaterialPtr CalLoader::loadCoreMaterial(CalDataSource& dataSrc){  // check if this is a valid file  char magic[4];  if(!dataSrc.readBytes(&magic[0], 4) || (memcmp(&magic[0], Cal::MATERIAL_FILE_MAGIC, 4) != 0))  {    CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__);    return 0;  }  // check if the version is compatible with the library  int version;  if(!dataSrc.readInteger(version) || (version < Cal::EARLIEST_COMPATIBLE_FILE_VERSION) || (version > Cal::CURRENT_FILE_VERSION))  {    CalError::setLastError(CalError::INCOMPATIBLE_FILE_VERSION, __FILE__, __LINE__);    return 0;  }  // allocate a new core material instance  CalCoreMaterialPtr pCoreMaterial = new CalCoreMaterial();  if(!pCoreMaterial)  {    CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__);    return 0;  }  // get the ambient color of the core material  CalCoreMaterial::Color ambientColor;  dataSrc.readBytes(&ambientColor, sizeof(ambientColor));  // get the diffuse color of the core material  CalCoreMaterial::Color diffuseColor;  dataSrc.readBytes(&diffuseColor, sizeof(diffuseColor));  // get the specular color of the core material  CalCoreMaterial::Color specularColor;  dataSrc.readBytes(&specularColor, sizeof(specularColor));  // get the shininess factor of the core material  float shininess;  dataSrc.readFloat(shininess);  // check if an error happened  if(!dataSrc.ok())  {    dataSrc.setError();    return 0;  }  // set the colors and the shininess  pCoreMaterial->setAmbientColor(ambientColor);  pCoreMaterial->setDiffuseColor(diffuseColor);  pCoreMaterial->setSpecularColor(specularColor);  pCoreMaterial->setShininess(shininess);  // read the number of maps  int mapCount;  if(!dataSrc.readInteger(mapCount) || (mapCount < 0))  {    CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__);    return 0;  }  // reserve memory for all the material data  if(!pCoreMaterial->reserve(mapCount))  {    CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__);    return 0;  }  // load all maps  int mapId;  for(mapId = 0; mapId < mapCount; ++mapId)  {    CalCoreMaterial::Map map;    // read the filename of the map    std::string strName;    dataSrc.readString(map.strFilename);    // initialize the user data    map.userData = 0;    // check if an error happened    if(!dataSrc.ok())    {      CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__);      return 0;    }    // set map in the core material instance    pCoreMaterial->setMap(mapId, map);  }  return pCoreMaterial;} /*****************************************************************************//** Loads a core mesh instance.  *  * This function loads a core mesh instance from a data source.  *  * @param dataSrc The data source to load the core mesh instance from.  *  * @return One of the following values:  *         \li a pointer to the core mesh  *         \li \b 0 if an error happened  *****************************************************************************/CalCoreMeshPtr CalLoader::loadCoreMesh(CalDataSource& dataSrc){  // check if this is a valid file  char magic[4];  if(!dataSrc.readBytes(&magic[0], 4) || (memcmp(&magic[0], Cal::MESH_FILE_MAGIC, 4) != 0))  {    CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__);    return 0;  }  // check if the version is compatible with the library  int version;  if(!dataSrc.readInteger(version) || (version < Cal::EARLIEST_COMPATIBLE_FILE_VERSION) || (version > Cal::CURRENT_FILE_VERSION))  {    CalError::setLastError(CalError::INCOMPATIBLE_FILE_VERSION, __FILE__, __LINE__);    return 0;  }  // get the number of submeshes  int submeshCount;  if(!dataSrc.readInteger(submeshCount))  {    CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__);    return 0;  }  // allocate a new core mesh instance  CalCoreMeshPtr pCoreMesh = new CalCoreMesh();  if(!pCoreMesh)  {    CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__);    return 0;  }  // load all core submeshes  for(int submeshId = 0; submeshId < submeshCount; ++submeshId)  {    // load the core submesh    CalCoreSubmesh *pCoreSubmesh = loadCoreSubmesh(dataSrc);    if(pCoreSubmesh == 0)    {      return 0;    }    // add the core submesh to the core mesh instance    pCoreMesh->addCoreSubmesh(pCoreSubmesh);  }  return pCoreMesh;} /*****************************************************************************//** Loads a core skeleton instance.  *  * This function loads a core skeleton instance from a data source.  *  * @param dataSrc The data source 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::loadCoreSkeleton(CalDataSource& dataSrc){  // check if this is a valid file  char magic[4];  if(!dataSrc.readBytes(&magic[0], 4) || (memcmp(&magic[0], Cal::SKELETON_FILE_MAGIC, 4) != 0))  {    CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__);    return 0;  }  // check if the version is compatible with the library  int version;  if(!dataSrc.readInteger(version) || (version < Cal::EARLIEST_COMPATIBLE_FILE_VERSION) || (version > Cal::CURRENT_FILE_VERSION))  {    CalError::setLastError(CalError::INCOMPATIBLE_FILE_VERSION, __FILE__, __LINE__);    return 0;  }  // read the number of bones  int boneCount;  if(!dataSrc.readInteger(boneCount) || (boneCount <= 0))  {    CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__);    return 0;  }  // allocate a new core skeleton instance  CalCoreSkeletonPtr pCoreSkeleton = new CalCoreSkeleton();  if(!pCoreSkeleton)  {    CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__);    return 0;  }  // load all core bones  for(int boneId = 0; boneId < boneCount; ++boneId)  {    // load the core bone    CalCoreBone *pCoreBone = loadCoreBones(dataSrc);    if(pCoreBone == 0)    {      return 0;    }    // set the core skeleton of the core bone instance    pCoreBone->setCoreSkeleton(pCoreSkeleton.get());    // add the core bone to the core skeleton instance    pCoreSkeleton->addCoreBone(pCoreBone);    // add a core skeleton mapping of the bone's name for quick reference later    pCoreSkeleton->mapCoreBoneName(boneId, pCoreBone->getName());  }  // calculate state of the core skeleton  pCoreSkeleton->calculateState();  return pCoreSkeleton;} /*****************************************************************************//** Loads a core bone instance.  *  * This function loads a core bone instance from a data source.  *  * @param dataSrc The data source to load the core bone instance from.  *  * @return One of the following values:  *         \li a pointer to the core bone  *         \li \b 0 if an error happened  *****************************************************************************/CalCoreBone *CalLoader::loadCoreBones(CalDataSource& dataSrc){  if(!dataSrc.ok())  {    dataSrc.setError();    return 0;  }  // read the name of the bone  std::string strName;  dataSrc.readString(strName);  // get the translation of the bone  float tx, ty, tz;  dataSrc.readFloat(tx);  dataSrc.readFloat(ty);  dataSrc.readFloat(tz);  // get the rotation of the bone  float rx, ry, rz, rw;  dataSrc.readFloat(rx);  dataSrc.readFloat(ry);  dataSrc.readFloat(rz);  dataSrc.readFloat(rw);  // get the bone space translation of the bone  float txBoneSpace, tyBoneSpace, tzBoneSpace;  dataSrc.readFloat(txBoneSpace);  dataSrc.readFloat(tyBoneSpace);  dataSrc.readFloat(tzBoneSpace);  // get the bone space rotation of the bone  float rxBoneSpace, ryBoneSpace, rzBoneSpace, rwBoneSpace;  dataSrc.readFloat(rxBoneSpace);  dataSrc.readFloat(ryBoneSpace);  dataSrc.readFloat(rzBoneSpace);  dataSrc.readFloat(rwBoneSpace);  // get the parent bone id  int parentId;  dataSrc.readInteger(parentId);  CalQuaternion rot(rx,ry,rz,rw);  CalQuaternion rotbs(rxBoneSpace, ryBoneSpace, rzBoneSpace, rwBoneSpace);  CalVector trans(tx,ty,tz);  if (loadingMode & LOADER_ROTATE_X_AXIS)  {    if (parentId == -1) // only root bone necessary    {      // Root bone must have quaternion rotated      CalQuaternion x_axis_90(0.7071067811f,0.0f,0.0f,0.7071067811f);      rot *= x_axis_90;      // Root bone must have translation rotated also      trans *= x_axis_90;    }  }    // check if an error happened  if(!dataSrc.ok())  {    dataSrc.setError();    return 0;  }  // allocate a new core bone instance  CalCoreBone *pCoreBone;  pCoreBone = new CalCoreBone(strName);  if(pCoreBone == 0)  {    CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__);    return 0;  }  // set the parent of the bone  pCoreBone->setParentId(parentId);  // set all attributes of the bone  pCoreBone->setTranslation(trans);  pCoreBone->setRotation(rot);  pCoreBone->setTranslationBoneSpace(CalVector(txBoneSpace, tyBoneSpace, tzBoneSpace));  pCoreBone->setRotationBoneSpace(rotbs);  // read the number of children  int childCount;  if(!dataSrc.readInteger(childCount) || (childCount < 0))  {    delete pCoreBone;    CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__);    return 0;  }  // load all children ids  for(; childCount > 0; childCount--)  {    int childId;    if(!dataSrc.readInteger(childId) || (childId < 0))    {      delete pCoreBone;      CalError::setLastError(CalError::INVALID_FILE_FORMAT, __FILE__, __LINE__);      return 0;    }    pCoreBone->addChildId(childId);  }  return pCoreBone;} /*****************************************************************************//** Loads a core keyframe instance.  *  * This function loads a core keyframe instance from a data source.  *  * @param dataSrc The data source to load the core keyframe instance from.  *  * @return One of the following values:  *         \li a pointer to the core keyframe  *         \li \b 0 if an error happened  *****************************************************************************/CalCoreKeyframe* CalLoader::loadCoreKeyframe(CalDataSource& dataSrc){  if(!dataSrc.ok())  {    dataSrc.setError();    return 0;  }  // get the time of the keyframe  float time;  dataSrc.readFloat(time);  // get the translation of the bone  float tx, ty, tz;  dataSrc.readFloat(tx);  dataSrc.readFloat(ty);  dataSrc.readFloat(tz);  // get the rotation of the bone  float rx, ry, rz, rw;  dataSrc.readFloat(rx);  dataSrc.readFloat(ry);  dataSrc.readFloat(rz);  dataSrc.readFloat(rw);  // check if an error happened  if(!dataSrc.ok())  {    dataSrc.setError();    return false;  }

⌨️ 快捷键说明

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