TEST(DcdCollisionTest, RigidRigidCollisionTest)
{
	auto sphere1 = std::make_shared<Blocks::SphereElement>("Sphere1");
	auto sphere2 = std::make_shared<Blocks::SphereElement>("Sphere2");
	sphere2->setPose(Math::makeRigidTransform(Math::Quaterniond::Identity(), Vector3d(0.0, 0.0, 0.5)));

	auto runtime = std::make_shared<Framework::Runtime>();
	auto scene = runtime->getScene();
	scene->addSceneElement(sphere1);
	scene->addSceneElement(sphere2);

	std::vector<std::shared_ptr<Physics::Representation>> physicsRepresentations;
	physicsRepresentations.push_back(sphere1->getComponents<Physics::Representation>()[0]);
	physicsRepresentations.push_back(sphere2->getComponents<Physics::Representation>()[0]);

	auto sphere1Collision = sphere1->getComponents<Collision::Representation>()[0];
	auto sphere2Collision = sphere2->getComponents<Collision::Representation>()[0];
	sphere1Collision->update(0.0);
	sphere2Collision->update(0.0);
	std::vector<std::shared_ptr<Collision::Representation>> collisionRepresentations;
	collisionRepresentations.push_back(sphere1Collision);
	collisionRepresentations.push_back(sphere2Collision);

	auto prepareState = std::make_shared<PrepareCollisionPairs>(false);
	auto stateTmp = std::make_shared<PhysicsManagerState>();
	stateTmp->setRepresentations(physicsRepresentations);
	stateTmp->setCollisionRepresentations(collisionRepresentations);
	auto state = prepareState->update(0.0, stateTmp); // This step prepares the collision pairs
	ASSERT_EQ(1u, state->getCollisionPairs().size());

	auto dcdCollision = std::make_shared<DcdCollision>(false);
	std::shared_ptr<PhysicsManagerState> newState = dcdCollision->update(1.0, state);
	EXPECT_TRUE(newState->getCollisionPairs().at(0)->hasContacts());
}
示例#2
0
void SkeletalCreature::finishInit() {
	Agent::finishInit();

	processGenes();
	skeletonInit();
	setPose(0);
}
示例#3
0
 void Skeleton::setPose(const vector<double>& state, bool bCalcTrans, bool bCalcDeriv) {
     VectorXd x(state.size());
     for (unsigned int i = 0; i < state.size(); i++) {
         x(i) = state[i];
     }
     setPose(x, bCalcTrans, bCalcDeriv);
 }
