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)
549 const OIS::MouseState ms = _arg.state;
553 angle += Degree(ms.X.rel * 0.13f);
572 const OIS::MouseState ms = _arg.state;
585 default:
return false;
591 const OIS::MouseState ms = _arg.state;
593 if (ms.buttonDown(OIS::MB_Right) && _id == OIS::MB_Middle)
609 default:
return false;
632 if (new_vehicle ==
nullptr)
701 Vector3 velocity = Vector3::ZERO;
702 Radian angle = Degree(90);
719 speed = velocity.normalise();
736 Vector3 lookAtPrediction = lookAt + velocity * speed;
738 float interval = std::max(radius, speed);
742 (distance > cmradius * 8.0f && angle < Degree(30)) ||
743 (distance < cmradius * 2.0f && angle > Degree(150)) ||
744 distance > cmradius * std::max(25.0f, speed * 1.15f) ||
748 float water_height = (water && !water->IsUnderWater(lookAt)) ? water->
GetStaticWaterHeight() : 0.0f;
751 std::vector<std::pair<float, Vector3>> viable_positions;
752 for (
int i = 0; i < 10; i++)
754 Vector3 pos = lookAt;
757 float angle = Math::TWO_PI *
frand();
758 pos += Vector3(cos(angle), 0, sin(angle)) * cmradius * 2.5f;
762 float dist = std::max(cmradius * 2.5f, std::sqrt(cmradius) * speed);
763 float mrnd = Math::Clamp(0.6f * cmradius / dist, 0.0f, 0.3f);
764 float arnd = mrnd +
frand() * (1.0f - mrnd);
765 float rnd =
frand() > 0.5f ? arnd : -arnd;
766 pos += (velocity + velocity.crossProduct(Vector3::UNIT_Y) * rnd) * dist;
768 pos.y = std::max(pos.y, water_height);
770 pos.y += desired_offset * (i < 7 ? 1.0f :
frand());
773 float hdiff = std::abs(pos.y - lookAt.y - desired_offset);
774 viable_positions.push_back({hdiff, pos});
775 if (hdiff < 1.0f || viable_positions.size() > 2)
779 if (!viable_positions.empty())
781 std::sort(viable_positions.begin(), viable_positions.end());
793 float fov = atan2(20.0f, std::pow(camDist, fovExp));
802 const OIS::MouseState ms = _arg.state;
804 if (ms.buttonDown(OIS::MB_Right))
899 desiredPosition.y = std::max(h, desiredPosition.y);
917 Vector3 precedingPosition = this->
GetCameraNode()->getPosition() + camDisplacement;
943 const OIS::MouseState ms = _arg.state;
945 if (ms.buttonDown(OIS::MB_Right))
981 Vector3 mTrans(Vector3::ZERO);
986 cct_rot_scale *= 3.0f;
987 cct_trans_scale *= 5.0f;
991 cct_rot_scale *= 6.0f;
992 cct_trans_scale *= 10.0f;
996 cct_rot_scale *= 0.2f;
997 cct_trans_scale *= 0.2f;
1002 mTrans.x -= cct_trans_scale;
1006 mTrans.x += cct_trans_scale;
1010 mTrans.z -= cct_trans_scale;
1014 mTrans.z += cct_trans_scale;
1018 mTrans.y += cct_trans_scale;
1022 mTrans.y -= cct_trans_scale;
1027 mRotX -= cct_rot_scale;
1031 mRotX += cct_rot_scale;
1035 mRotY += cct_rot_scale;
1039 mRotY -= cct_rot_scale;
1045 Vector3 camPosition = this->
GetCameraNode()->getPosition() + this->
GetCameraNode()->getOrientation() * mTrans.normalisedCopy() * cct_trans_scale;
1090 const OIS::MouseState ms = _arg.state;
1101 Vector3 camDir = (this->
GetCameraNode()->getPosition() - lookAt).normalisedCopy();
1106 Quaternion rotX = dir.getRotationTo(camDir, Vector3::UNIT_Y);
1110 Radian angle = dir.angleBetween(camDir);
1111 if ( angle > Radian(Math::HALF_PI) )
1113 if ( std::abs(Radian(
m_cam_rot_x).valueRadians()) < Math::HALF_PI )
1169 if (centerDir.length() > 1.0f)
1171 centerDir.normalise();
1173 m_cam_target_direction = -atan2(centerDir.dotProduct(Vector3::UNIT_X), centerDir.dotProduct(-Vector3::UNIT_Z));
1186 const OIS::MouseState ms = _arg.state;
1196 splinePosDiff *= 3.0f;
1201 splinePosDiff *= 0.1f;
1268 for (
ActorPtr& actor : linkedBeams)
1270 if (actor->ar_num_camera_rails <= 0)
1276 Vector3 linkedSplineFront = actor->ar_nodes[actor->ar_camera_rail[0]].AbsPosition;
1277 Vector3 linkedSplineBack = actor->ar_nodes[actor->ar_camera_rail[actor->ar_num_camera_rails - 1]].AbsPosition;
1279 if (curSplineBack.distance(linkedSplineFront) < 5.0f)
1281 for (
int i = 1; i < actor->ar_num_camera_rails; i++)
1286 else if (curSplineFront.distance(linkedSplineFront) < 5.0f)
1288 for (
int i = 1; i < actor->ar_num_camera_rails; i++)
1293 else if (curSplineBack.distance(linkedSplineBack) < 5.0f)
1295 for (
int i = actor->ar_num_camera_rails - 2; i >= 0; i--)
1300 else if (curSplineFront.distance(linkedSplineBack) < 5.0f)
1302 for (
int i = actor->ar_num_camera_rails - 2; i >= 0; i--)
1318 if (firstPoint.distance(lastPoint) < 1.0f)
1335 m_splinecam_mo->begin(
"tracks/transred", Ogre::RenderOperation::OT_LINE_STRIP);