56     int steps = std::max(3.0f, a.distance(b) * 2.0f);
 
   57     for (
int i = 1; i < steps; i++)
 
   59         Vector3 pos = a + (b - a) * (
float)i / steps;
 
   71     int steps = std::max(3.0f, start.distance(end) * (6.0f / interval));
 
   72     for (
int i = 0; i <= steps; i++)
 
   74         Vector3 b = start + (end - start) * (
float)i / steps;
 
   83 CameraManager::CameraManager() :
 
   84       m_current_behavior(CAMERA_BEHAVIOR_INVALID)
 
   86     , m_cct_trans_scale(1.0f)
 
   87     , m_cct_sim_speed(1.0f)
 
   88     , m_cam_before_toggled(CAMERA_BEHAVIOR_INVALID)
 
   89     , m_prev_toggled_cam(CAMERA_BEHAVIOR_INVALID)
 
   90     , m_charactercam_is_3rdperson(true)
 
   91     , m_splinecam_num_linked_beams(0)
 
   92     , m_splinecam_auto_tracking(false)
 
   93     , m_splinecam_spline(new SimpleSpline())
 
   94     , m_splinecam_spline_closed(false)
 
   95     , m_splinecam_spline_len(1.0f)
 
   97     , m_splinecam_spline_pos(0.5f)
 
   98     , m_staticcam_force_update(false)
 
   99     , m_staticcam_fov_exponent(1.0f)
 
  103     , m_cam_dist_min(0.f)
 
  104     , m_cam_dist_max(0.f)
 
  105     , m_cam_target_direction(0.f)
 
  106     , m_cam_target_pitch(0.f)
 
  108     , m_cam_look_at(
Ogre::Vector3::ZERO)
 
  109     , m_cam_look_at_last(
Ogre::Vector3::ZERO)
 
  110     , m_cam_look_at_smooth(
Ogre::Vector3::ZERO)
 
  111     , m_cam_look_at_smooth_last(
Ogre::Vector3::ZERO)
 
  112     , m_cam_limit_movement(true)
 
  113     , m_camera_node(nullptr)
 
  182     default:                              
return false;
 
  225         Vector3 up = dir.crossProduct(roll);
 
  226         roll = up.crossProduct(dir);
 
  228         Quaternion orientation = Quaternion(
m_cam_rot_x, up) * Quaternion(Degree(180.0) + 
m_cam_rot_y, roll) * Quaternion(roll, up, dir);
 
  304             fov = cvar_fov->
getInt() + modifier;
 
  305             if (fov >= 10 && fov <= 160)
 
  390     switch (new_behavior)
 
  565             angle += Degree(ms.X.rel * 0.13f);
 
  596     default:                              
return false;
 
  606     if (ms.buttonDown(OIS::MB_Right) && ms.buttonDown(OIS::MB_Middle))
 
  622     default:                              
return false;
 
  645     if (new_vehicle == 
nullptr)
 
  714     Vector3 velocity = Vector3::ZERO;
 
  715     Radian angle = Degree(90);
 
  732         speed = velocity.normalise();
 
  749         Vector3 lookAtPrediction = lookAt + velocity * speed;
 
  751         float interval = std::max(radius, speed);
 
  755                (distance > cmradius * 8.0f && angle < Degree(30)) ||
 
  756                (distance < cmradius * 2.0f && angle > Degree(150)) ||
 
  757                 distance > cmradius * std::max(25.0f, speed * 1.15f) ||
 
  761             float water_height = (water && !water->IsUnderWater(lookAt)) ? water->
GetStaticWaterHeight() : 0.0f;
 
  764             std::vector<std::pair<float, Vector3>> viable_positions;
 
  765             for (
int i = 0; i < 10; i++)
 
  767                 Vector3 pos = lookAt;
 
  770                     float angle = Math::TWO_PI * 
frand();
 
  771                     pos += Vector3(cos(angle), 0, sin(angle)) * cmradius * 2.5f;
 
  775                     float dist = std::max(cmradius * 2.5f, std::sqrt(cmradius) * speed);
 
  776                     float mrnd = Math::Clamp(0.6f * cmradius / dist, 0.0f, 0.3f);
 
  777                     float arnd = mrnd + 
frand() * (1.0f - mrnd);
 
  778                     float  rnd = 
