MStatus HRBFSkinCluster::skinDQ(MMatrixArray& transforms, int numTransforms, MArrayDataHandle& weightListHandle, MItGeometry& iter) { MStatus returnStatus; // compute dual quaternions. we're storing them as a parallel array. std::vector<MQuaternion> tQuaternions(numTransforms); // translation quaterions std::vector<MQuaternion> rQuaternions(numTransforms); // rotation quaternions for (int i = 0; i < numTransforms; i++) { rQuaternions.at(i) = getRotationQuaternion(transforms[i]); rQuaternions.at(i).normalizeIt(); tQuaternions.at(i) = getTranslationQuaternion(transforms[i], rQuaternions.at(i)); #if DEBUG_PRINTS std::cout << "rota quaternion " << i << " is: " << rQuaternions.at(i) << std::endl; std::cout << "tran quaternion " << i << " is: " << tQuaternions.at(i) << std::endl; #endif } MQuaternion rBlend; // blended rotation quaternions MQuaternion tBlend; // blended translation quaternions MQuaternion scaleMe; // Maya's quaternion scaling is in-place double weight; // Iterate through each point in the geometry. // for (; !iter.isDone(); iter.next()) { MPoint pt = iter.position(); MPoint skinned; rBlend = MQuaternion(); // reset tBlend = MQuaternion(); // reset rBlend[3] = 0.0; tBlend[3] = 0.0; // get the weights for this point MArrayDataHandle weightsHandle = weightListHandle.inputValue().child(weights); // compute the skinning for (int i = 0; i<numTransforms; ++i) { if (MS::kSuccess == weightsHandle.jumpToElement(i)) { weight = weightsHandle.inputValue().asDouble(); scaleMe = rQuaternions.at(i); rBlend = rBlend + scaleMe.scaleIt(weight); scaleMe = tQuaternions.at(i); tBlend = tBlend + scaleMe.scaleIt(weight); } } MMatrix dqMatrix = makeDQMatrix(rBlend.normalizeIt(), tBlend); skinned = pt * dqMatrix; // Set the final position. iter.setPosition(skinned); // advance the weight list handle weightListHandle.next(); } return returnStatus; }