void CInterpolation::Interpolate(float t, vec3_t &point, vec3_t &angle, float *fov) { if(m_SmoothStart && m_SmoothEnd) { t = (1.0f - t) * (t * t) + t * (1.0f - ((t - 1.0f) * (t - 1.0f))); } else if(m_SmoothStart) { t = t * t; } else if(m_SmoothEnd) { t = t - 1.0f; t = -(t * t) + 1; } if(point) { BezierInterpolatePoint(t, point); } if(angle) { InterpolateAngle(t, angle); } if(fov) { *fov = m_StartFov + (t * (m_EndFov - m_StartFov)); } }
// Bone and Frame (positions, angles) -> Transform Matrix static void FindFrameTransform(Model3D_Transform& T, Model3D_Frame& Frame, GLfloat MixFrac, Model3D_Frame& AddlFrame) { T.Identity(); // First, do rotations: short Angle; // Right-to-left; in the right order for Dim3 (and Tomb Raider) // Z: Angle = InterpolateAngle(Frame.Angles[2],MixFrac,AddlFrame.Angles[2]); if (Angle != 0) { GLfloat C = TrigNorm*cosine_table[Angle]; GLfloat S = TrigNorm*sine_table[Angle]; for (int ic=0; ic<3; ic++) { GLfloat X = T.M[0][ic]; GLfloat Y = T.M[1][ic]; GLfloat XR = X*C - Y*S; GLfloat YR = X*S + Y*C; T.M[0][ic] = XR; T.M[1][ic] = YR; } } // X: Angle = InterpolateAngle(Frame.Angles[0],MixFrac,AddlFrame.Angles[0]); if (Angle != 0) { GLfloat C = TrigNorm*cosine_table[Angle]; GLfloat S = TrigNorm*sine_table[Angle]; for (int ic=0; ic<3; ic++) { GLfloat X = T.M[1][ic]; GLfloat Y = T.M[2][ic]; GLfloat XR = X*C - Y*S; GLfloat YR = X*S + Y*C; T.M[1][ic] = XR; T.M[2][ic] = YR; } } // Y: Angle = InterpolateAngle(Frame.Angles[1],MixFrac,AddlFrame.Angles[1]); if (Angle != 0) { GLfloat C = TrigNorm*cosine_table[Angle]; GLfloat S = TrigNorm*sine_table[Angle]; for (int ic=0; ic<3; ic++) { GLfloat X = T.M[2][ic]; GLfloat Y = T.M[0][ic]; GLfloat XR = X*C - Y*S; GLfloat YR = X*S + Y*C; T.M[2][ic] = XR; T.M[0][ic] = YR; } } // Set up overall translate: GLfloat *FrameOfst = Frame.Offset; if (MixFrac != 0) { GLfloat *AddlFrameOfst = AddlFrame.Offset; for (int ic=0; ic<3; ic++) T.M[ic][3] = FrameOfst[ic] + MixFrac*(AddlFrameOfst[ic]-FrameOfst[ic]); } else { for (int ic=0; ic<3; ic++) T.M[ic][3] = FrameOfst[ic]; } }