//----------------------------------------------------------------------------- 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)); } }
bool bulletSimulation::SetFrame(int in_Frame) { // see if we have to reset the world if(in_Frame <= 0) { ResetWorld(); return true; } // now let's skip if we already have that frame or the interval>5 - we don't want bullet to compute the whole sequence if you move to the last frame. if(mLastFrame >= in_Frame || (in_Frame-mLastFrame)>5) { return false; } mChangingFrame = true; // if this is not the first frame, let's update all rbd! for(btRigidBodyIt it = mRigidBodies.begin();it!=mRigidBodies.end();it++) { // skip corrupt bodies if(it->second->body==NULL) continue; if(it->first.secondary != -1) continue; btCollisionShape * shape = (btBoxShape*)it->second->body->getCollisionShape(); if(shape != NULL) { // refresh the kine ptr it->second->kine.Set(it->second->kine.GetAsText()); XSI::MATH::CTransformation xf = XSI::KinematicState(it->second->kine).GetTransform();//(float)in_Frame); shape->setLocalScaling(btVector3(xf.GetSclX(),xf.GetSclY(),xf.GetSclZ())); // skip non valid ops if(!it->second->op.IsValid()) continue; // update the mass an inertia it->second->mass = XSI::CustomOperator(it->second->op).GetParameterValue(L"mass"); btVector3 inertia(0,0,0); if(it->second->mass > 0.0f) shape->calculateLocalInertia(it->second->mass,inertia); it->second->body->setMassProps(it->second->mass,inertia); // if we are passive rigid body, let's update the transform if(it->second->mass == 0.0f) { btDefaultMotionState * motionState = (btDefaultMotionState*)it->second->body->getMotionState(); if(motionState != NULL) { btTransform transform; transform.setOrigin(btVector3(xf.GetPosX(),xf.GetPosY(),xf.GetPosZ())); XSI::MATH::CQuaternion q = xf.GetRotationQuaternion(); transform.setRotation(btQuaternion(q.GetX(),q.GetY(),q.GetZ(),q.GetW())); it->second->body->proceedToTransform( transform ); } } } } // step to the given frame if(in_Frame > 0) { while(in_Frame > mLastFrame) { float dt=(1.0f/mFps)/(float)mSubSteps; //Step every subframe for (int i=0;i<mSubSteps;i++) mDynamicsWorld->stepSimulation(dt,0,1.0f/mFps); mLastFrame++; } } mLastFrame = in_Frame; mChangingFrame = false; return true; }