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;
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);
System integration layer; inspired by OgreBites::ApplicationContext.
#define ROR_ASSERT(_EXPR)
static const int DEFAULT_INTERNAL_CAM_PITCH
static const int SPLINECAM_DRAW_RESOLUTION
static const float TRANS_SPEED
static const Ogre::Vector3 CHARACTERCAM_OFFSET_3RD_PERSON(0.0f, 1.1f, 0.0f)
static const float ROTATE_SPEED
bool intersectsTerrain(Vector3 a, Vector3 b)
static const Ogre::Vector3 CHARACTERCAM_OFFSET_1ST_PERSON(0.0f, 1.82f, 0.0f)
Game state manager and message-queue provider.
NodeNum_t ar_custom_camera_node
Sim state; custom tracking node for 3rd-person camera.
NodeNum_t ar_camera_node_dir[MAX_CAMERAS]
Physics attr; 'camera' = frame of reference; back node.
void prepareInside(bool inside)
Prepares vehicle for in-cabin camera use.
bool ar_camera_node_roll_inv[MAX_CAMERAS]
Physics attr; 'camera' = frame of reference; indicates roll node is right instead of left.
void NotifyActorCameraChanged()
Logic: sound, display; Notify this vehicle that camera changed;.
CineCameraID_t ar_current_cinecam
Sim state; index of current CineCam (CINECAMERAID_INVALID if using 3rd-person camera)
NodeNum_t ar_camera_node_roll[MAX_CAMERAS]
Physics attr; 'camera' = frame of reference; left node.
Ogre::Vector3 getPosition()
NodeNum_t ar_camera_rail[MAX_CAMERARAIL]
Nodes defining camera-movement spline.
Ogre::Vector3 getDirection()
average actor velocity, calculated using the actor positions of the last two frames
bool isBeingReset() const
PerVehicleCameraContext ar_camera_context
ActorPtrVec ar_linked_actors
BEWARE: Includes indirect links, see DetermineLinkedActors(); Other actors linked using 'hooks/ties/r...
NodeNum_t ar_camera_node_pos[MAX_CAMERAS]
Physics attr; 'camera' = frame of reference; origin node.
int ar_num_cinecams
Sim attr;.
Ogre::Real getMinimalCameraRadius()
float getMinCameraRadius()
CineCameraID_t ar_forced_cinecam
Sim state; index of CineCam forced by script (CINECAMERAID_INVALID if not forced)
NodeNum_t ar_cinecam_node[MAX_CAMERAS]
Sim attr; Cine-camera node indexes.
ActorType ar_driveable
Sim attr; marks vehicle type and features.
float GetSimulationSpeed() const
Ogre::Viewport * GetViewport()
Quake-style console variable, defined in RoR.cfg or crated via Console UI and scripts.
bool CameraBehaviorVehicleMousePressed()
Ogre::Radian m_cam_target_direction
void UpdateCameraBehaviorStatic()
void NotifyContextChange()
Ogre::Degree m_cct_rot_scale
ActorPtr m_cct_player_actor
CameraBehaviors m_current_behavior
void ActivateNewBehavior(CameraBehaviors new_behavior, bool reset)
Ogre::ManualObject * m_splinecam_mo
void CameraBehaviorVehicleSplineCreateSpline()
void UpdateCameraBehaviorFree()
Ogre::Radian m_staticcam_previous_fov
bool EvaluateSwitchBehavior()
std::deque< node_t * > m_splinecam_spline_nodes
Ogre::Vector3 m_staticcam_position
void CameraBehaviorVehicleSplineReset()
Ogre::Vector3 m_cam_look_at_smooth
CameraBehaviors m_cam_before_toggled
Toggled modes (FREE, FREEFIX) remember original state.
unsigned int m_splinecam_num_linked_beams
bool m_splinecam_auto_tracking
void UpdateCameraBehaviorFixed()
void ReCreateCameraNode()
Needed since we call Ogre::SceneManager::ClearScene() after end of sim. session.
Ogre::Vector3 m_cam_look_at_last
float m_staticcam_fov_exponent
void DeactivateCurrentBehavior()
void CameraBehaviorOrbitUpdate()
bool CameraBehaviorStaticMouseMoved()
void NotifyVehicleChanged(ActorPtr new_vehicle)
void UpdateInputEvents(float dt)
bool CameraBehaviorVehicleSplineMouseMoved()
Ogre::Real m_splinecam_spline_len
CameraBehaviors m_prev_toggled_cam
Switching toggled modes (FREE, FREEFIX) keeps 1-slot history.
void UpdateCurrentBehavior()
Ogre::SceneNode * GetCameraNode()
@ CAMERA_BEHAVIOR_ISOMETRIC
@ CAMERA_BEHAVIOR_INVALID
@ CAMERA_BEHAVIOR_VEHICLE_SPLINE
@ CAMERA_BEHAVIOR_CHARACTER
@ CAMERA_BEHAVIOR_VEHICLE
@ CAMERA_BEHAVIOR_VEHICLE_CINECAM
Ogre::Real m_cct_trans_scale
void switchToNextBehavior()
void switchBehavior(CameraBehaviors new_behavior)
bool m_splinecam_spline_closed
void SwitchBehaviorOnVehicleChange(CameraBehaviors new_behavior, ActorPtr new_vehicle)
void CameraBehaviorVehicleReset()
bool handleMousePressed()
bool m_charactercam_is_3rdperson
void CameraBehaviorVehicleSplineUpdateSpline()
CameraBehaviors GetCurrentBehavior() const
void UpdateCameraBehaviorVehicle()
Ogre::SimpleSpline * m_splinecam_spline
Ogre::Vector3 m_cam_look_at_smooth_last
Ogre::Camera * GetCamera()
void CameraBehaviorOrbitReset()
bool CameraBehaviorOrbitMouseMoved()
Ogre::Radian m_cam_target_pitch
void CameraBehaviorVehicleSplineUpdate()
bool m_cam_limit_movement
void CameraBehaviorVehicleSplineUpdateSplineDisplay()
Ogre::Vector3 m_cam_look_at
void ResetCurrentBehavior()
void ToggleCameraBehavior(CameraBehaviors new_behavior)
Only accepts FREE and FREEFIX modes.
Ogre::Timer m_staticcam_update_timer
bool m_staticcam_force_update
Ogre::Real m_splinecam_spline_pos
Ogre::Vector3 m_staticcam_look_at
Ogre::SceneNode * m_camera_node
Ogre::Vector3 getPosition()
void setRotation(Ogre::Radian rotation)
Ogre::Radian getRotation() const
std::pair< bool, Ogre::Real > intersectsTris(Ogre::Ray ray)
@ CONSOLE_MSGTYPE_INFO
Generic message.
void putMessage(MessageArea area, MessageType type, std::string const &msg, std::string icon="")
@ HIDDEN
Hidden as inactive, will re-appear the moment user moves mouse.
void SetMouseCursorVisibility(MouseCursorVisibility visi)
Character * GetPlayerCharacter()
const ActorPtr & GetPlayerActor()
const TerrainPtr & GetTerrain()
ActorManager * GetActorManager()
Ogre::SceneManager * GetSceneManager()
void showDashboardOverlays(bool show, ActorPtr actor)
float getPrecision() const
Wrapper for classic c-string (local buffer) Refresher: strlen() excludes '\0' terminator; strncat() A...
const char * ToCStr() const
float getHeightAt(float x, float z)
Collisions * GetCollisions()
float GetStaticWaterHeight()
Returns static water level configured in 'terrn2'.
@ EDITOR_MODE
Hacky, but whatever... added by Ulteq, 2016.
@ AIRPLANE
its an airplane
AppContext * GetAppContext()
CVar * gfx_static_cam_fov_exp
OverlayWrapper * GetOverlayWrapper()
InputEngine * GetInputEngine()
CVar * io_invert_orbitcam
CVar * gfx_fov_internal_default
CameraManager * GetCameraManager()
GUIManager * GetGuiManager()
GameContext * GetGameContext()
CVar * gfx_fov_external_default
CVar * gfx_fixed_cam_tracking
static const NodeNum_t NODENUM_INVALID
static const CineCameraID_t CINECAMERAID_INVALID
uint16_t NodeNum_t
Node position within Actor::ar_nodes; use RoR::NODENUM_INVALID as empty value.
CameraCtxBehavior behavior
@ CAMCTX_BEHAVIOR_VEHICLE_3rdPERSON
@ CAMCTX_BEHAVIOR_VEHICLE_SPLINE
@ CAMCTX_BEHAVIOR_VEHICLE_CINECAM
@ CAMCTX_BEHAVIOR_EXTERNAL
Ogre::Vector3 AbsPosition
absolute position in the world (shaky)