//----------------------------------------------------------------------------- void XsiSkeletonExporter::sampleAllBones(DeformerMap& deformers, std::vector<NodeAnimationTrack*> deformerTracks, double frame, Real time, float fps, AxisAlignedBox& AABBPadding) { CValueArray args; CValue dummy; args.Resize(2); // set the playcontrol args[0] = L"PlayControl.Key"; args[1] = frame; mXsiApp.ExecuteCommand(L"SetValue", args, dummy); args[0] = L"PlayControl.Current"; mXsiApp.ExecuteCommand(L"SetValue", args, dummy); // Refresh mXsiApp.ExecuteCommand(L"Refresh", CValueArray(), dummy); // Sample all bones for (DeformerMap::iterator di = deformers.begin(); di != deformers.end(); ++di) { DeformerEntry* deformer = di->second; NodeAnimationTrack* track = deformerTracks[deformer->boneID]; double initposx, initposy, initposz; deformer->initialXform.GetTranslationValues(initposx, initposy, initposz); double initrotx, initroty, initrotz; deformer->initialXform.GetRotation().GetXYZAngles(initrotx, initroty, initrotz); double initsclx, initscly, initsclz; deformer->initialXform.GetScalingValues(initsclx, initscly, initsclz); XSI::MATH::CMatrix4 invTrans = deformer->initialXform.GetMatrix4(); invTrans.InvertInPlace(); XSI::MATH::CTransformation transformation; if (deformer->pBone->getParent() == 0) { // Based on global transformation = deformer->obj.GetKinematics().GetGlobal().GetTransform(); } else { // Based on local transformation = deformer->obj.GetKinematics().GetLocal().GetTransform(); } double posx, posy, posz; transformation.GetTranslationValues(posx, posy, posz); double sclx, scly, sclz; transformation.GetScalingValues(sclx, scly, sclz); // Make relative to initial XSI::MATH::CMatrix4 transformationMatrix = transformation.GetMatrix4(); transformationMatrix.MulInPlace(invTrans); transformation.SetMatrix4(transformationMatrix); // create keyframe TransformKeyFrame* kf = track->createNodeKeyFrame(time); // not sure why inverted transform doesn't work for position, but it doesn't // I thought XSI used same transform order as OGRE kf->setTranslate(Vector3(posx - initposx, posy - initposy, posz - initposz)); kf->setRotation(XSItoOgre(transformation.GetRotationQuaternion())); kf->setScale(Vector3(sclx / initsclx, scly / initscly, sclz / initsclz)); // Derive AABB of bone positions, for padding animated mesh AABB XSI::MATH::CVector3 bonePos = deformer->obj.GetKinematics().GetGlobal().GetTransform().GetTranslation(); AABBPadding.merge(XSItoOgre(bonePos)); } }