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);