static void chaseInterpolate( int time, float timeFraction, vec3_t origin, vec3_t angles, float *distance, int *target ) { float lerp; int times[4]; vec4_t origins[4], pr; Quat_t quats[4], qr; demoChasePoint_t *point = chasePointSynch( time ); if (!point->next) { VectorCopy( point->origin, origin ); VectorCopy( point->angles, angles ); *distance = point->distance; *target = point->target; return; } chasePointControl( point, times, origins, quats ); lerp = ((time - point->time) + timeFraction) / (point->next->time - point->time); QuatTimeSpline( lerp, times, quats, qr ); VectorTimeSpline( lerp, times, (float *)origins, (float *)pr,4 ); /* Copy the results */ VectorCopy( pr, demo.chase.origin ); demo.chase.target = point->target; demo.chase.distance = pr[3]; QuatToAngles( qr, demo.chase.angles ); }
static void demoEffectAnglesAt( demoEffectParent_t *parent, int time, float timeFraction, vec3_t angles ) { demoEffectPoint_t *match[4]; Quat_t quats[4], qr; int times[4]; vec3_t tempAngles; float lerp; demoEffectMatchAt( parent->points, time, EFFECT_ANGLES, match ); if (!match[1] ) { if ( match[0] ) { VectorCopy( match[0]->angles, angles ); } else if ( match[2] ) { VectorCopy( match[2]->angles, angles ); } else { VectorCopy( parent->angles, angles ); } return; } else if (!match[2] ) { VectorCopy( match[1]->angles, angles ); return; } QuatFromAngles( match[1]->angles, quats[1] ); QuatFromAnglesClosest( match[2]->angles, quats[1], quats[2] ); if (!match[0]) { VectorSubtract( match[2]->angles, match[1]->angles, tempAngles ); VectorAdd( tempAngles, match[1]->angles, tempAngles ); QuatFromAnglesClosest( tempAngles, quats[1], quats[0] ); } else { QuatFromAnglesClosest( match[0]->angles, quats[1], quats[0] ); } if (!match[3]) { VectorSubtract( match[2]->angles, match[1]->angles, tempAngles ); VectorAdd( tempAngles, match[2]->angles, tempAngles ); QuatFromAnglesClosest( tempAngles, quats[2], quats[3] ); } else { QuatFromAnglesClosest( match[3]->angles, quats[2], quats[3] ); } demoEffectMatchTimes( match, times ); lerp = ((time - times[1]) + timeFraction) / (times[2] - times[1]); QuatTimeSpline( lerp, times, quats, qr ); QuatToAngles( qr, angles ); }
Vec3 TurretComponent::AbsoluteAnglesToRelativeAngles(const Vec3 absoluteAngles) const { quat_t torsoRotation; quat_t absoluteRotation; quat_t relativeRotation; vec3_t relativeAngles; AnglesToQuat(TorsoAngles().Data(), torsoRotation); AnglesToQuat(absoluteAngles.Data(), absoluteRotation); // This is the inverse of RelativeAnglesToAbsoluteAngles. See the comment there for details. quat_t inverseTorsoOrientation; QuatCopy(torsoRotation, inverseTorsoOrientation); QuatInverse(inverseTorsoOrientation); QuatMultiply(inverseTorsoOrientation, absoluteRotation, relativeRotation); QuatToAngles(relativeRotation, relativeAngles); /*turretLogger.Debug("AbsoluteAnglesToRelativeAngles: %s → %s. Torso angles: %s.", Utility::Print(absoluteAngles), Utility::Print(Vec3::Load(relativeAngles)), TorsoAngles() );*/ return Vec3::Load(relativeAngles); }
Vec3 TurretComponent::RelativeAnglesToAbsoluteAngles(const Vec3 relativeAngles) const { quat_t torsoRotation; quat_t relativeRotation; quat_t absoluteRotation; vec3_t absoluteAngles; AnglesToQuat(TorsoAngles().Data(), torsoRotation); AnglesToQuat(relativeAngles.Data(), relativeRotation); // Rotate by torso rotation in world space, then by relative orientation in torso space. // This is equivalent to rotating by relative orientation in world space, then by torso rotation // in world space. This then is equivalent to multiplying the torso rotation in world space on // the left hand side and the relative rotation in world space on the right hand side. QuatMultiply(torsoRotation, relativeRotation, absoluteRotation); QuatToAngles(absoluteRotation, absoluteAngles); /*turretLogger.Debug("RelativeAnglesToAbsoluteAngles: %s → %s. Torso angles: %s.", Utility::Print(relativeAngles), Utility::Print(Vec3::Load(absoluteAngles)), TorsoAngles() );*/ return Vec3::Load(absoluteAngles); }