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

📄 bone.cpp

📁 Cal3D实现虚拟角色 Cal3D实现虚拟角色
💻 CPP
字号:
//****************************************************************************//// bone.cpp                                                                   //// Copyright (C) 2001, 2002 Bruno 'Beosil' Heidelberger                       ////****************************************************************************//// This library is free software; you can redistribute it and/or modify it    //// under the terms of the GNU Lesser General Public License as published by   //// the Free Software Foundation; either version 2.1 of the License, or (at    //// your option) any later version.                                            ////****************************************************************************//#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "cal3d/error.h"#include "cal3d/bone.h"#include "cal3d/coremodel.h"#include "cal3d/coremesh.h"#include "cal3d/coresubmesh.h"#include "cal3d/corebone.h"#include "cal3d/skeleton.h"#include "cal3d/coreskeleton.h"CalBone::CalBone(CalCoreBone* coreBone)  : m_pSkeleton(0){  assert(coreBone);  m_pCoreBone = coreBone;  clearState();} /*****************************************************************************//** Interpolates the current state to another state.  *  * This function interpolates the current state (relative translation and  * rotation) of the bone instance to another state of a given weight.  *  * @param weight The blending weight.  * @param translation The relative translation to be interpolated to.  * @param rotation The relative rotation to be interpolated to.  *****************************************************************************/void CalBone::blendState(float weight, const CalVector& translation, const CalQuaternion& rotation){  if(m_accumulatedWeightAbsolute == 0.0f)  {    // it is the first state, so we can just copy it into the bone state    m_translationAbsolute = translation;    m_rotationAbsolute = rotation;    m_accumulatedWeightAbsolute = weight;  }  else  {    // it is not the first state, so blend all attributes    float factor;    factor = weight / (m_accumulatedWeightAbsolute + weight);    m_translationAbsolute.blend(factor, translation);    m_rotationAbsolute.blend(factor, rotation);    m_accumulatedWeightAbsolute += weight;  }} /*****************************************************************************//** Calculates the current state.  *  * This function calculates the current state (absolute translation and  * rotation, as well as the bone space transformation) of the bone instance  * and all its children.  *****************************************************************************/void CalBone::calculateState(){  // check if the bone was not touched by any active animation  if(m_accumulatedWeight == 0.0f)  {    // set the bone to the initial skeleton state    m_translation = m_pCoreBone->getTranslation();    m_rotation = m_pCoreBone->getRotation();  }  // get parent bone id  int parentId;  parentId = m_pCoreBone->getParentId();  if(parentId == -1)  {    // no parent, this means absolute state == relative state    m_translationAbsolute = m_translation;    m_rotationAbsolute = m_rotation;  }  else  {    // get the parent bone    CalBone *pParent;    pParent = m_pSkeleton->getBone(parentId);    // transform relative state with the absolute state of the parent    m_translationAbsolute = m_translation;    m_translationAbsolute *= pParent->getRotationAbsolute();    m_translationAbsolute += pParent->getTranslationAbsolute();    m_rotationAbsolute = m_rotation;    m_rotationAbsolute *= pParent->getRotationAbsolute();  }  // calculate the bone space transformation  m_translationBoneSpace = m_pCoreBone->getTranslationBoneSpace();  m_translationBoneSpace *= m_rotationAbsolute;  m_translationBoneSpace += m_translationAbsolute;  m_rotationBoneSpace = m_pCoreBone->getRotationBoneSpace();  m_rotationBoneSpace *= m_rotationAbsolute;  // Generate the vertex transform.  If I ever add support for bone-scaling  // to Cal3D, this step will become significantly more complex.  m_transformMatrix = m_rotationBoneSpace;  // calculate all child bones  std::list<int>::iterator iteratorChildId;  for(iteratorChildId = m_pCoreBone->getListChildId().begin(); iteratorChildId != m_pCoreBone->getListChildId().end(); ++iteratorChildId)  {    m_pSkeleton->getBone(*iteratorChildId)->calculateState();  }} /*****************************************************************************//** Clears the current state.  *  * This function clears the current state (absolute translation and rotation)  * of the bone instance and all its children.  *****************************************************************************/void CalBone::clearState(){  m_accumulatedWeight = 0.0f;  m_accumulatedWeightAbsolute = 0.0f;} /*****************************************************************************//** Provides access to the core bone.  *  * This function returns the core bone on which this bone instance is based on.  *  * @return One of the following values:  *         \li a pointer to the core bone  *         \li \b 0 if an error happend  *****************************************************************************/CalCoreBone *CalBone::getCoreBone(){  return m_pCoreBone;} /*****************************************************************************//** Resets the bone to its core state  *  * This function changes the state of the bone to its default non-animated  * position and orientation. Child bones are unaffected and may be animated  * independently.   *****************************************************************************/void CalBone::setCoreState(){   // set the bone to the initial skeleton state   m_translation = m_pCoreBone->getTranslation();   m_rotation = m_pCoreBone->getRotation();   // set the appropriate weights   m_accumulatedWeightAbsolute = 1.0f;   m_accumulatedWeight = 1.0f ;   calculateState() ;} /*****************************************************************************//** Resets the bone and children to core states  *  * This function changes the state of the bone to its default non-animated  * position and orientation. All child bones are also set in this manner.  *****************************************************************************/void CalBone::setCoreStateRecursive(){  // set the bone to the initial skeleton state  m_translation = m_pCoreBone->getTranslation();  m_rotation = m_pCoreBone->getRotation();  // set the appropriate weights  m_accumulatedWeightAbsolute = 1.0f;  m_accumulatedWeight = 1.0f ;  // set core state for all child bones  std::list<int>::iterator iteratorChildId;  for(iteratorChildId = m_pCoreBone->getListChildId().begin(); iteratorChildId != m_pCoreBone->getListChildId().end(); ++iteratorChildId)  {    m_pSkeleton->getBone(*iteratorChildId)->setCoreStateRecursive();  }  calculateState() ;} /*****************************************************************************//** Sets the current rotation.  *  * This function sets the current relative rotation of the bone instance.  * Caveat: For this change to appear, calculateState() must be called   * afterwards.  *****************************************************************************/void CalBone::setRotation(const CalQuaternion& rotation){  m_rotation = rotation;  m_accumulatedWeightAbsolute = 1.0f;  m_accumulatedWeight = 1.0f ;} /*****************************************************************************//** Returns the current rotation.  *  * This function returns the current relative rotation of the bone instance.  *  * @return The relative rotation to the parent as quaternion.  *****************************************************************************/const CalQuaternion& CalBone::getRotation(){  return m_rotation;} /*****************************************************************************//** Returns the current absolute rotation.  *  * This function returns the current absolute rotation of the bone instance.  *  * @return The absolute rotation to the parent as quaternion.  *****************************************************************************/const CalQuaternion& CalBone::getRotationAbsolute(){  return m_rotationAbsolute;} /*****************************************************************************//** Returns the current bone space rotation.  *  * This function returns the current rotation to bring a point into the bone  * instance space.  *  * @return The rotation to bring a point into bone space.  *****************************************************************************/const CalQuaternion& CalBone::getRotationBoneSpace(){  return m_rotationBoneSpace;} /*****************************************************************************//** Sets the current translation.  *  * This function sets the current relative translation of the bone instance.  * Caveat: For this change to appear, calculateState() must be called   * afterwards.  *****************************************************************************/void CalBone::setTranslation(const CalVector& translation){  m_translation = translation;  m_accumulatedWeightAbsolute = 1.0f;  m_accumulatedWeight = 1.0f ;} /*****************************************************************************//** Returns the current translation.  *  * This function returns the current relative translation of the bone instance.  *  * @return The relative translation to the parent as quaternion.  *****************************************************************************/const CalVector& CalBone::getTranslation(){  return m_translation;} /*****************************************************************************//** Returns the current absolute translation.  *  * This function returns the current absolute translation of the bone instance.  *  * @return The absolute translation to the parent as quaternion.  *****************************************************************************/const CalVector& CalBone::getTranslationAbsolute(){  return m_translationAbsolute;} /*****************************************************************************//** Returns the current bone space translation.  *  * This function returns the current translation to bring a point into the  *bone instance space.  *  * @return The translation to bring a point into bone space.  *****************************************************************************/const CalVector& CalBone::getTranslationBoneSpace(){  return m_translationBoneSpace;} /*****************************************************************************//** Returns the current bone space translation.  *  * This function returns the current translation to bring a point into the  *bone instance space.  *  * @return The translation to bring a point into bone space.  *****************************************************************************/const CalMatrix& CalBone::getTransformMatrix(){  return m_transformMatrix;} /*****************************************************************************//** Locks the current state.  *  * This function locks the current state (absolute translation and rotation)  * of the bone instance and all its children.  *****************************************************************************/void CalBone::lockState(){  // clamp accumulated weight  if(m_accumulatedWeightAbsolute > 1.0f - m_accumulatedWeight)  {    m_accumulatedWeightAbsolute = 1.0f - m_accumulatedWeight;  }  if(m_accumulatedWeightAbsolute > 0.0f)  {    if(m_accumulatedWeight == 0.0f)    {      // it is the first state, so we can just copy it into the bone state      m_translation = m_translationAbsolute;      m_rotation = m_rotationAbsolute;      m_accumulatedWeight = m_accumulatedWeightAbsolute;    }    else    {      // it is not the first state, so blend all attributes      float factor;      factor = m_accumulatedWeightAbsolute / (m_accumulatedWeight + m_accumulatedWeightAbsolute);      m_translation.blend(factor, m_translationAbsolute);      m_rotation.blend(factor, m_rotationAbsolute);      m_accumulatedWeight += m_accumulatedWeightAbsolute;    }    m_accumulatedWeightAbsolute = 0.0f;  }} /*****************************************************************************//** Sets the skeleton.  *  * This function sets the skeleton to which the bone instance is attached to.  *  * @param pSkeleton The skeleton to which the bone instance should be  *                  attached to.  *****************************************************************************/void CalBone::setSkeleton(CalSkeleton *pSkeleton){  m_pSkeleton = pSkeleton;} /*****************************************************************************//** Calculates the bounding box.  *  * This function Calculates the bounding box of the bone instance.  *  *****************************************************************************/void CalBone::calculateBoundingBox(){   if(!getCoreBone()->isBoundingBoxPrecomputed())	   return;   CalVector dir = CalVector(1.0f,0.0f,0.0f);   dir*=getTransformMatrix();   m_boundingBox.plane[0].setNormal(dir);   dir = CalVector(-1.0f,0.0f,0.0f);   dir*=getTransformMatrix();   m_boundingBox.plane[1].setNormal(dir);   dir = CalVector(0.0f,1.0f,0.0f);   dir*=getTransformMatrix();   m_boundingBox.plane[2].setNormal(dir);   dir = CalVector(0.0f,-1.0f,0.0f);   dir*=getTransformMatrix();   m_boundingBox.plane[3].setNormal(dir);   dir = CalVector(0.0f,0.0f,1.0f);   dir*=getTransformMatrix();   m_boundingBox.plane[4].setNormal(dir);   dir = CalVector(0.0f,0.0f,-1.0f);   dir*=getTransformMatrix();   m_boundingBox.plane[5].setNormal(dir);      int i;      for(i=0;i< 6; i++)   {       CalVector position;       getCoreBone()->getBoundingData(i,position);             position*=getTransformMatrix();       position+=getTranslationBoneSpace();       int planeId;       for(planeId = 0; planeId < 6; ++planeId)       {          if(m_boundingBox.plane[planeId].eval(position) < 0.0f)          {             m_boundingBox.plane[planeId].setPosition(position);          }       }          }} /*****************************************************************************//** Returns the current bounding box.  *  * This function returns the current bounding box of the bone instance.  *  * @return bounding box.  *****************************************************************************/CalBoundingBox & CalBone::getBoundingBox(){   return m_boundingBox;}//****************************************************************************//

⌨️ 快捷键说明

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