示例#4
0
// Set and publish pose.
void Publisher::publishStateAsCallback(
    const okvis::Time & t, const okvis::kinematics::Transformation & T_WS)
{
  setTime(t);
  setPose(T_WS);  // TODO: provide setters for this hack
  publishPose();
}
示例#5
0
void StaticEntity::setCubeCoordinate(const CoordI& cc)
{
	cube_coordinate_ = cc;
	Vec3f pos = Properties::WorldToPosition(cube_coordinate_);
	setPose(pos);
	Vec3f center_pos = Properties::WorldToPositionCenter(cube_coordinate_);
	setCenterPosition(center_pos);
}
示例#6
0
void Object::setPoseLWH(Pose pose, Point bounding_box_lwh)
{
  bounding_box_lwh_ = bounding_box_lwh;
  scale_.x = bounding_box_lwh_.x;
  scale_.y = bounding_box_lwh_.y;
  scale_.z = bounding_box_lwh_.z;

  setPose(pose);
}
示例#7
0
void SkeletalCreature::setPoseGene(unsigned int poseno) {
	std::map<unsigned int, creaturePoseGene *>::iterator i = posegenes.find(poseno);
	if (i == posegenes.end()) return; // TODO: is there a better behaviour here?

	creaturePoseGene *g = i->second;
	assert(g->poseno == poseno);
	gaitgene = 0;
	walking = false; // TODO: doesn't belong here, does it? really the idea of a 'walking' bool is horrid
	setPose(g->getPoseString());
}
void 
MeshPose::eventReceived(const std::string &sender, const std::string &eventType, curitiba::event_::IEventData *evt)
{
	if(eventType=="NEXT_POSE") {
		m_ActivePose++;
		if (m_ActivePose >= m_vOffsets.size())
			m_ActivePose = 0;
		setPose(m_ActivePose);
	}
}
TEST_F(OsgSkeletonRepresentationRenderTests, WithNeutralPoseTest)
{
	auto graphics = std::make_shared<SurgSim::Graphics::OsgSkeletonRepresentation>("Skeleton");
	graphics->loadModel("OsgSkeletonRepresentationRenderTests/rigged_cylinder.osgt");
	graphics->setSkinningShaderFileName("Shaders/skinning.vert");
	graphics->setNeutralBonePose("Bone",
		makeRigidTransform(makeRotationQuaternion(M_PI_4, Vector3d(1.0, 1.0, 1.0)), Vector3d::Zero()));

	auto sceneElement = std::make_shared<SurgSim::Framework::BasicSceneElement>("Rigged Cylinder");
	sceneElement->addComponent(graphics);
	scene->addSceneElement(sceneElement);

	viewElement->setPose(SurgSim::Math::makeRigidTransform(
		Vector3d(-0.3, 0.3, -0.3),
		Vector3d(0.0, 0.0, 0.0),
		Vector3d(0.0, 0.0, 1.0)));

	runtime->start();
	boost::this_thread::sleep(boost::posix_time::milliseconds(2000));

	std::pair<RigidTransform3d, RigidTransform3d> rootTransform;
	rootTransform.first =
		makeRigidTransform(makeRotationQuaternion(0.0, Vector3d(1.0, 1.0, 1.0)), Vector3d::Zero());
	rootTransform.second =
		makeRigidTransform(makeRotationQuaternion(0.0, Vector3d(1.0, 1.0, 1.0)), Vector3d::Zero());

	std::pair<RigidTransform3d, RigidTransform3d> boneTransform;
	boneTransform.first =
		makeRigidTransform(makeRotationQuaternion(0.0, Vector3d(1.0, 0.0, 0.0)), Vector3d::Zero());
	boneTransform.second =
		makeRigidTransform(makeRotationQuaternion(0.0, Vector3d(1.0, 0.0, 0.0)), Vector3d(0.0, 4.0, 0.0));

	int numSteps = 1000;

	for (int i = 0; i < numSteps; ++i)
	{
		double t = static_cast<double>(i) / numSteps;

		RigidTransform3d pose = interpolate(rootTransform, t);
		sceneElement->setPose(pose);

		pose = interpolate(boneTransform, t / 3.0);
		graphics->setBonePose("Bone", RigidTransform3d::Identity());
		graphics->setBonePose("Bone_001", pose);
		graphics->setBonePose("Bone_002", pose);
		graphics->setBonePose("Bone_003", pose);

		/// The total number of steps should complete in 5 seconds
		boost::this_thread::sleep(boost::posix_time::milliseconds(5000 / numSteps));
	}

	runtime->stop();
}
		void rosSpin() {					
			
			double dt;
			
			Eigen::Vector3d t(0.0, 0.0, 0.0);
			Eigen::Vector3d t_new(0.0, 0.0, 0.0);
			Eigen::Vector3d t_vel(0.0, 0.0, 0.0);
			Eigen::Vector3d t_imu(0.0, 0.0, 0.0);
			Eigen::Vector3d t_arm(-0.19, 0.0, 0.02);
			Eigen::Quaterniond q_imu;
			
			ros::Rate rate(15);	
			
			ros::Time time_prev, time_now;
			
			time_prev = ros::Time::now();

			while(ros::ok()) {	
				
				ros::spinOnce();
				
				time_now = ros::Time::now();			
				dt = (time_now - time_prev).toSec();
				time_prev = time_now;		
				
				// Compute Rotation
				
				q_imu = w_imu.getQuaternionForAngularChange(dt);
								
				q = q * q_imu;
								
				// Compute Translation		
				
				t_imu = v_wheel.getRotationArm()*v_wheel.getTranslation() - q_imu.toRotationMatrix()*t_arm + t_arm;
				
				t_new = t + q.toRotationMatrix()*t_imu;
				
				t_vel = (t_new - t)/dt;
				
				t = t_new;
								
				setPose(t, q, t_new);		
				
				pub_data.publish(odometry);
						
				rate.sleep();
			}			
			
		};
