Esempio n. 1
0
void IKTree::reset(int frame)
{
  MT_Quaternion q;
  BVHNode *n;

  for (int i=0; i<numBones; i++) {
    bone[i].pos = origin;
    bone[i].lRot = identity;
    bone[i].gRot = identity;
    n = bone[i].node;
    Rotation rot=n->frameData(frame).rotation();
    Position pos=n->frameData(frame).position();

    for (int k=0; k<n->numChannels; k++) {  // rotate each axis in order
      q = identity;
      switch (n->channelType[k]) {
      case BVH_XROT:
        q.setRotation(xAxis, rot.x * M_PI / 180);
      break;
      case BVH_YROT:
        q.setRotation(yAxis, rot.y * M_PI / 180);
      break;
      case BVH_ZROT:
        q.setRotation(zAxis, rot.z * M_PI / 180);
      break;
      case BVH_XPOS: bone[i].pos[0] = pos.x; break;
      case BVH_YPOS: bone[i].pos[1] = pos.y; break;
      case BVH_ZPOS: bone[i].pos[2] = pos.z; break;
      }
      bone[i].lRot = q * bone[i].lRot;
    }
/*
    for (int k=0; k<3; k++) {  // rotate each axis in order
      rad = n->frame[frame][k] * M_PI / 180;
      q = identity;
      switch (n->channelType[k]) {
      case BVH_XROT: q.setRotation(xAxis, rad); break;
      case BVH_YROT: q.setRotation(yAxis, rad); break;
      case BVH_ZROT: q.setRotation(zAxis, rad); break;
      case BVH_XPOS: bone[i].pos[0] = n->frame[frame][k]; break;
      case BVH_YPOS: bone[i].pos[1] = n->frame[frame][k]; break;
      case BVH_ZPOS: bone[i].pos[2] = n->frame[frame][k]; break;
      }
      bone[i].lRot = q * bone[i].lRot;
    }
*/
  }
  updateBones(0);
}
Esempio n. 2
0
void IKTree::solve(int frame)
{
  double x, y, z;
  reset(frame);

  IKEffectorList effList;

  for (int i=0; i<20; i++) {
    effList.num = 0;
    solveJoint(frame, 0, effList);
  }

  for (int i=0; i<numBones-1; i++) {
    BVHNode *n = bone[i].node;
    Rotation rot=n->frameData(frame).rotation();
    toEuler(bone[i].lRot, n->channelOrder, x, y, z);

    for (int j=0; j<n->numChannels; j++) {  // rotate each axis in order
      switch (n->channelType[j]) {
        case BVH_XROT: n->ikRot.x = x - rot.x; break;
        case BVH_YROT: n->ikRot.y = y - rot.y; break;
        case BVH_ZROT: n->ikRot.z = z - rot.z; break;
        default: break;
      }
    }

/*
    for (int j=0; j<3; j++) {  // rotate each axis in order
      switch (n->channelType[j]) {
        case BVH_XROT: n->ikRot[j] = x - n->frame[frame][j]; break;
        case BVH_YROT: n->ikRot[j] = y - n->frame[frame][j]; break;
        case BVH_ZROT: n->ikRot[j] = z - n->frame[frame][j]; break;
        default: break;
      }
    } */
  }
  display = 1;
  updateBones(0);
  display = 0;
}
Esempio n. 3
0
void Blender::EvaluateRelativeLimbWeights(QList<TimelineTrail*>* trails, int trailsCount)       //TODO: into below method?
{
  int minPosIndex = 999999999;
  int maxPosIndex = -1;
  TrailItem** currentItems = new TrailItem*[trailsCount];

  //Find first and last occupied time-line position. And initialize currentItems with first non-shadows
  for(int i=0; i<trailsCount; i++)
  {
    TrailItem* firstItem = trails->at(i)->firstItem();
    if(firstItem==NULL)
    {
      currentItems[i] = NULL;
      continue;
    }

    //Shadow items don't matter much because the nearest/furthest item is always non-shadow
    if(firstItem->beginIndex() < minPosIndex)
      minPosIndex = firstItem->beginIndex();

    TrailItem* lastItem = trails->at(i)->lastItem();
    if(lastItem->endIndex() > maxPosIndex)
      maxPosIndex = trails->at(i)->lastItem()->endIndex();

    while(firstItem->isShadow())
      firstItem = firstItem->nextItem();
    currentItems[i] = firstItem;
  }
  if(maxPosIndex == -1)                       //Time-line is empty
    return;

  int curPosIndex = minPosIndex;
  //Position pseudo-node is not included, but it's OK as it can't be highlighted
  QStringList boneNames = BVH::getValidNodeNames();
  while(curPosIndex<=maxPosIndex)
  {
    foreach(QString bName, boneNames)
    {
      int sumWeight = 0;
      int weightsUsed = 0;
      bool emptyPosition = true;

      //Temporary helper structure. Value is array of 2 integers: frame index inside
      //respective animation and its frame weight
      QMap<BVHNode*, QVector<int> >* usedData = new QMap<BVHNode*, QVector<int> >();

      for(int i=0; i<trailsCount; i++)
      {
        TrailItem* item = currentItems[i];

        if(item == NULL)                                 //No more items on i-th trail
          continue;
        if(item->beginIndex() > curPosIndex)             //We're before first item of this trail
          continue;

        if(item->endIndex() < curPosIndex)               //Move to next item
        {
          currentItems[i] = item->nextItem();
          item = currentItems[i];
        }
        if(item == NULL || item->isShadow())             //Still here?
          continue;
        else
          emptyPosition = false;

        if(item->beginIndex() <= curPosIndex && item->endIndex() >= curPosIndex)
        {
          int frameIndex = curPosIndex - item->beginIndex();
          int frameWeight = item->getWeight(frameIndex);

          if(!item->getAnimation()->bones()->contains(bName))
            Announcer::Exception(NULL, "Exception: can't evaluate relative weight for limb " +bName);


//          BVHNode* limb = item->getAnimation()->bones()->value(bName);      NOT WORKING. REALLY NEED TO KNOW WHY
          //desperate DEBUG
          BVHNode* limb = item->getAnimation()->getNodeByName(bName);

          QVector<int> tempData;
          tempData << frameIndex << frameWeight;
          usedData->insert(limb, tempData);
          sumWeight += frameWeight * limb->frameData(frameIndex).weight();
          weightsUsed++;
        }
//        else Announcer::Exception(NULL, "Lame programmer exception :(");    //DEBUG
      }

      if(emptyPosition)                         //There were no valid item at this position
        break;                                  //so jump to the next one



      QMapIterator<BVHNode*, QVector<int> > iter(*usedData);
      while(iter.hasNext())
      {
        iter.next();
        BVHNode* bone = iter.key();
        QVector<int> tempData = iter.value();
        int frame = tempData[0];
        int frameW = tempData[1];

        if(sumWeight==0)                        //Little trick if weight of current limb was 0 on all trails
          bone->setKeyFrameRelWeight(frame, 1.0 / (double)weightsUsed);
        else
        {
          int limbW = bone->frameData(frame).weight();
          double relWei = (double)(frameW*limbW) / (double)sumWeight;
          bone->setKeyFrameRelWeight(frame, relWei);
        }
      }

      delete usedData;
    }
    curPosIndex++;
  }