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); }
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; }
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++; }