/* PMDObject::updateRootBone: update root bone if assigned to a base bone */
void PMDObject::updateRootBone()
{
   btVector3 pos;
   btVector3 posAbs;
   PMDBone *b;
   btTransform tr;

   if (!m_baseBone) return;

   /* relative position */
   pos = m_offsetPos;
   /* if absolute flag is true, fix relative position from root bone */
   posAbs = m_offsetPos + m_origBasePos - m_baseBone->getTransform()->getOrigin();
   if (m_absPosFlag[0]) pos.setX(posAbs.x());
   if (m_absPosFlag[1]) pos.setY(posAbs.y());
   if (m_absPosFlag[2]) pos.setZ(posAbs.z());

   /* set root bone */
   b = m_pmd.getRootBone();
   b->setCurrentPosition(&pos);
   b->setCurrentRotation(&m_offsetRot);
   b->update();
   /* update transform for base position */
   tr = (*m_baseBone->getTransform()) * (*b->getTransform());
   b->setTransform(&tr);
}
/* MotionManager::startMotionSub: initialize a motion */
void MotionManager::startMotionSub(VMD * vmd, MotionPlayer * m)
{
   btVector3 offset;
   PMDBone *centerBone;
   btTransform tr;
   btVector3 pos;

   btVector3 centerPos;
   btVector3 rootOffset;

   /* initialize and setup motion controller */
   m->mc.setup(m_pmd, vmd);

   /* reset values */
   m->mc.reset();

   /* base motion does treat the bones with single motion frame at 0th frame as the same as normal bones */
   m->mc.setIgnoreSingleMotion(m->ignoreStatic);

   /* reset work area */
   m->vmd = vmd;
   m->active = true;
   m->endingBoneBlend = 0.0f;
   m->endingFaceBlend = 0.0f;
   /* when motion is changed, speed acceleration is turned off */
   m->accelerationStatusFlag = ACCELERATION_STATUS_CONSTANT;

   /* set model offset */
   if (m->enableSmooth) {
      offset.setZero();
      if (m->mc.hasCenter() && m->enableRePos) {
         /* when the started motion has center motion, the center position of the model will be moved to the current position */
         /* The current global position of the center bone will become the new offset of the root bone, and the local center position will be reset */
         centerBone = m_pmd->getCenterBone();
         /* calculate relative origin of center bone from model root bone */
         tr = m_pmd->getRootBone()->getTransform()->inverse();
         pos = tr * centerBone->getTransform()->getOrigin();
         /* get the translation vector */
         centerBone->getOriginPosition(&centerPos);
         offset = pos - centerPos;
         offset.setY(0.0f); /* Y axis should be set to zero to place model on ground */
         /* save the current pos/rot for smooth motion changing, resetting center location */
         m->mc.setOverrideFirst(&offset);
         /* add the offset to the root bone */
         m_pmd->getRootBone()->getOffset(&rootOffset);
         rootOffset += offset;
         m_pmd->getRootBone()->setOffset(&rootOffset);
         m_pmd->getRootBone()->update();
      } else {
         /* save the current pos/rot for smooth motion changing */
         m->mc.setOverrideFirst(NULL) ;
      }
   }
}