コード例 #1
0
ファイル: world.cpp プロジェクト: drivird/drunken-octo-robot
// This is the task that deals with making everything interactive
AsyncTask::DoneStatus World::roll(GenericAsyncTask* taskPtr)
   {
   // Standard technique for finding the amount of time since the last frame
   double dt = taskPtr->get_elapsed_time() - m_last;
   m_last = taskPtr->get_elapsed_time();

   // If dt is large, then there has been a # hiccup that could cause the ball
   // to leave the field if this functions runs, so ignore the frame
   if(dt > 0.2) { return AsyncTask::DS_cont; }

   // The collision handler collects the collisions. We dispatch which function
   // to handle the collision based on the name of what was collided into
   for(int i = 0; i < m_cHandlerPtr->get_num_entries(); ++i)
      {
      PT(CollisionEntry) entryPtr = m_cHandlerPtr->get_entry(i);
      const string& name = entryPtr->get_into_node()->get_name();
      if(name == "wall_collide")        { wall_collide_handler(*entryPtr);   }
      else if(name == "ground_collide") { ground_collide_handler(*entryPtr); }
      else if(name == "loseTrigger")    { lose_game(*entryPtr);              }
      }

   // Read the mouse position and tilt the maze accordingly
   PT(MouseWatcher) mouseWatcherPtr = DCAST(MouseWatcher, m_windowFrameworkPtr->get_mouse().node());
   if(mouseWatcherPtr->has_mouse())
      {
      // get the mouse position
      const LPoint2f& mpos = mouseWatcherPtr->get_mouse();
      m_mazeNp.set_p(mpos.get_y() * -10);
      m_mazeNp.set_r(mpos.get_x() * 10);
      }

   // Finally, we move the ball
   // Update the velocity based on acceleration
   m_ballV += m_accelV * dt * ACCEL;
   // Clamp the velocity to the maximum speed
   if(m_ballV.length_squared() > MAX_SPEED_SQ)
      {
      m_ballV.normalize();
      m_ballV *= MAX_SPEED;
      }
   // Update the position based on the velocity
   m_ballRootNp.set_pos(m_ballRootNp.get_pos() + (m_ballV * dt));

   // This block of code rotates the ball. It uses something called a quaternion
   // to rotate the ball around an arbitrary axis. That axis perpendicular to
   // the balls rotation, and the amount has to do with the size of the ball
   // This is multiplied on the previous rotation to incrementally turn it.
   LRotationf prevRot(m_ballNp.get_quat());
   LVector3f axis = UP.cross(m_ballV);
   LRotationf newRot(axis, 45.5 * dt * m_ballV.length());
   m_ballNp.set_quat(prevRot * newRot);

   // Continue the task indefinitely
   return AsyncTask::DS_cont;
   }
コード例 #2
0
/*! When copying from a regular contact, we must be careful because the	
	normal of a virtual contact points outwards, whereas the normal of a 
	trasitional contact points inwards.
*/
VirtualContact::VirtualContact(int f, int l, Contact *original) : Contact()
{
	init();
	mFingerNum = f;
	mLinkNum = l;

	numFrictionEdges = original->numFrictionEdges;
	memcpy( frictionEdges, original->frictionEdges, 6 * numFrictionEdges * sizeof(double) );
	cof = original->cof;

	loc = original->loc;
	frame = original->frame;
	//we now rotate the frame so that the normal points outwards, as the contact on the object would
	Quaternion q(3.14159, vec3(1,0,0));
	transf newRot(q, vec3(0,0,0) );
	frame = newRot * frame;
	normal = -1 * original->normal;
	body1 = original->body1;
	body2 = original->body2;
}