示例#11
0
void CViewerContainer::showRangeScan(CNode* node)
{
	CRangeScanNode* obsNode = dynamic_cast<CRangeScanNode*>(node);
	ASSERT_(obsNode);

	auto obj = mrpt::make_aligned_shared<mrpt::opengl::CPlanarLaserScan>();
	obj->setScan(*(obsNode->observation().get()));
	obj->setPose(obsNode->getPose());
	obj->setSurfaceColor(1.0f, 0.0f, 0.0f, 0.5f);

	forEachGl([obsNode, obj](CGlWidget* gl) {
		gl->setSelected(obsNode->getPose().asTPose());
		gl->setLaserScan(obj);
	});
}
void 
MeshPose::setPose(std::string aName)
{
	unsigned int index = 0;
	while (index < m_vNames.size() && m_vNames[index] != aName) {
		index++;
	}
	if (index < m_vNames.size()) {
		m_ActivePose = index;
		setPose(index);
	}

	resetCompilationFlags();

}
  bool Primitive::restore(FILE* f){
    Pose pose;
    Pos vel;
    Pos avel;

    if ( fread ( pose.ptr() , sizeof ( Pose::value_type), 16, f ) == 16 )
      if( fread ( vel.ptr() , sizeof ( Pos::value_type), 3, f ) == 3 )
        if( fread ( avel.ptr() , sizeof ( Pos::value_type), 3, f ) == 3 ){
          setPose(pose);
          if(body){
            dBodySetLinearVel(body,vel.x(),vel.y(),vel.z());
            dBodySetAngularVel(body,avel.x(),avel.y(),avel.z());
          }
          return true;
        }
    fprintf ( stderr, "Primitve::restore: cannot read primitive from data\n" );
    return false;
  }