frand() > 0.5f ? arnd : -arnd;
 
  779                     pos += (velocity + velocity.crossProduct(Vector3::UNIT_Y) * rnd) * dist;
 
  781                 pos.y = std::max(pos.y, water_height);
 
  783                 pos.y += desired_offset * (i < 7 ? 1.0f : 
frand());
 
  786                     float hdiff = std::abs(pos.y - lookAt.y - desired_offset);
 
  787                     viable_positions.push_back({hdiff, pos});
 
  788                     if (hdiff < 1.0f || viable_positions.size() > 2)
 
  792             if (!viable_positions.empty())
 
  794                 std::sort(viable_positions.begin(), viable_positions.end());
 
  806     float fov = atan2(20.0f, std::pow(camDist, fovExp));
 
  819     if (ms.buttonDown(OIS::MB_Right))
 
  914         desiredPosition.y = std::max(h, desiredPosition.y);
 
  932     Vector3 precedingPosition = this->
GetCameraNode()->getPosition() + camDisplacement;
 
  962     if (ms.buttonDown(OIS::MB_Right))
 
  998     Vector3 mTrans(Vector3::ZERO);
 
 1003         cct_rot_scale *= 3.0f;
 
 1004         cct_trans_scale *= 5.0f;
 
 1008         cct_rot_scale *= 6.0f;
 
 1009         cct_trans_scale *= 10.0f;
 
 1013         cct_rot_scale *= 0.2f;
 
 1014         cct_trans_scale *= 0.2f;
 
 1019         mTrans.x -= cct_trans_scale;
 
 1023         mTrans.x += cct_trans_scale;
 
 1027         mTrans.z -= cct_trans_scale;
 
 1031         mTrans.z += cct_trans_scale;
 
 1035         mTrans.y += cct_trans_scale;
 
 1039         mTrans.y -= cct_trans_scale;
 
 1044         mRotX -= cct_rot_scale;
 
 1048         mRotX += cct_rot_scale;
 
 1052         mRotY += cct_rot_scale;
 
 1056         mRotY -= cct_rot_scale;
 
 1062     Vector3 camPosition = this->
GetCameraNode()->getPosition() + this->
GetCameraNode()->getOrientation() * mTrans.normalisedCopy() * cct_trans_scale;
 
 1120             Vector3 camDir = (this->
GetCameraNode()->getPosition() - lookAt).normalisedCopy();
 
 1125             Quaternion rotX = dir.getRotationTo(camDir, Vector3::UNIT_Y);
 
 1129             Radian angle = dir.angleBetween(camDir);
 
 1130             if ( angle > Radian(Math::HALF_PI) )
 
 1132                 if ( std::abs(Radian(
m_cam_rot_x).valueRadians()) < Math::HALF_PI )
 
 1188         if (centerDir.length() > 1.0f)
 
 1190             centerDir.normalise();
 
 1192             m_cam_target_direction = -atan2(centerDir.dotProduct(Vector3::UNIT_X), centerDir.dotProduct(-Vector3::UNIT_Z));
 
 1217             splinePosDiff *= 3.0f;
 
 1222             splinePosDiff *= 0.1f;
 
 1289         for (
ActorPtr& actor : linkedBeams)
 
 1291             if (actor->ar_num_camera_rails <= 0)
 
 1297             Vector3 linkedSplineFront = actor->ar_nodes[actor->ar_camera_rail[0]].AbsPosition;
 
 1298             Vector3 linkedSplineBack = actor->ar_nodes[actor->ar_camera_rail[actor->ar_num_camera_rails - 1]].AbsPosition;
 
 1300             if (curSplineBack.distance(linkedSplineFront) < 5.0f)
 
 1302                 for (
int i = 1; i < actor->ar_num_camera_rails; i++)
 
 1307             else if (curSplineFront.distance(linkedSplineFront) < 5.0f)
 
 1309                 for (
int i = 1; i < actor->ar_num_camera_rails; i++)
 
 1314             else if (curSplineBack.distance(linkedSplineBack) < 5.0f)
 
 1316                 for (
int i = actor->ar_num_camera_rails - 2; i >= 0; i--)
 
 1321             else if (curSplineFront.distance(linkedSplineBack) < 5.0f)
 
 1323                 for (
int i = actor->ar_num_camera_rails - 2; i >= 0; i--)
 
 1339     if (firstPoint.distance(lastPoint) < 1.0f)
 
 1356         m_splinecam_mo->begin(
"tracks/transred", Ogre::RenderOperation::OT_LINE_STRIP);