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(); }
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; }
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; } }
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; }