示例#14
0
文件: widget.cpp 项目: ArkaJU/opencv
void cv::viz::Widget3D::updatePose(const Affine3d &pose)
{
    vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
    CV_Assert("Widget is not 3D." && actor);

    vtkSmartPointer<vtkMatrix4x4> matrix = actor->GetUserMatrix();
    if (!matrix)
    {
        setPose(pose);
        return;
    }

    Affine3d updated_pose = pose * Affine3d(*matrix->Element);
    matrix = vtkmatrix(updated_pose.matrix);

    actor->SetUserMatrix(matrix);
    actor->Modified();
}
示例#15
0
void SkeletalCreature::gaitTick() {
	if (!gaitgene) return;
	uint8 pose = gaitgene->pose[gaiti];
	if (pose == 0) {
		if (gaiti == 0) return; // non-worky gait

		gaiti = 0;
		gaitTick();
		return;
	}

	std::map<unsigned int, creaturePoseGene *>::iterator i = posegenes.find(pose);
	if (i != posegenes.end()) {
		creaturePoseGene *poseg = i->second;
		assert(poseg->poseno == pose);
		setPose(poseg->getPoseString());
	}

	gaiti++; if (gaiti > 7) gaiti = 0;
}
示例#16
0
//------------------------------------------------------------------------------
//!
RCP<SkeletalAnimation>
Puppeteer::retarget(
   Skeleton*          srcSkel,
   Skeleton*          dstSkel,
   SkeletalAnimation* srcAnim,
   bool               constraints,
   const Vec3f&       userScale
)
{
   DBG_BLOCK( os_pup, "Puppeteer::retarget(" << srcSkel << ", " << dstSkel << ", " << srcAnim << ")" );
   if( (srcSkel == 0) || (dstSkel == 0) || (srcAnim == 0) )
   {
      // Safeguarding.
      return NULL;
   }

   // Compute scaling factors.
   Vec3f srcRoot;
   Vec3f dstRoot;
   float srcH, srcW;
   float dstH, dstW;
   getRootHeightWidth( srcSkel, srcRoot, srcH, srcW );
   getRootHeightWidth( dstSkel, dstRoot, dstH, dstW );

   float rootScaleY = dstH / srcH;
   float stepScale  = dstW / srcW;


   // Detect step constraints. (might need extra parameters to help this stage)
   // 1. Thresholds
   Vector< ContactList >  contactLists;
   float maxVelDetThreshold   = 0.1f * srcH / srcAnim->rate();
   float maxPosExtThreshold   = 0.05f * srcH;
   uint minNumFramesThreshold = 5;

   // 2. Bones candidates.
   Vector<int> boneCandidates;
   if( constraints )
   {
      for( uint i = 0; i < srcSkel->numLimbs(); ++i )
      {
         uint nID = srcSkel->limb(i).nodeID();
         Skeleton::DepthFirstIterator it = srcSkel->depthFirst( nID );
         for( uint j = 0; j < 3 && it(); ++j, ++it )
         {
            nID = *it;
         }
         boneCandidates.pushBack( srcSkel->node(nID).boneID() );
      }
   }


   // 3. Contacts.
   findContactCandidates(
      srcSkel, srcAnim,
      maxVelDetThreshold,
      maxPosExtThreshold,
      minNumFramesThreshold,
      boneCandidates,
      contactLists
   );

   // Set a default (constant) influence radius for all contact candidates.
   float influenceRadius = srcH * 0.3f;
   for( uint cl = 0; cl < contactLists.size(); ++cl )
   {
      ContactList& contactList = contactLists[cl];
      contactList.influenceRadius( influenceRadius );
   }

   // Retarget animation.
   // 1. Clone animation.
   RCP<SkeletalAnimation> dstAnim = srcAnim->clone();
   dstAnim->skeleton( dstSkel );

   // 2. Rescale root based on lower body height and readjust bone angle
   // to take into account the difference in the canonical pose.

   // Compute transformation from the src pose to the dst pose.
   Vector<Quatf> convert(srcSkel->numBones());
   for( uint b = 0; b < srcSkel->numBones(); ++b )
   {
      convert[b] = dstSkel->bone(b).orientation() * srcSkel->bone(b).orientation().getInversed();
   }


   Vec3f floorHeight( 0.0f, computeFloorHeight( srcSkel, srcAnim ), 0.0f );
   Vec3f scale = userScale * Vec3f( stepScale, rootScaleY, rootScaleY );
   for( uint p = 0; p < dstAnim->numPoses(); ++p )
   {
      // Adjust root.
      SkeletalPose& pose = *dstAnim->pose(p);
      Mat4f mat      = pose.orientation().toMatrix();
      Vec3f goalRoot = ( pose.position() + mat*srcRoot - floorHeight )*scale;
      Vec3f curRoot  = mat * dstRoot;
      pose.position( goalRoot-curRoot );

      // Adjust bones angles.
      for( uint b = 0; b < pose.bones().size(); ++b )
      {
         pose.bones()[b] = convert[b]*pose.bones()[b];
      }
   }

   // 3. Compute targets constraints.
   for( uint cl = 0; cl < contactLists.size(); ++cl )
   {
      ContactList& contactList = contactLists[cl];
      for( uint c = 0; c < contactList.numContacts(); ++c )
      {
         Contact& contact = contactList.contact(c);
         contact.target( (contact.target() - floorHeight)*scale );
      }
   }

   // 4. Retarget each frame of animation by imposing constraints on limbs
   // positions.
   Skeleton::Instance srcInst;
   srcInst.skeleton( srcSkel );
   Skeleton::Instance dstInst;
   dstInst.skeleton( dstSkel );
   ConstraintConverter  cc( srcInst, contactLists );
   for( uint p = 0; p < dstAnim->numPoses(); ++p )
   {
      setPose( srcInst, srcAnim, p ); // The ConstraintConverter needs the proper positions.
      setPose( dstInst, dstAnim.ptr(), p );
      resolveConstraints( dstInst, cc.computePoseConstraints(p) );
      dstAnim->setPose( p, dstInst.pose(), dstInst.offset() );
   }

   // 5. Scale animation speed based on relative scales.
   dstAnim->velocity( dstAnim->velocity() * scale );

   return dstAnim;
}
// Should show two rotating cubes, one in the middle of the screen being rendered normally, the
// other one in the top right hand corner, being rendered onto a texture mapped on a quad
TEST_F(OsgScreenSpaceQuadRenderTests, RenderTextureTest)
{

	auto defaultCamera = viewElement->getCamera();
	auto camera = std::make_shared<OsgCamera>("RenderPass");
	camera->setProjectionMatrix(defaultCamera->getProjectionMatrix());
	camera->setRenderGroupReference("RenderPass");
	camera->setGroupReference(SurgSim::Graphics::Representation::DefaultGroupName);

	auto dimensions = viewElement->getView()->getDimensions();

	std::shared_ptr<OsgRenderTarget2d> renderTargetOsg =
		std::make_shared<OsgRenderTarget2d>(dimensions[0], dimensions[1], 1.0, 2, true);
	camera->setRenderTarget(renderTargetOsg);

	viewElement->addComponent(camera);

	int screenWidth = dimensions[0];
	int screenHeight = dimensions[1];

	int width = dimensions[0] / 3;
	int height = dimensions[1] / 3;

	std::shared_ptr<ScreenSpaceQuadRepresentation> quad;
	quad = makeQuad("Color1", width, height, screenWidth - width, screenHeight - height);
	quad->setTexture(renderTargetOsg->getColorTargetOsg(0));
	viewElement->addComponent(quad);

	quad = makeQuad("Color2", width, height, screenWidth - width, screenHeight - height * 2);
	quad->setTexture(renderTargetOsg->getColorTargetOsg(1));
	viewElement->addComponent(quad);

	quad = makeQuad("Depth", width, height, 0.0, screenHeight - height);
	quad->setTexture(renderTargetOsg->getDepthTargetOsg());
	viewElement->addComponent(quad);

	Quaterniond quat = Quaterniond::Identity();
	RigidTransform3d startPose = SurgSim::Math::makeRigidTransform(quat, Vector3d(0.0, 0.0, -0.2));
	quat = SurgSim::Math::makeRotationQuaternion(M_PI, Vector3d::UnitY().eval());
	RigidTransform3d endPose = SurgSim::Math::makeRigidTransform(quat, Vector3d(0.0, 0.0, -0.2));

	auto box = std::make_shared<OsgBoxRepresentation>("Graphics");
	box->setSizeXYZ(0.05, 0.05, 0.05);
	box->setGroupReference("RenderPass");
	auto boxElement1 = std::make_shared<BasicSceneElement>("Box 1");
	boxElement1->addComponent(box);
	boxElement1->setPose(startPose);
	scene->addSceneElement(boxElement1);

	box = std::make_shared<OsgBoxRepresentation>("Graphics");
	box->setSizeXYZ(0.05, 0.05, 0.05);
	auto boxElement2 = std::make_shared<BasicSceneElement>("Box 2");
	boxElement2->addComponent(box);
	boxElement2->setPose(startPose);
	scene->addSceneElement(boxElement2);

	/// Run the thread
	runtime->start();

	int numSteps = 100;
	boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
	for (int i = 0; i < numSteps; ++i)
	{
		double t = static_cast<double>(i) / numSteps;
		boxElement1->setPose(SurgSim::Testing::interpolate<RigidTransform3d>(startPose, endPose, t));
		boxElement2->setPose(SurgSim::Testing::interpolate<RigidTransform3d>(endPose, startPose, t));
		boost::this_thread::sleep(boost::posix_time::milliseconds(1000 / 100));
	}

	graphicsManager->dumpDebugInfo();
}
示例#18
0
文件: Local.cpp 项目: chuck1/gru_old
void			phx::core::scene::local::step(neb::core::TimeStep const & ts) {
	BOOST_LOG_CHANNEL_SEV(lg, "phx core scene", debug) << __PRETTY_FUNCTION__ << " dt = " << ts.dt;

	neb::core::scene::local::step(ts);
	phx::core::scene::base::step(ts);

	auto app = neb::app::base::global();

	// timer
	//timer_set_.step(time);

	//physx::PxU32 nbPxactor = px_scene_->getNbActors(physx::PxActorTypeSelectionFlag::eRIGID_DYNAMIC);

	// PxScene
	assert(px_scene_ != NULL);

	px_scene_->simulate(ts.dt);
	px_scene_->fetchResults(true);

	// retrieve array of actors that moved
	physx::PxU32 nb_active_transforms;
	const physx::PxActiveTransform* active_transforms = px_scene_->getActiveTransforms(nb_active_transforms);

	
	BOOST_LOG_CHANNEL_SEV(lg, "phx core scene", debug)
		<< "active transforms: " << nb_active_transforms;

	//physx::PxTransform pose;
	physx::PxTransform pose;

	// update each render object with the new transform
	for(physx::PxU32 i = 0; i < nb_active_transforms; ++i) {
		//physx::PxActor* px_actor = active_transforms[i].actor;

		//printf( "actor type = %i\n", px_actor->getType() );

		physx::PxActor* pxactor = active_transforms[i].actor;
		assert(pxactor);

		void* ud = active_transforms[i].userData;
		assert(ud);

		physx::PxRigidBody* pxrigidbody = pxactor->isRigidBody();


		neb::core::actor::base* pactor = static_cast<neb::core::actor::base*>(ud);
		auto actor = pactor->isActorBase();
		
		assert(actor);
		
		if(actor) {
			pose = active_transforms[i].actor2World;
			actor->setPose(neb::core::pose(
						phx::util::convert(pose.p),
						phx::util::convert(pose.q)
						));
			
			BOOST_LOG_CHANNEL_SEV(lg, "phx core scene", debug)
				<< std::setw(8) << "p"
				<< std::setw(8) << pose.p.x
				<< std::setw(8) << pose.p.y
				<< std::setw(8) << pose.p.z;
		

			if(pxrigidbody != NULL) {
				auto rigidbody = actor->isActorRigidBody();
				if(!rigidbody) {
					std::cout << typeid(*actor).name() << std::endl;
					abort();
				}

				physx::PxVec3 v(pxrigidbody->getLinearVelocity());

				rigidbody->velocity_ = phx::util::convert(v);

				//v.print();
			}

			actor->flag_.set(neb::core::actor::util::Flag::E::SHOULD_UPDATE);
		}
	}

	// vehicle
	//physx::PxVec3 g(0,-0.25,0);
	//vehicle_manager_.vehicle_suspension_raycasts(px_scene_);
	//vehicle_manager_.update((float)dt, g);

	send_actor_update();

}
示例#19
0
template<typename PointT> void
pcl::registration::LUM<PointT>::compute ()
{
  int n = static_cast<int> (getNumVertices ());
  if (n < 2)
  {
    PCL_ERROR("[pcl::registration::LUM::compute] The slam graph needs at least 2 vertices.\n");
    return;
  }
  for (int i = 0; i < max_iterations_; ++i)
  {
    // Linearized computation of C^-1 and C^-1*D and convergence checking for all edges in the graph (results stored in slam_graph_)
    typename SLAMGraph::edge_iterator e, e_end;
    for (boost::tuples::tie (e, e_end) = edges (*slam_graph_); e != e_end; ++e)
      computeEdge (*e);

    // Declare matrices G and B
    Eigen::MatrixXf G = Eigen::MatrixXf::Zero (6 * (n - 1), 6 * (n - 1));
    Eigen::VectorXf B = Eigen::VectorXf::Zero (6 * (n - 1));

    // Start at 1 because 0 is the reference pose
    for (int vi = 1; vi != n; ++vi)
    {
      for (int vj = 0; vj != n; ++vj)
      {
        // Attempt to use the forward edge, otherwise use backward edge, otherwise there was no edge
        Edge e;
        bool present1, present2;
        boost::tuples::tie (e, present1) = edge (vi, vj, *slam_graph_);
        if (!present1)
        {
          boost::tuples::tie (e, present2) = edge (vj, vi, *slam_graph_);
          if (!present2)
            continue;
        }

        // Fill in elements of G and B
        if (vj > 0)
          G.block (6 * (vi - 1), 6 * (vj - 1), 6, 6) = -(*slam_graph_)[e].cinv_;
        G.block (6 * (vi - 1), 6 * (vi - 1), 6, 6) += (*slam_graph_)[e].cinv_;
        B.segment (6 * (vi - 1), 6) += (present1 ? 1 : -1) * (*slam_graph_)[e].cinvd_;
      }
    }

    // Computation of the linear equation system: GX = B
    // TODO investigate accuracy vs. speed tradeoff and find the best solving method for our type of linear equation (sparse)
    Eigen::VectorXf X = G.colPivHouseholderQr ().solve (B);

    // Update the poses
    float sum = 0.0;
    for (int vi = 1; vi != n; ++vi)
    {
      Eigen::Vector6f difference_pose = static_cast<Eigen::Vector6f> (-incidenceCorrection (getPose (vi)).inverse () * X.segment (6 * (vi - 1), 6));
      sum += difference_pose.norm ();
      setPose (vi, getPose (vi) + difference_pose);
    }

    // Convergence check
    if (sum <= convergence_threshold_ * static_cast<float> (n - 1))
      return;
  }
}
示例#20
0
/**
 * This method calculates the moves for the AI player
 *
 * @param movePtr Pointer to move the move list into
 */
