void R3DCamera::Rotate(float angle, float x, float y, float z) { // Get direction vector T_GLVector3f vecDir, vecNew; Vec3fSub(&vecDir, this->vLookAt, this->vEye); // Compute sin and cos of the angle float sinAng = (float)sin(angle); float cosAng = (float)cos(angle); // Compute new x position vecNew.x = (cosAng + (1 - cosAng) * x * x) * vecDir.x; vecNew.x += ((1 - cosAng) * x * y - z * sinAng) * vecDir.y; vecNew.x += ((1 - cosAng) * x * z + y * sinAng) * vecDir.z; // Compute new y position vecNew.y = ((1 - cosAng) * x * y + z * sinAng) * vecDir.x; vecNew.y += (cosAng + (1 - cosAng) * y * y) * vecDir.y; vecNew.z += ((1 - cosAng) * y * z - x * sinAng) * vecDir.z; // Compute new z position vecNew.z = ((1 - cosAng) * x * z - y * sinAng) * vecDir.x; vecNew.z += ((1 - cosAng) * y * z + x * sinAng) * vecDir.y; vecNew.z += (cosAng + (1 - cosAng) * z * z) * vecDir.z; // Compute new rotated look at vector Vec3fAdd(&this->vLookAt, this->vEye, vecNew); }
void CTrackingMissile::Update(void) { CQuaternion q; float t; m_Age = g_time - m_CreationTime; if(m_Age > m_LifeTime) { Die(); return; } if (!m_Tracking) { if (m_Age <= 0.4f) { if (m_FlyLeft) m_RenderObj.MoveRight(-20.0f * g_FrameTime, 0); else m_RenderObj.MoveRight(20.0f * g_FrameTime, 0); t = m_Age; QuatSlerp(&q, &m_Q0, &m_Q1, t * 2.5f); m_RenderObj.GetFrame(0)->SetOrientation(&q); } else if (m_Age <= 0.8f && !m_Target) { t = m_Age - 0.4f; QuatSlerp(&q, &m_Q1, &m_Q2, t * 2.5f); m_RenderObj.GetFrame(0)->SetOrientation(&q); } else { m_Tracking = true; m_RenderObj.GetFrame(0)->GetOrientation(&m_Q0); m_Q1 = m_Q0; m_Velocity = 120.0f; m_LastUpdate = g_time - m_UpdatePeriod; } } else { if (m_Target) { if (m_Target->IsActive()) { t = g_time - m_LastUpdate; if (t >= m_UpdatePeriod) { CVector3f oldfwd, newfwd, tpos, pos, lead(0.0f, 0.0f, 0.0f); m_Q0 = m_Q1; // Find new orientation, lead target a little m_RenderObj.GetFrame(0)->GetForward(&oldfwd); m_Target->GetPosition(&tpos, 0); m_Target->GetVelocity(&lead); Vec3fScale(&lead, &lead, m_UpdatePeriod); Vec3fAdd(&tpos, &tpos, &lead); GetPosition(&pos, 0); Vec3fSubtract(&newfwd, &tpos, &pos); Vec3fNormalize(&newfwd, &newfwd); QuatRotationArc(&q, &oldfwd, &newfwd); QuatCrossProduct(&m_Q1, &q, &m_Q1); m_LastUpdate += m_UpdatePeriod; t = g_time - m_LastUpdate; } QuatSlerp(&q, &m_Q0, &m_Q1, t * m_SlerpScale); m_RenderObj.GetFrame(0)->SetOrientation(&q); } else m_Target = 0; } } // Move the shot forward MoveForward(m_Velocity * g_FrameTime, 0); // Update the ambient sound GetPosition(&m_CurPosition, 0); CVector3f Velocity; Velocity.x = (m_CurPosition.x - m_LastPosition.x) / g_FrameTime; Velocity.y = (m_CurPosition.y - m_LastPosition.y) / g_FrameTime; Velocity.z = (m_CurPosition.z - m_LastPosition.z) / g_FrameTime; m_MissileInAir->UpdateSound(m_CurPosition, Velocity); m_LastPosition = m_CurPosition; CGameObject::Update(); }