Matrix4 Matrix4::BuildViewMatrix(const Vector3 &from, const Vector3 &lookingAt, const Vector3 up /*= Vector3(1,0,0)*/ ) { Matrix4 r; r.SetPositionVector(Vector3(-from.x,-from.y,-from.z)); Matrix4 m; Vector3 f = (lookingAt - from); f.Normalise(); Vector3 s = Vector3::Cross(f,up); Vector3 u = Vector3::Cross(s,f); s.Normalise(); u.Normalise(); m.values[0] = s.x; m.values[4] = s.y; m.values[8] = s.z; m.values[1] = u.x; m.values[5] = u.y; m.values[9] = u.z; m.values[2] = -f.x; m.values[6] = -f.y; m.values[10] = -f.z; return m*r; }
Vector3 FeedingTube::GetForwardsClippingDir( double _predictionTime, FeedingTube *_sender ) { if (_sender == NULL) { return GetDishFront( _predictionTime ); } Vector3 senderDishFront = _sender->GetDishFront( _predictionTime ); Vector3 dishFront = GetDishFront( _predictionTime ); // Make the two dishFronts point at each other. Vector3 SR = GetDishPos(_predictionTime) - _sender->GetDishPos(_predictionTime) ; SR.Normalise(); if (SR * senderDishFront < 0) senderDishFront *= -1; if (SR * dishFront > 0) dishFront *= -1; Vector3 combinedDirection = -senderDishFront + dishFront; if (combinedDirection.MagSquared() < 0.5) return -dishFront; return combinedDirection.Normalise(); }
Vector3 Tripod::CalcAttackUpVector() { Vector3 toEnemy = m_attackTarget - m_pos; toEnemy.Normalise(); Vector3 toEnemyHorizontal(toEnemy); toEnemyHorizontal.HorizontalAndNormalise(); Vector3 up = g_upVector - toEnemyHorizontal; up.Normalise(); return up; }
Vector3 Trunk::vertexCoordOfCircle(const Vector3& normal, const Vector3& centerCoord, const float& radius, const short& degree) { Vector3 uV = Vector3(normal.y, normal.x, 0); Vector3 vV = Vector3::Cross(normal, uV); uV.Normalise(); vV.Normalise(); float rad = PI * degree / 180; auto circle = [&](float center, float u, float v){ return center + radius * ((u * cos(rad)) + (v * sin(rad))); }; return Vector3(circle(centerCoord.x, uV.x, vV.x), circle(centerCoord.y, uV.y, vV.y), circle(centerCoord.z, uV.z, vV.z)); }
void SoulDestroyer::RenderShapes( double _predictionTime ) { Vector3 predictedPos = m_pos + m_vel * _predictionTime; Vector3 predictedFront = m_front; Vector3 predictedUp = m_up; Vector3 predictedRight = predictedUp ^ predictedFront; predictedFront = predictedRight ^ predictedUp; predictedFront.Normalise(); predictedUp.Normalise(); Matrix34 mat(predictedFront, predictedUp, predictedPos); glEnable( GL_NORMALIZE ); glDisable( GL_TEXTURE_2D ); g_app->m_renderer->SetObjectLighting(); s_shapeHead[m_id.GetTeamId()]->Render(_predictionTime, mat); for( int i = 1; i < m_positionHistory.Size(); i+=1 ) { Vector3 pos1 = *m_positionHistory.GetPointer(i); Vector3 pos2 = *m_positionHistory.GetPointer(i-1); Vector3 pos = pos1 + (pos2 - pos1); Vector3 front = (pos2 - pos1).Normalise(); Vector3 right = front ^ g_upVector; Vector3 up = right ^ front; Vector3 vel = (pos2 - pos1) / SERVER_ADVANCE_PERIOD; pos += vel * _predictionTime; double scale = 1.0 - ( (double) i / (double) m_positionHistory.Size() ); scale *= 1.5; if( i == m_positionHistory.Size()-1 ) scale = 0.8; scale = max( scale, 0.5 ); Matrix34 tailMat( front, up, pos ); tailMat.u *= scale; tailMat.r *= scale; tailMat.f *= scale; s_shapeTail[m_id.GetTeamId()]->Render(_predictionTime, tailMat ); } g_app->m_renderer->UnsetObjectLighting(); glDisable( GL_NORMALIZE ); }
void Explosion::ApplyForceToApplicable() { list<GameObject *> objects; GameObjectManager::Instance()->GetTypesOnScreen<DrawableObject>(objects); for (auto obj : objects) { if (!obj) { GAME_ASSERT(obj); continue; } if (obj->IsDebris() || obj->IsProjectile()) { MovingSprite * moveable = static_cast<MovingSprite *>(obj); // has to be a movingsprite if it's one of the above Vector3 direction = obj->Position() - m_position; float distSquared = direction.LengthSquared(); if (distSquared < (mRadius * mRadius)) { direction.Normalise(); moveable->SetVelocityXYZ(moveable->GetVelocity().X + (direction.X * 10), moveable->GetVelocity().Y + (direction.Y * 15), 0); } } } }
/* Here's how we generate the 3D normalised direction vector that we use with our picking ray. We use our new unproject function /twice/ and then normalise the result. Here's how this works! We unproject once right up against the near plane, and then once again, right up against the far plane. This gives us 2 positions in space, both 'under' the mouse pointer from the camera's perspective. We can then get the direction vector between them and normalise it, giving us a direction vector that comes from our camera position, and passes through the mouse pointer. Near Far | | | | | | O-> |* *| | | | | */ Vector3 Renderer::GetMouseDirectionVector3(float aspect, float fov, Camera &cam) { Vector2 mpos = Window::GetMouse()->GetAbsolutePosition(); //We remove the y axis mouse position from height as OpenGL is 'upside down', //and thinks the bottom left is the origin, instead of the top left! Vector3 nearPos = Vector3(mpos.x, height - mpos.y, 0.0f ); //We also don't use exactly 1.0 (the normalised 'end' of the far plane) as this //causes the unproject function to go a bit weird. Vector3 farPos = Vector3(mpos.x, height - mpos.y, 0.99999999f ); Vector3 a = UnProject(nearPos,aspect,fov,cam); Vector3 b = UnProject(farPos,aspect,fov,cam); Vector3 c = b-a; c.Normalise(); return c; }
Vector3 Centripetal(const Point3& origin, const Point3& pos, const Vector3& vel, float mass) { const Vector3 dir = origin - pos; float radius = dir.Magnitude(); float mag = mass * vel.MagnitudeSq() / radius; return dir.Normalise() * mag; }
void Spring::Update(float msec){ //F = -kx - c (n . vab) //Calculate the world positions for the local positions Vector3 posL = m_lhs->BuildTransform() * m_localPosL; Vector3 posR = m_rhs->BuildTransform() * m_localPosR; //Work out the direction between the two nodes Vector3 forceDir = posR - posL; //Calculate a value for the length between the two points - rest length. //This is basically the amount of extension the spring has undertaken. (x) float err = forceDir.Length() - m_length; //We divide it by the rest length of the spring to get a normalized value for the // extension of the spring err /= m_length; //Normalise the direction of the force forceDir.Normalise(); Vector3& linVelL = m_lhs->GetLinearVelocity(); Vector3& linVelR = m_rhs->GetLinearVelocity(); //Calculate the force to be applied Vector3 force = forceDir * (err * m_ks - Vector3::Dot(forceDir, (linVelL - linVelR) * m_kd)); m_lhs->ApplyForce(force*0.5f, Vector3(0,0,0)); m_rhs->ApplyForce(-force*0.5f, Vector3(0,0,0)); }
Vector3 Project(const Vector3 &v1, const Vector3 &v2) { // *********************************************** // Vector Projection // ----------------------------------------------- // | ^ (v2) // | /. // | / . // ------ X -----> (v1) // | // | // | // To project onto another vector we get the // the cosine of the angle formed between v1 & v2. // This can be done through normaliseing v1 and // then doing a dot product. We then rescale v1 // to the cosine of the angle and then we have our // projected vector. // *********************************************** Vector3 result = v1; result.Normalise(); float cosine = Vector3::DOT(result, v2); result *= cosine; return result; }
void Quaternion::Rotation(float theta,Vector3 r) { float sn=sin(-DEGTORAD*theta/2),cs=cos(-DEGTORAD*theta/2); r.Normalise(); x=r.x*sn; y=r.y*sn; z=r.z*sn; w=cs; }
Matrix34 const &Matrix34::RotateAround( Vector3 const & _onorm, float _angle ) { Vector3 norm = _onorm; norm.Normalise(); float s = (float)sin(_angle); float c = (float)cos(_angle); float dot = r * norm; Vector3 a = norm * dot; Vector3 n1 = r - a; Vector3 n2 = norm ^ n1; r = a + c*n1 + s*n2; dot = u * norm; a = norm * dot; n1 = u - a; n2 = norm ^ n1; u = a + c*n1 + s*n2; dot = f * norm; a = norm * dot; n1 = f - a; n2 = norm ^ n1; f = a + c*n1 + s*n2; return *this; }
Matrix34 const &Matrix34::RotateAround( Vector3 const & _onorm, double _angle ) { Vector3 norm = _onorm; norm.Normalise(); double s = (double)iv_sin(_angle); double c = (double)iv_cos(_angle); double dot = r * norm; Vector3 a = norm * dot; Vector3 n1 = r - a; Vector3 n2 = norm ^ n1; r = a + c*n1 + s*n2; dot = u * norm; a = norm * dot; n1 = u - a; n2 = norm ^ n1; u = a + c*n1 + s*n2; dot = f * norm; a = norm * dot; n1 = f - a; n2 = norm ^ n1; f = a + c*n1 + s*n2; return *this; }
bool CollisionDetector::SphereSphereCollision(PhysicsNode& p0, PhysicsNode& p1, CollisionData* data) { return false; //get the collision data CollisionSphere& s0 = *(CollisionSphere*)p0.GetCollisionVolume(); CollisionSphere& s1 = *(CollisionSphere*)p1.GetCollisionVolume(); //get the normal Vector3 normal = p0.GetPosition() - p1.GetPosition(); //get the distance (squared) const float distSq = LengthSq(normal); //get the max distance before collision const float sumRadius = s0.GetRadius() + s1.GetRadius(); //if the distance is less than the max distance if (distSq < sumRadius*sumRadius) { //if there is collision data storage if (data) { //set the penetration depth data->m_penetration = sumRadius - sqrtf(distSq); //get the normal of the collision normal.Normalise(); data->m_normal = normal; //get the point of collision data->m_point = p0.GetPosition() - normal*(s0.GetRadius() - data->m_penetration*0.5f); } return true; } return false; }
void Officer::RenderFlag( float _predictionTime ) { float timeIndex = g_gameTime + m_id.GetUniqueId() * 10; float size = 20.0f; Vector3 up = g_upVector; Vector3 front = m_front * -1; front.y = 0; front.Normalise(); if( m_orders != OrderNone ) { up.RotateAround( front * sinf(timeIndex*2) * 0.3f ); } Vector3 entityUp = g_upVector; Vector3 entityRight(m_front ^ entityUp); Vector3 entityFront = entityUp ^ entityRight; Matrix34 mat( entityFront, entityUp, m_pos + m_vel * _predictionTime ); Vector3 flagPos = m_flagMarker->GetWorldMatrix(mat).pos; int texId = -1; if ( m_orders == OrderNone ) texId = g_app->m_resource->GetTexture( "icons/banner_none.bmp" ); else if ( m_orders == OrderGoto ) texId = g_app->m_resource->GetTexture( "icons/banner_goto.bmp" ); else if ( m_orders == OrderFollow && !m_absorb ) texId = g_app->m_resource->GetTexture( "icons/banner_follow.bmp" ); else if ( m_orders == OrderFollow && m_absorb ) texId = g_app->m_resource->GetTexture( "icons/banner_absorb.bmp" ); m_flag.SetTexture( texId ); m_flag.SetPosition( flagPos ); m_flag.SetOrientation( front, up ); m_flag.SetSize( size ); m_flag.Render(); }
bool PhysicsSystem::PointInConvexPolygon(const Vector3 testPosition, Vector3 * convexShapePoints, int numPointsL) const { //Check if our test point is inside our convex shape. for(int i =0; i<numPointsL; ++i){ const int i0 = i; const int i1 = (i+1) % numPointsL; const Vector3& p0 = convexShapePoints[i0]; const Vector3& p1 = convexShapePoints[i1]; //Required things - a point on the edge and the normal. Vector3 normal = p0 - p1; normal.Normalise(); const Vector3 n = Vector3::Cross(Vector3(0,0,1), normal); //Using the point equation to calculate d and determine if our point //is on the positive or negative side of the plane (edge). const float d = Vector3::Dot( n, p0); //Calculate whihc side out test points is.. //+ve = inside ; -ve = outside; 0 = on plane. const float s = d - Vector3::Dot(n, testPosition); if(s < 0.0f) { //Failed - so skip rest of the test. return false; } } return true; }
Vector3 Math::CalculateTriangleNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3) { Vector3 vec1 = v2 - v1; Vector3 vec2 = v3 - v1; Vector3 normal = vec1.crossProduct(vec2); return normal.Normalise(); }
Vector3 Vector3::UnitCross( const Vector3& other ) const { Vector3 cross = Vector3( y * other.z - z * other.y, z * other.x - x * other.z, x * other.y - y * other.x); cross.Normalise(); return cross; }
void CurrencyOrb::DoTrackPlayer(float delta) { mSineWaveProps.DoSineWave = false; Player * player = GameObjectManager::Instance()->GetPlayer(); if (!player) { return; } // accelerate towards the target Vector3 direction = Vector3(player->CollisionCentreX(), player->CollisionCentreY(), player->Z()) - m_position; direction.Normalise(); m_direction = direction; float multiplier = mTimeTracking > 2.0f ? 3.0f : 1.0f; bool prioritiseX = false; if (std::abs(m_direction.X) > std::abs(m_direction.Y)) { AccelerateX(m_direction.X, kAccelerateRate * multiplier); prioritiseX = true; } else { AccelerateY(m_direction.Y, kAccelerateRate * multiplier); } if (prioritiseX && ((m_direction.X < 0 && m_velocity.X > 0) || (m_direction.X > 0 && m_velocity.X < 0))) { // the velocity of the orb is still moving in the opposite x direction // let's give it a helping hand to catch up by accelerating harshly AccelerateX(m_direction.X, kHarshAccelerateRate * multiplier); } if (!prioritiseX && ((m_direction.Y < 0 && m_velocity.Y > 0) || (m_direction.Y > 0 && m_velocity.Y < 0))) { // the velocity of the orb is still moving in the opposite y direction // let's give it a helping hand to catch up by accelerating harshly AccelerateY(m_direction.Y, kHarshAccelerateRate * multiplier); } Vector2 dir = Vector2(m_velocity.X, m_velocity.Y); dir.Normalise(); if (dir.X > 0) { SetRotationAngle(-acos(dir.Dot(Vector2(0, -1)))); } else { SetRotationAngle(acos(dir.Dot(Vector2(0, -1)))); } }
void Matrix34::OrientRU( Vector3 const & _r, Vector3 const & _u ) { Vector3 tr = _r; tr.Normalise(); f = tr ^ _u; r = tr; f.Normalise(); u = f ^ r; }
void Matrix34::OrientRF( Vector3 const & _r, Vector3 const & _f ) { Vector3 tr = _r; tr.Normalise(); u = _f ^ tr; r = tr; u.Normalise(); f = r ^ u; }
void Matrix34::OrientUF( Vector3 const & _u, Vector3 const & _f ) { Vector3 tu = _u; tu.Normalise(); r = tu ^ _f; u = tu; r.Normalise(); f = r ^ u; }
void Matrix34::OrientUR( Vector3 const & _u, Vector3 const & _r ) { Vector3 tu = _u; tu.Normalise(); f = _r ^ tu; u = tu; f.Normalise(); r = u ^ f; }
void Matrix34::OrientFR( Vector3 const & _f, Vector3 const & _r ) { Vector3 tf = _f; tf.Normalise(); u = tf ^ _r; f = tf; u.Normalise(); r = u ^ f; }
void Matrix34::OrientFU( Vector3 const & _f, Vector3 const & _u ) { Vector3 tf = _f; tf.Normalise(); r = _u ^ tf; f = tf; r.Normalise(); u = f ^ r; }
void SphereCollisionShape::GetLocalCollisionAxes(PhysicsObject* currentObject, PhysicsObject* collidingObject, std::vector<Vector3>* out_axes) { if (out_axes) { //Only one axis of collision for a sphere Vector3 ab = collidingObject->GetPosition() - currentObject->GetPosition(); ab.Normalise(); out_axes->push_back(ab); } }
Quaternion Vector3::GetRotationTo(Vector3 dest, Vector3 fallbackAxis) { // Based on Stan Melax's article in Game Programming Gems Quaternion q; // Copy, since cannot modify local Vector3 v0 = *this; Vector3 v1 = dest; v0.Normalise(); v1.Normalise(); Real d = v0.DotProduct(v1); // If dot == 1, vectors are the same if (d >= 1.0f) { return Quaternion::IDENTITY; } // sometimes the dot product yields -1.0000001 // floating point math does that to you if (d < -1.0f) d = -1.0f; Real s = Math::Sqrt( (1+d)*2 ); if (s < 1e-6f) { if (fallbackAxis != Vector3::ZERO) { // rotate 180 degrees about the fallback axis q.FromAngleAxis(Radian(Math::PI), fallbackAxis); } else { // Generate an axis Vector3 axis = Vector3::UNIT_X.CrossProduct(*this); if (axis.IsZeroLength) // pick another if colinear axis = Vector3::UNIT_Y.CrossProduct(*this); axis.Normalise(); q.FromAngleAxis(Radian(Math::PI), axis); } } else { Real invs = 1 / s; Vector3 c = v0.CrossProduct(v1); q.x = c.x * invs; q.y = c.y * invs; q.z = c.z * invs; q.w = s * 0.5; q.Normalise(); } return q; }
void PhysicsSystem::EnemyFire(EnemyEntity* ee) { LaserEntity* le = findInactiveLaser(); le->Activate(ee->GetPhysicsNode().GetPosition()); Vector3 temp = player->GetPhysicsNode().GetPosition() - le->GetPhysicsNode().GetPosition(); temp.Normalise(); temp = temp * 10; le->GetPhysicsNode().SetLinearVelocity(temp); }
void Triangle::SetTriangle(Vector3 v0, Vector3 v1, Vector3 v2) { m_vertices[0] = v0; m_vertices[1] = v1; m_vertices[2] = v2; //Calculate Normal Vector3 NormalA = m_vertices[1] - m_vertices[0]; Vector3 NormalB = m_vertices[2] - m_vertices[0]; Vector3 Norm = NormalA.CrossProduct(NormalB); Norm.Normalise(); m_normal = Norm; }
void ZMO::CreateCameraMatrices(Array<Matrix4>& matrices) const { Vector3* eye = (Vector3*)mChannels[0].mData; Vector3* target = (Vector3*)mChannels[1].mData; Vector3* up = (Vector3*)mChannels[2].mData; Vector3 trans = Vector3(5200.0f, 5200.0f, 0.0f); matrices.SetSize(mFrameCount); for(unsigned int i = 0; i < mFrameCount; ++i){ Vector3 e = eye[i] + trans; Vector3 t = target[i] + trans; Vector3 u = up[i] * 100.0f; u.Normalise(); matrices[i] = Matrix4::CreateLookAtRH(e, t, up[i]); } }