//-----------------------------------------------------------------------------
	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));



		}

	}
Пример #2
0
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;
}