예제 #1
0
void Camera::tic(uint64_t time) {
  vec3 temp1, temp2;
  vec3 tempVec;
   mat4 tempMatrix;
   float pathAccOffset = 0.0;

  // Find the angle between the two paths
// float rotAngle = m_pathAngle * (m_head->getPosition() - m_pathPos).Length()
// / ((m_head->getPosition() - m_tail->getPosition()).Length()
// - CAMERA_LOOK_AHEAD_DISTANCE);

  // If we are turning our forward, but the angle between ourselves and
  // the intended is close enough, stop turning to allow for rotation
  /*if (m_turning && .5 > 
      angleBetween(m_head->getPosition() - m_tail->getPosition(), 
		   m_pathRef - m_pathPos)) {
		   m_turning = false;
    m_pathPos = m_pathRef - ((m_head->getPosition() 
			      - m_tail->getPosition()).Normalized() 
			     * CAMERA_LOOK_AHEAD_DISTANCE);
    //  m_pathUp = m_tail->getUp();
    //} 
  
  // If we aren't turning, its safe to rotate
  //if (!m_turning) {*/
     temp1 = m_tail->getUp() * (m_head->getPosition() - m_pathRef).Length() / 
	(m_head->getPosition() - m_tail->getPosition()).Length();
     temp2 = m_head->getUp() * (m_pathRef - m_tail->getPosition()).Length() / 
	(m_head->getPosition() - m_tail->getPosition()).Length();
     m_pathUp = (temp1 + temp2).Normalized();
   //  }

  // Move our reference point down the path
  if (m_boosting) {
     m_boostTime += time;
     if (m_boostTime > 2000) {
m_boostTime = 2000;
     }


     pathAccOffset = (CAMERA_BOOST_ACC * m_boostTime);

  }
  else {
     m_boostTime -= time * 3;
     if(m_boostTime < 0) {
	m_boostTime = 0;
     }

  }

  m_pathRef += (((m_head->getPosition() - m_pathRef).Normalized()) * 
		   ((time * CAMERA_DEF_VELOCITY) + pathAccOffset));
  
  calculateSide();
  tempVec = (m_pathRef - m_pathPos).Normalized();
  m_pathPos = m_pathRef - (tempVec * CAMERA_LOOK_AHEAD_DISTANCE);

  setLookAt();
}
예제 #2
0
Camera::Camera(PathPoint* head, PathPoint* tail)
   : m_pathPos(0,0,0), m_pathRef(0,0,1), m_pathUp(0,1,0), m_pathSide (1, 0, 0),
     m_eye(0,0,0), m_ref(0,0,1), m_up(0,1,0), cameraType(_MOTION_CAMERA),
     m_turning(false), m_boosting(false), m_boostTime(0) {

   //Save the tail and head
   m_tail = tail;
   m_head = head;
   
   //Set the current up, position, reference, side, and forward vectors
   m_pathUp = m_tail->getUp();
   m_pathPos = tail->getPosition();
   m_pathRef = m_pathPos + ((head->getPosition()
- tail->getPosition()).Normalized()
* CAMERA_LOOK_AHEAD_DISTANCE);
   m_pathForw = (m_head->getPosition() -
m_tail->getPosition()).Normalized();
   calculateSide();
   m_planes = vector<vec4>(6);

   //Calculate the angle between them
   m_pathAngle = angleBetween(m_head->getUp(), m_tail->getUp());
   
   //Initialize the real look at vectors
   m_eye = m_pathPos;
   m_ref = m_pathRef;
   m_up = m_pathUp;
}
예제 #3
0
void Camera::checkPath(PathPoint* head) {
  if (head != m_head) {
    m_tail = m_head;
    m_head = head;

    //Shouldn't need to change, but might have to
    //m_pathUp = m_tail->getUp();
    calculateSide();

    //m_pathAngle = angleBetween(m_head->getUp(), m_tail->getUp());
    
    //m_turning = true;
  }
}
예제 #4
0
bool testShape2D
	( SWManifold& manifold
	, const SWShape2D* shape1, const tmat33& mat1
	, const SWShape2D* shape2, const tmat33& mat2 )
{
	tvec2 simplex[3];

	//! find first simplex
	{
		tvec2 dir, farthest1, farthest2;

		dir = tvec2::axisX;
		shape1->getFarthest( farthest1, dir, mat1 );
		shape2->getFarthest( farthest2, -dir, mat2 );
		simplex[0] = farthest1 - farthest2;

		dir = (-simplex[0]).normal();
		shape1->getFarthest( farthest1, dir, mat1 );
		shape2->getFarthest( farthest2, -dir, mat2 );
		simplex[1] = farthest1 - farthest2;

		tvec2 line = (simplex[1] - simplex[0]);
		if ( line.length() < SW_Epsilon ) return false;

		float kz = line.cross( simplex[0] );
		if ( SWMath.abs(kz) < SW_Epsilon )
		{
			if (  line.dot( -simplex[0] ) < 0 ) return false;
			if ( -line.dot( -simplex[1] ) < 0 ) return false;
			kz = 1;
		}
		dir = line.cross( kz ).normal();
		shape1->getFarthest( farthest1, dir, mat1 );
		shape2->getFarthest( farthest2, -dir, mat2 );
		simplex[2] = farthest1 - farthest2;
	}

	//! try a few times to find overriding using Minkowski Difference and GJK
	tuint trying = 32;
	while ( trying-- )
	{
		float simplesArea = calculateArea(simplex[0], simplex[1], simplex[2]);
		if ( simplesArea < SW_Epsilon ) return false;
		float originArea = 0;
		originArea += calculateArea( tvec2::zero, simplex[0], simplex[1]);
		originArea += calculateArea( tvec2::zero, simplex[1], simplex[2]);
		originArea += calculateArea( tvec2::zero, simplex[2], simplex[0]);
		
		//! is it close enough
		if ( SWMath.abs(originArea - simplesArea) < SW_Epsilon )
		{
			//! finds normal and depth using EPA.
			//! we only try as much as maxTrying to find them
			const tuint maxTrying = 16;
			tvec2 polytope[maxTrying];
			tvec2 center = tvec2::zero;
			tuint count = 0;

			//! first, fills polytope with simplex that contains the origin.
			center += polytope[count] = simplex[count];++count;
			center += polytope[count] = simplex[count];++count;
			center += polytope[count] = simplex[count];++count;
			center /= count;
			while ( count < maxTrying )
			{
				tuint insertPos = 0;
				tvec2 direction;
				float closest = FLT_MAX;
				for ( tuint i = 0 ; i < count ; ++i )
				{
					tvec2 edge = polytope[(i+1)%count] - polytope[i];
					float kz = edge.cross( center-polytope[i] );
					tvec2 dir = edge.cross(kz).normal();
					float length = dir.dot(polytope[i]);
					if ( length < closest )
					{
						insertPos = i+1;
						direction = dir;
						closest = length;
					}
				}

				//! finds new farthest point.
				tvec2 farthest1, farthest2;
				shape1->getFarthest( farthest1, direction, mat1 );
				shape2->getFarthest( farthest2, -direction, mat2 );
				tvec2 farthest = farthest1 - farthest2;

				//! save the result
				manifold.normal = direction;
				manifold.depth = closest;

				//! is it close enough
				float length = direction.dot(farthest);
				if ( SWMath.abs(length - closest) < SW_Epsilon )
				{
					manifold.normal = manifold.normal.normal();
					break;
				}
				else 
				{
					tuint itor = count;
					while ( itor > insertPos )
					{
						polytope[itor--] = polytope[itor];
					}
					polytope[insertPos] = farthest;
					count += 1;
				}
			}

			//! finds incident points using edge clipping.
			{
				tuint count = 0;
				struct {tvec2 v1,v2;} ref, inc;
				shape2->getCrossest( inc.v1, inc.v2, -manifold.normal, mat2);
				if ( (inc.v1-inc.v2).length() < SW_Epsilon ) manifold.points[count++] = (inc.v1+inc.v2)*0.5f;

				if ( count == 0 )
				{
					shape1->getCrossest( ref.v1, ref.v2, manifold.normal, mat1);
					clipToEdge( inc.v1, inc.v2, ref.v1, ref.v2 );
					tvec2 edgeNormal = (ref.v2 - ref.v1).normal();
					edgeNormal = -edgeNormal.cross( edgeNormal.cross(manifold.normal) );

					float d1, d2;
					d1 = edgeNormal.dot( inc.v1 - ref.v1 );
					d2 = edgeNormal.dot( inc.v2 - ref.v1 );
					if ( d1 <= 0 ) {manifold.points[count++] = inc.v1;}
					if ( d2 <= 0 ) {manifold.points[count++] = inc.v2;}
					if ( count == 2 )
					{
						if ( (inc.v1-inc.v2).length() < SW_Epsilon )
						{
							manifold.points[0] = (inc.v1+inc.v2)*0.5f;
							count = 1;
						}
					}
				}
				manifold.count = count;
			}
			return true;
		}
		else
		{
			//! finds sides where origin is.
			tflag8 sideFlag;
			calculateSide( sideFlag, simplex[0], simplex[1], simplex[2] );
			tuint count = 0;
			tuint index = 0;

			//! meaning of outside is opposite side of center of polygon in each edges.
			//! if there are two outsides, 
			//! it means that the shapes don't meet each other in case of the convex-shape.
			if ( sideFlag.get(0) ) { index = 0; count += 1;}
			if ( sideFlag.get(1) ) { index = 1; count += 1;}
			if ( sideFlag.get(2) ) { index = 2; count += 1;}
			if ( count >= 2 ) return false;

			//! finds normal to the origin from a edge.
			tvec2 edge = simplex[(index+1)%3]-simplex[index];
			float kz = edge.cross(simplex[index]);
			tvec2 dir = edge.cross( kz ).normal();

			//! finds new farthest point.
			tvec2 farthest1, farthest2;
			shape1->getFarthest( farthest1, dir, mat1 );
			shape2->getFarthest( farthest2, -dir, mat2 );
			simplex[(index+2)%3] = farthest1 - farthest2;
		}
	}
	return false;
}