bool AIPlayer::getAIMove(Move *movePtr)
{
   *movePtr = NullMove;

   // Use the eye as the current position.
   MatrixF eye;
   getEyeTransform(&eye);
   Point3F location = eye.getPosition();
   Point3F rotation = getRotation();

#ifdef TORQUE_NAVIGATION_ENABLED
   if(mDamageState == Enabled)
   {
      if(mMoveState != ModeStop)
         updateNavMesh();
      if(!mFollowData.object.isNull())
      {
         if(mPathData.path.isNull())
         {
            if((getPosition() - mFollowData.object->getPosition()).len() > mFollowData.radius)
               followObject(mFollowData.object, mFollowData.radius);
         }
         else
         {
            if((mPathData.path->mTo - mFollowData.object->getPosition()).len() > mFollowData.radius)
               repath();
            else if((getPosition() - mFollowData.object->getPosition()).len() < mFollowData.radius)
            {
               clearPath();
               mMoveState = ModeStop;
            throwCallback("onTargetInRange");
            }
            else if((getPosition() - mFollowData.object->getPosition()).len() < mAttackRadius)
            {
            throwCallback("onTargetInFiringRange");
            }
         }
      }
   }
#endif // TORQUE_NAVIGATION_ENABLED

   // Orient towards the aim point, aim object, or towards
   // our destination.
   if (mAimObject || mAimLocationSet || mMoveState != ModeStop) 
   {
      // Update the aim position if we're aiming for an object
      if (mAimObject)
         mAimLocation = mAimObject->getPosition() + mAimOffset;
      else
         if (!mAimLocationSet)
            mAimLocation = mMoveDestination;

      F32 xDiff = mAimLocation.x - location.x;
      F32 yDiff = mAimLocation.y - location.y;

      if (!mIsZero(xDiff) || !mIsZero(yDiff)) 
      {
         // First do Yaw
         // use the cur yaw between -Pi and Pi
         F32 curYaw = rotation.z;
         while (curYaw > M_2PI_F)
            curYaw -= M_2PI_F;
         while (curYaw < -M_2PI_F)
            curYaw += M_2PI_F;

         // find the yaw offset
         F32 newYaw = mAtan2( xDiff, yDiff );
         F32 yawDiff = newYaw - curYaw;

         // make it between 0 and 2PI
         if( yawDiff < 0.0f )
            yawDiff += M_2PI_F;
         else if( yawDiff >= M_2PI_F )
            yawDiff -= M_2PI_F;

         // now make sure we take the short way around the circle
         if( yawDiff > M_PI_F )
            yawDiff -= M_2PI_F;
         else if( yawDiff < -M_PI_F )
            yawDiff += M_2PI_F;

         movePtr->yaw = yawDiff;

         // Next do pitch.
         if (!mAimObject && !mAimLocationSet) 
         {
            // Level out if were just looking at our next way point.
            Point3F headRotation = getHeadRotation();
            movePtr->pitch = -headRotation.x;
         }
         else 
         {
            // This should be adjusted to run from the
            // eye point to the object's center position. Though this
            // works well enough for now.
            F32 vertDist = mAimLocation.z - location.z;
            F32 horzDist = mSqrt(xDiff * xDiff + yDiff * yDiff);
            F32 newPitch = mAtan2( horzDist, vertDist ) - ( M_PI_F / 2.0f );
            if (mFabs(newPitch) > 0.01f) 
            {
               Point3F headRotation = getHeadRotation();
               movePtr->pitch = newPitch - headRotation.x;
            }
         }
      }
   }
   else 
   {
      // Level out if we're not doing anything else
      Point3F headRotation = getHeadRotation();
      movePtr->pitch = -headRotation.x;
   }

   // Move towards the destination
   if (mMoveState != ModeStop) 
   {
      F32 xDiff = mMoveDestination.x - location.x;
      F32 yDiff = mMoveDestination.y - location.y;

      // Check if we should mMove, or if we are 'close enough'
      if (mFabs(xDiff) < mMoveTolerance && mFabs(yDiff) < mMoveTolerance) 
      {
         mMoveState = ModeStop;
         onReachDestination();
      }
      else 
      {
         // Build move direction in world space
         if (mIsZero(xDiff))
            movePtr->y = (location.y > mMoveDestination.y) ? -1.0f : 1.0f;
         else
            if (mIsZero(yDiff))
               movePtr->x = (location.x > mMoveDestination.x) ? -1.0f : 1.0f;
            else
               if (mFabs(xDiff) > mFabs(yDiff)) 
               {
                  F32 value = mFabs(yDiff / xDiff);
                  movePtr->y = (location.y > mMoveDestination.y) ? -value : value;
                  movePtr->x = (location.x > mMoveDestination.x) ? -1.0f : 1.0f;
               }
               else 
               {
                  F32 value = mFabs(xDiff / yDiff);
                  movePtr->x = (location.x > mMoveDestination.x) ? -value : value;
                  movePtr->y = (location.y > mMoveDestination.y) ? -1.0f : 1.0f;
               }

         // Rotate the move into object space (this really only needs
         // a 2D matrix)
         Point3F newMove;
         MatrixF moveMatrix;
         moveMatrix.set(EulerF(0.0f, 0.0f, -(rotation.z + movePtr->yaw)));
         moveMatrix.mulV( Point3F( movePtr->x, movePtr->y, 0.0f ), &newMove );
         movePtr->x = newMove.x;
         movePtr->y = newMove.y;

         // Set movement speed.  We'll slow down once we get close
         // to try and stop on the spot...
         if (mMoveSlowdown) 
         {
            F32 speed = mMoveSpeed;
            F32 dist = mSqrt(xDiff*xDiff + yDiff*yDiff);
            F32 maxDist = mMoveTolerance*2;
            if (dist < maxDist)
               speed *= dist / maxDist;
            movePtr->x *= speed;
            movePtr->y *= speed;

            mMoveState = ModeSlowing;
         }
         else 
         {
            movePtr->x *= mMoveSpeed;
            movePtr->y *= mMoveSpeed;

            mMoveState = ModeMove;
         }

         if (mMoveStuckTestCountdown > 0)
            --mMoveStuckTestCountdown;
         else
         {
            // We should check to see if we are stuck...
            F32 locationDelta = (location - mLastLocation).len();
            if (locationDelta < mMoveStuckTolerance && mDamageState == Enabled) 
            {
               // If we are slowing down, then it's likely that our location delta will be less than
               // our move stuck tolerance. Because we can be both slowing and stuck
               // we should TRY to check if we've moved. This could use better detection.
               if ( mMoveState != ModeSlowing || locationDelta == 0 )
               {
                  mMoveState = ModeStuck;
                  onStuck();
               }
            }
         }
      }
   }

   // Test for target location in sight if it's an object. The LOS is
   // run from the eye position to the center of the object's bounding,
   // which is not very accurate.
   if (mAimObject)
   {
      if (checkInLos(mAimObject.getPointer()))
      {
         if (!mTargetInLOS)
         {
            throwCallback( "onTargetEnterLOS" );
            mTargetInLOS = true;
         }
   }
      else if (mTargetInLOS)
      {
            throwCallback( "onTargetExitLOS" );
            mTargetInLOS = false;
         }
      }

   Pose desiredPose = mPose;

   if ( mSwimming )  
      desiredPose = SwimPose;   
   else if ( mAiPose == 1 && canCrouch() )   
      desiredPose = CrouchPose;  
   else if ( mAiPose == 2 && canProne() )  
      desiredPose = PronePose;  
   else if ( mAiPose == 3 && canSprint() )  
      desiredPose = SprintPose;  
   else if ( canStand() )  
      desiredPose = StandPose;  
  
   setPose( desiredPose );
   
   // Replicate the trigger state into the move so that
   // triggers can be controlled from scripts.
   for( U32 i = 0; i < MaxTriggerKeys; i++ )
      movePtr->trigger[ i ] = getImageTriggerState( i );

#ifdef TORQUE_NAVIGATION_ENABLED
   if(mJump == Now)
   {
      movePtr->trigger[2] = true;
      mJump = None;
   }
   else if(mJump == Ledge)
   {
      // If we're not touching the ground, jump!
      RayInfo info;
      if(!getContainer()->castRay(getPosition(), getPosition() - Point3F(0, 0, 0.4f), StaticShapeObjectType, &info))
      {
         movePtr->trigger[2] = true;
         mJump = None;
      }
   }
#endif // TORQUE_NAVIGATION_ENABLED

   mLastLocation = location;

   return true;
}