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);
295 fov = cvar_fov->
getInt() + modifier;
296 if (fov >= 10 && fov <= 160)
381 switch (new_behavior)
556 angle += Degree(ms.X.rel * 0.13f);
587 default:
return false;
597 if (ms.buttonDown(OIS::MB_Right) && ms.buttonDown(OIS::MB_Middle))
613 default:
return false;
636 if (new_vehicle ==
nullptr)
705 Vector3 velocity = Vector3::ZERO;
706 Radian angle = Degree(90);
723 speed = velocity.normalise();
740 Vector3 lookAtPrediction = lookAt + velocity * speed;
742 float interval = std::max(radius, speed);
746 (distance > cmradius * 8.0f && angle < Degree(30)) ||
747 (distance < cmradius * 2.0f && angle > Degree(150)) ||
748 distance > cmradius * std::max(25.0f, speed * 1.15f) ||
752 float water_height = (water && !water->IsUnderWater(lookAt)) ? water->
GetStaticWaterHeight() : 0.0f;
755 std::vector<std::pair<float, Vector3>> viable_positions;
756 for (
int i = 0; i < 10; i++)
758 Vector3 pos = lookAt;
761 float angle = Math::TWO_PI *
frand();
762 pos += Vector3(cos(angle), 0, sin(angle)) * cmradius * 2.5f;
766 float dist = std::max(cmradius * 2.5f, std::sqrt(cmradius) * speed);
767 float mrnd = Math::Clamp(0.6f * cmradius / dist, 0.0f, 0.3f);
768 float arnd = mrnd +
frand() * (1.0f - mrnd);
769 float rnd =
frand() > 0.5f ? arnd : -arnd;
770 pos += (velocity + velocity.crossProduct(Vector3::UNIT_Y) * rnd) * dist;
772 pos.y = std::max(pos.y, water_height);
774 pos.y += desired_offset * (i < 7 ? 1.0f :
frand());
777 float hdiff = std::abs(pos.y - lookAt.y - desired_offset);
778 viable_positions.push_back({hdiff, pos});
779 if (hdiff < 1.0f || viable_positions.size() > 2)
783 if (!viable_positions.empty())
785 std::sort(viable_positions.begin(), viable_positions.end());
797 float fov = atan2(20.0f, std::pow(camDist, fovExp));
810 if (ms.buttonDown(OIS::MB_Right))
905 desiredPosition.y = std::max(h, desiredPosition.y);
923 Vector3 precedingPosition = this->
GetCameraNode()->getPosition() + camDisplacement;
953 if (ms.buttonDown(OIS::MB_Right))
989 Vector3 mTrans(Vector3::ZERO);
994 cct_rot_scale *= 3.0f;
995 cct_trans_scale *= 5.0f;
999 cct_rot_scale *= 6.0f;
1000 cct_trans_scale *= 10.0f;
1004 cct_rot_scale *= 0.2f;
1005 cct_trans_scale *= 0.2f;
1010 mTrans.x -= cct_trans_scale;
1014 mTrans.x += cct_trans_scale;
1018 mTrans.z -= cct_trans_scale;
1022 mTrans.z += cct_trans_scale;
1026 mTrans.y += cct_trans_scale;
1030 mTrans.y -= cct_trans_scale;
1035 mRotX -= cct_rot_scale;
1039 mRotX += cct_rot_scale;
1043 mRotY += cct_rot_scale;
1047 mRotY -= cct_rot_scale;
1053 Vector3 camPosition = this->
GetCameraNode()->getPosition() + this->
GetCameraNode()->getOrientation() * mTrans.normalisedCopy() * cct_trans_scale;
1111 Vector3 camDir = (this->
GetCameraNode()->getPosition() - lookAt).normalisedCopy();
1116 Quaternion rotX = dir.getRotationTo(camDir, Vector3::UNIT_Y);
1120 Radian angle = dir.angleBetween(camDir);
1121 if ( angle > Radian(Math::HALF_PI) )
1123 if ( std::abs(Radian(
m_cam_rot_x).valueRadians()) < Math::HALF_PI )
1179 if (centerDir.length() > 1.0f)
1181 centerDir.normalise();
1183 m_cam_target_direction = -atan2(centerDir.dotProduct(Vector3::UNIT_X), centerDir.dotProduct(-Vector3::UNIT_Z));
1208 splinePosDiff *= 3.0f;
1213 splinePosDiff *= 0.1f;
1280 for (
ActorPtr& actor : linkedBeams)
1282 if (actor->ar_num_camera_rails <= 0)
1288 Vector3 linkedSplineFront = actor->ar_nodes[actor->ar_camera_rail[0]].AbsPosition;
1289 Vector3 linkedSplineBack = actor->ar_nodes[actor->ar_camera_rail[actor->ar_num_camera_rails - 1]].AbsPosition;
1291 if (curSplineBack.distance(linkedSplineFront) < 5.0f)
1293 for (
int i = 1; i < actor->ar_num_camera_rails; i++)
1298 else if (curSplineFront.distance(linkedSplineFront) < 5.0f)
1300 for (
int i = 1; i < actor->ar_num_camera_rails; i++)
1305 else if (curSplineBack.distance(linkedSplineBack) < 5.0f)
1307 for (
int i = actor->ar_num_camera_rails - 2; i >= 0; i--)
1312 else if (curSplineFront.distance(linkedSplineBack) < 5.0f)
1314 for (
int i = actor->ar_num_camera_rails - 2; i >= 0; i--)
1330 if (firstPoint.distance(lastPoint) < 1.0f)
1347 m_splinecam_mo->begin(
"tracks/transred", Ogre::RenderOperation::OT_LINE_STRIP);