Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
CameraManager.cpp
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2005-2012 Pierre-Michel Ricordel
4 Copyright 2007-2012 Thomas Fischer
5 Copyright 2017-2020 Petr Ohlidal
6
7 For more information, see http://www.rigsofrods.org/
8
9 Rigs of Rods is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 3, as
11 published by the Free Software Foundation.
12
13 Rigs of Rods is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "CameraManager.h"
23
24#include "AppContext.h"
25#include "ApproxMath.h"
26#include "Actor.h"
27#include "ActorManager.h"
28#include "Character.h"
29#include "Collisions.h"
30#include "Console.h"
31#include "GameContext.h"
32#include "GfxScene.h"
33#include "InputEngine.h"
34#include "Language.h"
35#include "OverlayWrapper.h"
36#include "Replay.h"
37#include "Terrain.h"
38#include "GUIManager.h"
40#include "GfxWater.h"
41
42using namespace Ogre;
43using namespace RoR;
44
45static const Ogre::Vector3 CHARACTERCAM_OFFSET_1ST_PERSON(0.0f, 1.82f, 0.0f);
46static const Ogre::Vector3 CHARACTERCAM_OFFSET_3RD_PERSON(0.0f, 1.1f, 0.0f);
47static const int SPLINECAM_DRAW_RESOLUTION = 200;
48static const int DEFAULT_INTERNAL_CAM_PITCH = -15;
49static const float TRANS_SPEED = 50.f;
50static const float ROTATE_SPEED = 100.f;
51
52bool intersectsTerrain(Vector3 a, Vector3 b) // internal helper
53{
54 b.y = std::max(b.y, App::GetGameContext()->GetTerrain()->getHeightAt(b.x, b.z) + 1.0f);
55
56 int steps = std::max(3.0f, a.distance(b) * 2.0f);
57 for (int i = 1; i < steps; i++)
58 {
59 Vector3 pos = a + (b - a) * (float)i / steps;
60 float h = App::GetGameContext()->GetTerrain()->getHeightAt(pos.x, pos.z);
61 if (h > pos.y)
62 {
63 return true;
64 }
65 }
66 return App::GetGameContext()->GetTerrain()->GetCollisions()->intersectsTris(Ray(a, b - a)).first;
67}
68
69bool intersectsTerrain(Vector3 a, Vector3 start, Vector3 end, float interval) // internal helper
70{
71 int steps = std::max(3.0f, start.distance(end) * (6.0f / interval));
72 for (int i = 0; i <= steps; i++)
73 {
74 Vector3 b = start + (end - start) * (float)i / steps;
75 if (intersectsTerrain(a, b))
76 {
77 return true;
78 }
79 }
80 return false;
81}
82
84 m_current_behavior(CAMERA_BEHAVIOR_INVALID)
85 , m_cct_dt(0.0f)
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)
96 , m_splinecam_mo(0)
97 , m_splinecam_spline_pos(0.5f)
98 , m_staticcam_force_update(false)
99 , m_staticcam_fov_exponent(1.0f)
100 , m_cam_rot_x(0.0f)
101 , m_cam_rot_y(0.3f)
102 , m_cam_dist(5.f)
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)
107 , m_cam_ratio (11.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)
114{
115 m_cct_player_actor = nullptr;
117
118 m_camera = App::GetGfxScene()->GetSceneManager()->createCamera("PlayerCam");
119 m_camera->setNearClipDistance(0.5);
120 m_camera->setAutoAspectRatio(true);
121 this->CreateCameraNode();
122
123 App::GetAppContext()->GetViewport()->setCamera(m_camera);
124}
125
133
135{
137 m_camera_node = App::GetGfxScene()->GetSceneManager()->getRootSceneNode()->createChildSceneNode("PlayerCamNode");
138 m_camera_node->setFixedYawAxis(true);
139 m_camera_node->attachObject(m_camera);
140}
141
143{
144 m_camera_node = nullptr; // after call to `Ogre::SceneManager::ClearScene()`, the node pointer is invalid.
145 this->CreateCameraNode();
146}
147
149{
150 switch(m_current_behavior)
151 {
154 {
156 this->ResetCurrentBehavior();
157 return false;
158 }
159 else // first person
160 {
162 return true;
163 }
164 }
165 case CAMERA_BEHAVIOR_STATIC: return true;
166 case CAMERA_BEHAVIOR_VEHICLE: return true;
167 case CAMERA_BEHAVIOR_VEHICLE_SPLINE: return true;
169 if ( (m_cct_player_actor != nullptr)
171 {
174 return false;
175 }
176 return true;
177 }
178 case CAMERA_BEHAVIOR_FREE: return true;
179 case CAMERA_BEHAVIOR_FIXED: return true;
180 case CAMERA_BEHAVIOR_ISOMETRIC: return true;
181 case CAMERA_BEHAVIOR_INVALID: return true;
182 default: return false;
183 }
184}
185
187{
188 switch(m_current_behavior)
189 {
191 if (!App::GetGameContext()->GetPlayerCharacter())
192 return;
196
198 return;
199 }
200
204 return;
205
210
214
215 Vector3 dir = (m_cct_player_actor->ar_nodes[pos_node].AbsPosition
216 - m_cct_player_actor->ar_nodes[dir_node].AbsPosition).normalisedCopy();
217 Vector3 roll = (m_cct_player_actor->ar_nodes[pos_node].AbsPosition
218 - m_cct_player_actor->ar_nodes[roll_node].AbsPosition).normalisedCopy();
219
221 {
222 roll = -roll;
223 }
224
225 Vector3 up = dir.crossProduct(roll);
226 roll = up.crossProduct(dir);
227
228 Quaternion orientation = Quaternion(m_cam_rot_x, up) * Quaternion(Degree(180.0) + m_cam_rot_y, roll) * Quaternion(roll, up, dir);
229
231 this->GetCameraNode()->setOrientation(orientation);
232 return;
233 }
236 case CAMERA_BEHAVIOR_ISOMETRIC: return;
237 case CAMERA_BEHAVIOR_INVALID: return;
238 default: return;
239 }
240}
241
242void CameraManager::UpdateInputEvents(float dt) // Called every frame
243{
244 if (App::sim_state->getEnum<SimState>() != SimState::RUNNING &&
245 App::sim_state->getEnum<SimState>() != SimState::EDITOR_MODE)
246 {
247 return;
248 }
249
252 m_cct_dt = dt;
253 m_cct_rot_scale = Degree(TRANS_SPEED * dt);
255
256 // Handle forced cinecam
258 {
261 }
262 else
263 {
265 {
267 {
268 this->switchToNextBehavior();
269 }
270 }
271
272 if (App::GetInputEngine()->getEventBoolValueBounce(EV_CAMERA_FREE_MODE_FIX))
273 {
275 }
276
277 if (App::GetInputEngine()->getEventBoolValueBounce(EV_CAMERA_FREE_MODE))
278 {
280 }
281 }
282
284 {
285 this->UpdateCurrentBehavior();
286 }
287 else
288 {
290 }
291
292 // camera FOV settings
293 if (this->GetCurrentBehavior() != CameraManager::CAMERA_BEHAVIOR_STATIC) // the static camera has its own fov logic
294 {
297
298 int modifier = 0;
299 modifier = (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_FOV_LESS, 0.1f)) ? -1 : 0;
300 modifier += (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_FOV_MORE, 0.1f)) ? 1 : 0;
301 int fov = -1;
302 if (modifier != 0)
303 {
304 fov = cvar_fov->getInt() + modifier;
305 if (fov >= 10 && fov <= 160)
306 {
307 cvar_fov->setVal(fov);
308 }
309 else
310 {
312 }
313 }
314 if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_FOV_RESET))
315 {
318 cvar_fov->setVal(cvar_fov_default->getInt());
319 }
320
321 if (fov != -1)
322 {
323 Str<100> msg; msg << _L("FOV: ") << fov;
325 }
326 }
327}
328
330{
331 int i = (static_cast<int>(m_current_behavior) + 1) % CAMERA_BEHAVIOR_END;
332 this->switchBehavior(static_cast<CameraBehaviors>(i));
333}
334
336{
337 switch(m_current_behavior)
338 {
341
342 // Vars from CameraBehaviorOrbit
344 {
345 m_cam_rot_y = 0.1f;
346 m_cam_dist = 0.1f;
347 m_cam_ratio = 0.0f;
348 }
349 else
350 {
351 m_cam_rot_y = 0.3f;
352 m_cam_dist = 5.0f;
353 m_cam_ratio = 11.0f;
354 }
355 m_cam_dist_min = 0;
356 m_cam_target_pitch = 0.0f;
357 return;
358 }
359
363 return;
364
367 return;
368
373 App::GetCameraManager()->GetCamera()->setFOVy(Degree(App::gfx_fov_internal->getInt()));
374 return;
375
376 case CAMERA_BEHAVIOR_FREE: return;
377 case CAMERA_BEHAVIOR_FIXED: return;
378 case CAMERA_BEHAVIOR_ISOMETRIC: return;
379 case CAMERA_BEHAVIOR_INVALID: return;
380 default: return;
381 }
382}
383
385{
386 // Assign new behavior
387 m_current_behavior = new_behavior;
388
389 // Resolve per-behavior constraints and actions
390 switch (new_behavior)
391 {
394 break;
395
399 break;
400
403 break;
404
407 {
408 this->switchToNextBehavior();
409 return;
410 }
411 else if (reset)
412 {
415 }
417 break;
418
420 if ((m_cct_player_actor == nullptr) || (m_cct_player_actor->ar_num_cinecams <= 0))
421 {
422 this->switchToNextBehavior();
423 return;
424 }
425 else if ( reset )
426 {
427 this->ResetCurrentBehavior();
428 }
429
430 App::GetCameraManager()->GetCamera()->setFOVy(Degree(App::gfx_fov_internal->getInt()));
431
433
434 if ( RoR::App::GetOverlayWrapper() != nullptr )
435 {
438 }
439
442
444 break;
445
447 if ( m_cct_player_actor == nullptr )
448 {
449 this->switchToNextBehavior();
450 return;
451 }
452 else if ( reset )
453 {
454 this->ResetCurrentBehavior();
455 }
457 break;
458
460 if (m_cct_player_actor != nullptr)
461 {
462 this->switchToNextBehavior();
463 return;
464 }
465 else if (reset)
466 {
467 this->ResetCurrentBehavior();
468 }
469 break;
470
473 break;
474 }
475}
476
493
495{
496 if (new_behavior == m_current_behavior)
497 {
498 return;
499 }
500
502
503 if (m_cct_player_actor != nullptr)
504 {
506 if (!App::GetGuiManager()->IsGuiHidden())
507 {
509 }
511 {
513 }
514 }
515
516 this->ActivateNewBehavior(new_behavior, true);
517}
518
520{
521 if (new_behavior == m_current_behavior)
522 {
523 this->NotifyContextChange();
524 }
525
527
528 m_cct_player_actor = new_vehicle;
529
530 this->ActivateNewBehavior(new_behavior, new_behavior != m_current_behavior);
531}
532
537
542
544{
545
546 if (App::sim_state->getEnum<SimState>() == SimState::PAUSED)
547 {
548 return true; // Do nothing when paused
549 }
550
551 // IMPORTANT: get mouse button state from InputEngine, not from OIS directly
552 // - that state may be dirty, see commentary in `InputEngine::getMouseState()`
553 const OIS::MouseState ms = App::GetInputEngine()->getMouseState();
554
555 switch(m_current_behavior)
556 {
558 if (!App::GetGameContext()->GetPlayerCharacter())
559 return false;
561 {
563
564 m_cam_rot_y += Degree(ms.Y.rel * 0.13f);
565 angle += Degree(ms.X.rel * 0.13f);
566
567 m_cam_rot_y = Radian(std::min(+Math::HALF_PI * 0.65f, m_cam_rot_y.valueRadians()));
568 m_cam_rot_y = Radian(std::max(m_cam_rot_y.valueRadians(), -Math::HALF_PI * 0.9f));
569
571
573
574 return true;
575 }
576
578 }
584
585 App::GetCameraManager()->GetCameraNode()->yaw(Degree(-ms.X.rel * 0.13f), Ogre::Node::TS_WORLD);
586 App::GetCameraManager()->GetCameraNode()->pitch(Degree(-ms.Y.rel * 0.13f));
587
589
590 return true;
591 }
592
593 case CAMERA_BEHAVIOR_FIXED: return false;
594 case CAMERA_BEHAVIOR_ISOMETRIC: return false;
595 case CAMERA_BEHAVIOR_INVALID: return false;
596 default: return false;
597 }
598}
599
601{
602 // IMPORTANT: get mouse button state from InputEngine, not from OIS directly
603 // - that state may be dirty, see commentary in `InputEngine::getMouseState()`
604 const OIS::MouseState ms = App::GetInputEngine()->getMouseState();
605
606 if (ms.buttonDown(OIS::MB_Right) && ms.buttonDown(OIS::MB_Middle))
607 {
609 }
610
611 switch(m_current_behavior)
612 {
613 case CAMERA_BEHAVIOR_CHARACTER: return false;
614 case CAMERA_BEHAVIOR_STATIC: return false;
618 case CAMERA_BEHAVIOR_FREE: return false;
619 case CAMERA_BEHAVIOR_FIXED: return false;
620 case CAMERA_BEHAVIOR_ISOMETRIC: return false;
621 case CAMERA_BEHAVIOR_INVALID: return false;
622 default: return false;
623 }
624}
625
627{
628 switch(m_current_behavior)
629 {
634 m_cam_look_at_last = Vector3::ZERO;
635 return;
636
637 default:
638 return;
639 }
640}
641
643{
644 // Getting out of vehicle
645 if (new_vehicle == nullptr)
646 {
647 m_cct_player_actor = nullptr;
650 {
652 }
653 return;
654 }
655
656 // Getting in vehicle
659 {
660 // Change camera
661 switch (new_vehicle->ar_camera_context.behavior)
662 {
665 break;
666
669 break;
670
673 break;
674
675 default:
677 }
678 }
679}
680
681void CameraManager::ToggleCameraBehavior(CameraBehaviors new_behavior) // Only accepts FREE and FREEFIX modes
682{
683 ROR_ASSERT(new_behavior == CAMERA_BEHAVIOR_FIXED || new_behavior == CAMERA_BEHAVIOR_FREE);
684
685 if (m_current_behavior == new_behavior) // Leaving toggled mode?
686 {
688 {
691 }
693 {
696 }
697 }
698 else // Entering toggled mode
699 {
701 {
703 }
704 else
705 {
707 }
708 this->switchBehavior(new_behavior);
709 }
710}
711
713{
714 Vector3 velocity = Vector3::ZERO;
715 Radian angle = Degree(90);
716 float radius = 3.0f;
717 float speed = 0.0f;
718
720 {
722 {
724 }
727 if (App::GetGameContext()->GetPlayerActor()->ar_driveable != AIRPLANE)
728 {
730 }
731 angle = (m_staticcam_look_at - m_staticcam_position).angleBetween(velocity);
732 speed = velocity.normalise();
733
735 {
737 }
738 }
739 else
740 {
742 }
743
745
746 if (m_staticcam_force_update || m_staticcam_update_timer.getMilliseconds() > 1000)
747 {
748 Vector3 lookAt = m_staticcam_look_at;
749 Vector3 lookAtPrediction = lookAt + velocity * speed;
750 float distance = m_staticcam_position.distance(lookAt);
751 float interval = std::max(radius, speed);
752 float cmradius = std::max(radius, App::gfx_camera_height->getFloat() / 7.0f);
753
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) ||
758 intersectsTerrain(m_staticcam_position, lookAt, lookAtPrediction, interval))
759 {
760 const auto water = App::GetGameContext()->GetTerrain()->getWater();
761 float water_height = (water && !water->IsUnderWater(lookAt)) ? water->GetStaticWaterHeight() : 0.0f;
762 float desired_offset = std::max(std::sqrt(radius) * 2.89f, App::gfx_camera_height->getFloat());
763
764 std::vector<std::pair<float, Vector3>> viable_positions;
765 for (int i = 0; i < 10; i++)
766 {
767 Vector3 pos = lookAt;
768 if (speed < 2.5f)
769 {
770 float angle = Math::TWO_PI * frand();
771 pos += Vector3(cos(angle), 0, sin(angle)) * cmradius * 2.5f;
772 }
773 else
774 {
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;
780 }
781 pos.y = std::max(pos.y, water_height);
782 pos.y = std::max(pos.y, App::GetGameContext()->GetTerrain()->getHeightAt(pos.x, pos.z));
783 pos.y += desired_offset * (i < 7 ? 1.0f : frand());
784 if (!intersectsTerrain(pos, lookAt, lookAtPrediction, interval))
785 {
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)
789 break;
790 }
791 }
792 if (!viable_positions.empty())
793 {
794 std::sort(viable_positions.begin(), viable_positions.end());
796 m_staticcam_position = viable_positions.front().second;
798 }
799 }
800 }
801
802 static float fovExp = m_staticcam_fov_exponent;
803 fovExp = (1.0f / (m_cam_ratio + 1.0f)) * m_staticcam_fov_exponent + (m_cam_ratio / (m_cam_ratio + 1.0f)) * fovExp;
804
805 float camDist = m_staticcam_position.distance(m_staticcam_look_at);
806 float fov = atan2(20.0f, std::pow(camDist, fovExp));
807
808 this->GetCameraNode()->setPosition(m_staticcam_position);
809 App::GetCameraManager()->GetCameraNode()->lookAt(m_staticcam_look_at, Ogre::Node::TS_WORLD);
810 App::GetCameraManager()->GetCamera()->setFOVy(Radian(fov));
811}
812
814{
815 // IMPORTANT: get mouse button state from InputEngine, not from OIS directly
816 // - that state may be dirty, see commentary in `InputEngine::getMouseState()`
817 const OIS::MouseState ms = App::GetInputEngine()->getMouseState();
818
819 if (ms.buttonDown(OIS::MB_Right))
820 {
821 float scale = RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LMENU) ? 0.00002f : 0.0002f;
822 m_staticcam_fov_exponent += ms.Z.rel * scale;
823 m_staticcam_fov_exponent = Math::Clamp(m_staticcam_fov_exponent, 0.8f, 1.50f);
825 return true;
826 }
827
828 return false;
829}
830
832{
833 if (RoR::App::GetInputEngine()->getEventBoolValueBounce(EV_CAMERA_LOOKBACK))
834 {
835 if (m_cam_rot_x > Degree(0))
836 {
837 m_cam_rot_x = Degree(0);
838 }
839 else
840 {
841 m_cam_rot_x = Degree(180);
842 }
843 }
844
846 {
849 }
850 else
851 {
854 }
855 m_cam_rot_y = std::max((Radian)Degree(-80), m_cam_rot_y);
856 m_cam_rot_y = std::min(m_cam_rot_y, (Radian)Degree(88));
857
858 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CAMERA_ZOOM_IN) && m_cam_dist > 1)
859 {
861 }
862 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CAMERA_ZOOM_IN_FAST) && m_cam_dist > 1)
863 {
865 }
866 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CAMERA_ZOOM_OUT))
867 {
869 }
870 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CAMERA_ZOOM_OUT_FAST))
871 {
873 }
874
875 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CAMERA_RESET))
876 {
878 }
879
880 if (RoR::App::GetInputEngine()->isKeyDown(OIS::KC_RSHIFT) && RoR::App::GetInputEngine()->isKeyDownValueBounce(OIS::KC_SPACE))
881 {
884 {
885 RoR::App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("Limited camera movement enabled"), "camera_go.png");
886 }
887 else
888 {
889 RoR::App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("Limited camera movement disabled"), "camera_go.png");
890 }
891 }
892
894 {
896 }
898 {
900 }
901
902 m_cam_dist = std::max(0.0f, m_cam_dist);
903
904 Vector3 desiredPosition = m_cam_look_at + m_cam_dist * 0.5f * Vector3(
905 sin(m_cam_target_direction.valueRadians() + m_cam_rot_x.valueRadians()) * cos(m_cam_target_pitch.valueRadians() + m_cam_rot_y.valueRadians())
906 , sin(m_cam_target_pitch.valueRadians() + m_cam_rot_y.valueRadians())
907 , cos(m_cam_target_direction.valueRadians() + m_cam_rot_x.valueRadians()) * cos(m_cam_target_pitch.valueRadians() + m_cam_rot_y.valueRadians())
908 );
909
911 {
912 float h = App::GetGameContext()->GetTerrain()->getHeightAt(desiredPosition.x, desiredPosition.z) + 1.0f;
913
914 desiredPosition.y = std::max(h, desiredPosition.y);
915 }
916
917 if (m_cam_look_at_last == Vector3::ZERO)
918 {
920 }
921 if (m_cam_look_at_smooth == Vector3::ZERO)
922 {
924 }
925 if (m_cam_look_at_smooth_last == Vector3::ZERO)
926 {
928 }
929
930 Vector3 camDisplacement = m_cam_look_at - m_cam_look_at_last;
931 Vector3 precedingLookAt = m_cam_look_at_smooth_last + camDisplacement;
932 Vector3 precedingPosition = this->GetCameraNode()->getPosition() + camDisplacement;
933
934 Vector3 camPosition = (1.0f / (m_cam_ratio + 1.0f)) * desiredPosition + (m_cam_ratio / (m_cam_ratio + 1.0f)) * precedingPosition;
935
937 {
938 this->GetCameraNode()->setPosition(App::GetGameContext()->GetTerrain()->GetCollisions()->forcecampos);
940 }
941 else
942 {
943 if (m_cct_player_actor && m_cct_player_actor->ar_state == ActorState::LOCAL_REPLAY && camDisplacement != Vector3::ZERO)
944 this->GetCameraNode()->setPosition(desiredPosition);
945 else
946 this->GetCameraNode()->setPosition(camPosition);
947 }
948
949 m_cam_look_at_smooth = (1.0f / (m_cam_ratio + 1.0f)) * m_cam_look_at + (m_cam_ratio / (m_cam_ratio + 1.0f)) * precedingLookAt;
950
953 App::GetCameraManager()->GetCameraNode()->lookAt(m_cam_look_at_smooth, Ogre::Node::TS_WORLD);
954}
955
957{
958 // IMPORTANT: get mouse button state from InputEngine, not from OIS directly
959 // - that state may be dirty, see commentary in `InputEngine::getMouseState()`
960 const OIS::MouseState ms = App::GetInputEngine()->getMouseState();
961
962 if (ms.buttonDown(OIS::MB_Right))
963 {
965 float scale = RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LMENU) ? 0.002f : 0.02f;
967 {
968 m_cam_rot_x += Degree(ms.X.rel * -0.13f);
969 m_cam_rot_y += Degree(-ms.Y.rel * -0.13f);
970 }
971 else
972 {
973 m_cam_rot_x += Degree(ms.X.rel * 0.13f);
974 m_cam_rot_y += Degree(-ms.Y.rel * 0.13f);
975 }
976 m_cam_dist += -ms.Z.rel * scale;
977 return true;
978 }
979
980 return false;
981}
982
984{
985 m_cam_rot_x = 0.0f;
986 m_cam_rot_y = 0.3f;
987 m_cam_look_at_last = Vector3::ZERO;
988 m_cam_look_at_smooth = Vector3::ZERO;
989 m_cam_look_at_smooth_last = Vector3::ZERO;
990 App::GetCameraManager()->GetCamera()->setFOVy(Degree(App::gfx_fov_external->getInt()));
991}
992
994{
995 Degree mRotX(0.0f);
996 Degree mRotY(0.0f);
997 Degree cct_rot_scale(m_cct_rot_scale * 5.0f * m_cct_dt);
998 Vector3 mTrans(Vector3::ZERO);
999 Real cct_trans_scale(m_cct_trans_scale * 5.0f * m_cct_dt);
1000
1001 if (RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LSHIFT) || RoR::App::GetInputEngine()->isKeyDown(OIS::KC_RSHIFT))
1002 {
1003 cct_rot_scale *= 3.0f;
1004 cct_trans_scale *= 5.0f;
1005 }
1006 if (RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LCONTROL))
1007 {
1008 cct_rot_scale *= 6.0f;
1009 cct_trans_scale *= 10.0f;
1010 }
1011 if (RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LMENU))
1012 {
1013 cct_rot_scale *= 0.2f;
1014 cct_trans_scale *= 0.2f;
1015 }
1016
1017 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CHARACTER_SIDESTEP_LEFT))
1018 {
1019 mTrans.x -= cct_trans_scale;
1020 }
1021 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CHARACTER_SIDESTEP_RIGHT))
1022 {
1023 mTrans.x += cct_trans_scale;
1024 }
1025 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CHARACTER_FORWARD))
1026 {
1027 mTrans.z -= cct_trans_scale;
1028 }
1029 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CHARACTER_BACKWARDS))
1030 {
1031 mTrans.z += cct_trans_scale;
1032 }
1033 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CAMERA_UP))
1034 {
1035 mTrans.y += cct_trans_scale;
1036 }
1037 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CAMERA_DOWN))
1038 {
1039 mTrans.y -= cct_trans_scale;
1040 }
1041
1042 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CHARACTER_RIGHT))
1043 {
1044 mRotX -= cct_rot_scale;
1045 }
1046 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CHARACTER_LEFT))
1047 {
1048 mRotX += cct_rot_scale;
1049 }
1050 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CHARACTER_ROT_UP))
1051 {
1052 mRotY += cct_rot_scale;
1053 }
1054 if (RoR::App::GetInputEngine()->getEventBoolValue(EV_CHARACTER_ROT_DOWN))
1055 {
1056 mRotY -= cct_rot_scale;
1057 }
1058
1059 App::GetCameraManager()->GetCameraNode()->yaw(mRotX, Ogre::Node::TS_WORLD);
1060 App::GetCameraManager()->GetCameraNode()->pitch(mRotY);
1061
1062 Vector3 camPosition = this->GetCameraNode()->getPosition() + this->GetCameraNode()->getOrientation() * mTrans.normalisedCopy() * cct_trans_scale;
1063
1064 this->GetCameraNode()->setPosition(camPosition);
1065}
1066
1068{
1069 if (App::gfx_fixed_cam_tracking->getBool())
1070 {
1072 App::GetCameraManager()->GetCameraNode()->lookAt(look_at, Ogre::Node::TS_WORLD);
1073 }
1074}
1075
1077{
1078 Vector3 dir = m_cct_player_actor->getDirection();
1079
1080 m_cam_target_direction = -atan2(dir.dotProduct(Vector3::UNIT_X), dir.dotProduct(-Vector3::UNIT_Z));
1081 m_cam_target_pitch = 0.0f;
1082
1083 if ( RoR::App::gfx_extcam_mode->getEnum<GfxExtCamMode>() == RoR::GfxExtCamMode::PITCHING)
1084 {
1085 m_cam_target_pitch = -asin(dir.dotProduct(Vector3::UNIT_Y));
1086 }
1087
1088 m_cam_ratio = 1.0f / (m_cct_dt * 4.0f);
1089
1090 m_cam_dist_min = std::min(m_cct_player_actor->getMinimalCameraRadius() * 2.0f, 33.0f);
1091
1093
1095}
1096
1104
1106{
1107 // IMPORTANT: get mouse button state from InputEngine, not from OIS directly
1108 // - that state may be dirty, see commentary in `InputEngine::getMouseState()`
1109 const OIS::MouseState ms = App::GetInputEngine()->getMouseState();
1110
1111 if ( ms.buttonDown(OIS::MB_Middle) && RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LSHIFT) )
1112 {
1114 {
1115 // Calculate new camera distance
1117 m_cam_dist = 2.0f * this->GetCameraNode()->getPosition().distance(lookAt);
1118
1119 // Calculate new camera pitch
1120 Vector3 camDir = (this->GetCameraNode()->getPosition() - lookAt).normalisedCopy();
1121 m_cam_rot_y = asin(camDir.y);
1122
1123 // Calculate new camera yaw
1124 Vector3 dir = -m_cct_player_actor->getDirection();
1125 Quaternion rotX = dir.getRotationTo(camDir, Vector3::UNIT_Y);
1126 m_cam_rot_x = rotX.getYaw();
1127
1128 // Corner case handling
1129 Radian angle = dir.angleBetween(camDir);
1130 if ( angle > Radian(Math::HALF_PI) )
1131 {
1132 if ( std::abs(Radian(m_cam_rot_x).valueRadians()) < Math::HALF_PI )
1133 {
1134 if ( m_cam_rot_x < Radian(0.0f) )
1135 m_cam_rot_x -= Radian(Math::HALF_PI);
1136 else
1137 m_cam_rot_x += Radian(Math::HALF_PI);
1138 }
1139 }
1140 }
1141 }
1142
1143 return false;
1144}
1145
1147{
1149 {
1150 this->switchToNextBehavior();
1151 return;
1152 }
1153
1154 Vector3 dir = m_cct_player_actor->getDirection();
1155
1156 m_cam_target_pitch = 0.0f;
1157
1158 if (App::gfx_extcam_mode->getEnum<GfxExtCamMode>() == GfxExtCamMode::PITCHING)
1159 {
1160 m_cam_target_pitch = -asin(dir.dotProduct(Vector3::UNIT_Y));
1161 }
1162
1164 {
1166 }
1169
1171
1172 if (RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LSHIFT) && RoR::App::GetInputEngine()->isKeyDownValueBounce(OIS::KC_SPACE))
1173 {
1176 {
1178 }
1179 else
1180 {
1182 }
1183 }
1184
1186 {
1187 Vector3 centerDir = m_cct_player_actor->getPosition() - m_cam_look_at;
1188 if (centerDir.length() > 1.0f)
1189 {
1190 centerDir.normalise();
1191 Radian oldTargetDirection = m_cam_target_direction;
1192 m_cam_target_direction = -atan2(centerDir.dotProduct(Vector3::UNIT_X), centerDir.dotProduct(-Vector3::UNIT_Z));
1193 if (m_cam_target_direction.valueRadians() * oldTargetDirection.valueRadians() < 0.0f && centerDir.length() < m_cam_dist_min)
1194 {
1196 }
1197 }
1198 }
1199
1201}
1202
1204{
1205 // IMPORTANT: get mouse button state from InputEngine, not from OIS directly
1206 // - that state may be dirty, see commentary in `InputEngine::getMouseState()`
1207 const OIS::MouseState ms = App::GetInputEngine()->getMouseState();
1208
1209 m_cam_ratio = 1.0f / (m_cct_dt * 4.0f);
1210
1211 if (RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LCONTROL) && ms.buttonDown(OIS::MB_Right))
1212 {
1213 Real splinePosDiff = ms.X.rel * std::max(0.00005f, m_splinecam_spline_len * 0.0000001f);
1214
1215 if (RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LSHIFT) || RoR::App::GetInputEngine()->isKeyDown(OIS::KC_RSHIFT))
1216 {
1217 splinePosDiff *= 3.0f;
1218 }
1219
1220 if (RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LMENU))
1221 {
1222 splinePosDiff *= 0.1f;
1223 }
1224
1225 m_splinecam_spline_pos += splinePosDiff;
1226
1227 if (ms.X.rel > 0 && m_splinecam_spline_pos > 0.99f)
1228 {
1230 {
1231 m_splinecam_spline_pos -= 1.0f;
1232 }
1233 else
1234 {
1235 // u - turn
1236 }
1237 }
1238 else if (ms.X.rel < 0 && m_splinecam_spline_pos < 0.01f)
1239 {
1241 {
1242 m_splinecam_spline_pos += 1.0f;
1243 }
1244 else
1245 {
1246 // u - turn
1247 }
1248 }
1249
1252
1253 return true;
1254 }
1255 else
1256 {
1258 }
1259}
1260
1269
1271{
1274
1275 m_splinecam_spline->clear();
1277
1278 for (int i = 0; i < m_cct_player_actor->ar_num_camera_rails; i++)
1279 {
1281 }
1282
1283 auto linkedBeams = m_cct_player_actor->ar_linked_actors;
1284
1285 m_splinecam_num_linked_beams = static_cast<int>(linkedBeams.size());
1286
1288 {
1289 for (ActorPtr& actor : linkedBeams)
1290 {
1291 if (actor->ar_num_camera_rails <= 0)
1292 continue;
1293
1294 Vector3 curSplineFront = m_splinecam_spline_nodes.front()->AbsPosition;
1295 Vector3 curSplineBack = m_splinecam_spline_nodes.back()->AbsPosition;
1296
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;
1299
1300 if (curSplineBack.distance(linkedSplineFront) < 5.0f)
1301 {
1302 for (int i = 1; i < actor->ar_num_camera_rails; i++)
1303 {
1304 m_splinecam_spline_nodes.push_back(&actor->ar_nodes[actor->ar_camera_rail[i]]);
1305 }
1306 }
1307 else if (curSplineFront.distance(linkedSplineFront) < 5.0f)
1308 {
1309 for (int i = 1; i < actor->ar_num_camera_rails; i++)
1310 {
1311 m_splinecam_spline_nodes.push_front(&actor->ar_nodes[actor->ar_camera_rail[i]]);
1312 }
1313 }
1314 else if (curSplineBack.distance(linkedSplineBack) < 5.0f)
1315 {
1316 for (int i = actor->ar_num_camera_rails - 2; i >= 0; i--)
1317 {
1318 m_splinecam_spline_nodes.push_back(&actor->ar_nodes[actor->ar_camera_rail[i]]);
1319 }
1320 }
1321 else if (curSplineFront.distance(linkedSplineBack) < 5.0f)
1322 {
1323 for (int i = actor->ar_num_camera_rails - 2; i >= 0; i--)
1324 {
1325 m_splinecam_spline_nodes.push_front(&actor->ar_nodes[actor->ar_camera_rail[i]]);
1326 }
1327 }
1328 }
1329 }
1330
1331 for (unsigned int i = 0; i < m_splinecam_spline_nodes.size(); i++)
1332 {
1333 m_splinecam_spline->addPoint(m_splinecam_spline_nodes[i]->AbsPosition);
1334 }
1335
1336 Vector3 firstPoint = m_splinecam_spline->getPoint(0);
1337 Vector3 lastPoint = m_splinecam_spline->getPoint(m_splinecam_spline->getNumPoints() - 1);
1338
1339 if (firstPoint.distance(lastPoint) < 1.0f)
1340 {
1342 }
1343
1344 for (int i = 1; i < m_splinecam_spline->getNumPoints(); i++)
1345 {
1346 m_splinecam_spline_len += m_splinecam_spline->getPoint(i - 1).distance(m_splinecam_spline->getPoint(i));
1347 }
1348
1349 m_splinecam_spline_len /= 2.0f;
1350
1351 if (!m_splinecam_mo && RoR::App::diag_camera->getBool())
1352 {
1353 m_splinecam_mo = App::GetGfxScene()->GetSceneManager()->createManualObject();
1354 SceneNode* splineNode = App::GetGfxScene()->GetSceneManager()->getRootSceneNode()->createChildSceneNode();
1355
1356 m_splinecam_mo->begin("tracks/transred", Ogre::RenderOperation::OT_LINE_STRIP);
1357 for (int i = 0; i < SPLINECAM_DRAW_RESOLUTION; i++)
1358 {
1359 m_splinecam_mo->position(0, 0, 0);
1360 }
1361 m_splinecam_mo->end();
1362
1363 splineNode->attachObject(m_splinecam_mo);
1364 }
1365}
1366
1368{
1369 for (int i = 0; i < m_splinecam_spline->getNumPoints(); i++)
1370 {
1371 m_splinecam_spline->updatePoint(i, m_splinecam_spline_nodes[i]->AbsPosition);
1372 }
1373}
1374
1376{
1377 if (!m_splinecam_mo)
1378 return;
1379
1380 m_splinecam_mo->beginUpdate(0);
1381 for (int i = 0; i < SPLINECAM_DRAW_RESOLUTION; i++)
1382 {
1383 Real parametricDist = i / (float)SPLINECAM_DRAW_RESOLUTION;
1384 Vector3 position = m_splinecam_spline->interpolate(parametricDist);
1385 m_splinecam_mo->position(position);
1386 }
1387 m_splinecam_mo->end();
1388}
System integration layer; inspired by OgreBites::ApplicationContext.
#define ROR_ASSERT(_EXPR)
Definition Application.h:40
float frand()
Definition ApproxMath.h:31
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)
#define _L
Game state manager and message-queue provider.
Handles controller inputs from player.
NodeNum_t ar_custom_camera_node
Sim state; custom tracking node for 3rd-person camera.
Definition Actor.h:497
NodeNum_t ar_camera_node_dir[MAX_CAMERAS]
Physics attr; 'camera' = frame of reference; back node.
Definition Actor.h:445
void prepareInside(bool inside)
Prepares vehicle for in-cabin camera use.
Definition Actor.cpp:3023
bool ar_camera_node_roll_inv[MAX_CAMERAS]
Physics attr; 'camera' = frame of reference; indicates roll node is right instead of left.
Definition Actor.h:447
int ar_num_camera_rails
Definition Actor.h:404
node_t * ar_nodes
Definition Actor.h:330
void NotifyActorCameraChanged()
Logic: sound, display; Notify this vehicle that camera changed;.
Definition Actor.cpp:3893
CineCameraID_t ar_current_cinecam
Sim state; index of current CineCam (CINECAMERAID_INVALID if using 3rd-person camera)
Definition Actor.h:496
Replay * getReplay()
Definition Actor.cpp:4663
NodeNum_t ar_camera_node_roll[MAX_CAMERAS]
Physics attr; 'camera' = frame of reference; left node.
Definition Actor.h:446
Ogre::Vector3 getPosition()
Definition Actor.cpp:370
NodeNum_t ar_camera_rail[MAX_CAMERARAIL]
Nodes defining camera-movement spline.
Definition Actor.h:403
ActorState ar_state
Definition Actor.h:518
Ogre::Vector3 getDirection()
average actor velocity, calculated using the actor positions of the last two frames
Definition Actor.cpp:365
bool isBeingReset() const
Definition Actor.h:313
PerVehicleCameraContext ar_camera_context
Definition Actor.h:498
ActorPtrVec ar_linked_actors
BEWARE: Includes indirect links, see DetermineLinkedActors(); Other actors linked using 'hooks/ties/r...
Definition Actor.h:519
NodeNum_t ar_camera_node_pos[MAX_CAMERAS]
Physics attr; 'camera' = frame of reference; origin node.
Definition Actor.h:444
int ar_num_cinecams
Sim attr;.
Definition Actor.h:434
Ogre::Real getMinimalCameraRadius()
Definition Actor.cpp:4622
float getMinCameraRadius()
Definition Actor.h:296
CineCameraID_t ar_forced_cinecam
Sim state; index of CineCam forced by script (CINECAMERAID_INVALID if not forced)
Definition Actor.h:499
NodeNum_t ar_cinecam_node[MAX_CAMERAS]
Sim attr; Cine-camera node indexes.
Definition Actor.h:433
ActorType ar_driveable
Sim attr; marks vehicle type and features.
Definition Actor.h:431
float GetSimulationSpeed() const
Ogre::Viewport * GetViewport()
Definition AppContext.h:66
Quake-style console variable, defined in RoR.cfg or crated via Console UI and scripts.
Definition CVar.h:53
float getFloat() const
Definition CVar.h:96
void setVal(T val)
Definition CVar.h:72
int getInt() const
Definition CVar.h:97
Ogre::Radian m_cam_rot_y
bool CameraBehaviorVehicleMousePressed()
Ogre::Radian m_cam_target_direction
Ogre::Degree m_cct_rot_scale
ActorPtr m_cct_player_actor
CameraBehaviors m_current_behavior
Ogre::Radian m_cam_rot_x
void ActivateNewBehavior(CameraBehaviors new_behavior, bool reset)
Ogre::ManualObject * m_splinecam_mo
void CameraBehaviorVehicleSplineCreateSpline()
Ogre::Radian m_staticcam_previous_fov
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
void ReCreateCameraNode()
Needed since we call Ogre::SceneManager::ClearScene() after end of sim. session.
Ogre::Vector3 m_cam_look_at_last
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.
Ogre::Camera * m_camera
Ogre::SceneNode * GetCameraNode()
Ogre::Real m_cct_trans_scale
void switchBehavior(CameraBehaviors new_behavior)
void SwitchBehaviorOnVehicleChange(CameraBehaviors new_behavior, ActorPtr new_vehicle)
void CameraBehaviorVehicleSplineUpdateSpline()
CameraBehaviors GetCurrentBehavior() const
Ogre::SimpleSpline * m_splinecam_spline
Ogre::Vector3 m_cam_look_at_smooth_last
Ogre::Camera * GetCamera()
bool CameraBehaviorOrbitMouseMoved()
Ogre::Radian m_cam_target_pitch
void CameraBehaviorVehicleSplineUpdate()
void CameraBehaviorVehicleSplineUpdateSplineDisplay()
Ogre::Vector3 m_cam_look_at
void ToggleCameraBehavior(CameraBehaviors new_behavior)
Only accepts FREE and FREEFIX modes.
Ogre::Timer m_staticcam_update_timer
Ogre::Real m_splinecam_spline_pos
Ogre::Vector3 m_staticcam_look_at
Ogre::SceneNode * m_camera_node
Ogre::Vector3 getPosition()
Definition Character.cpp:92
void setRotation(Ogre::Radian rotation)
Definition Character.cpp:98
Ogre::Radian getRotation() const
Definition Character.h:53
std::pair< bool, Ogre::Real > intersectsTris(Ogre::Ray ray)
@ CONSOLE_MSGTYPE_INFO
Generic message.
Definition Console.h:60
void putMessage(MessageArea area, MessageType type, std::string const &msg, std::string icon="")
Definition Console.cpp:103
@ CONSOLE_SYSTEM_NOTICE
Definition Console.h:51
bool IsGuiHidden() const
Definition GUIManager.h:156
@ 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()
Definition GfxScene.h:83
bool isKeyDown(OIS::KeyCode mod)
Asks OIS directly.
OIS::MouseState getMouseState()
bool getEventBoolValueBounce(int eventID, float time=0.2f)
float getEventValue(int eventID, bool pure=false, InputSourceType valueSource=InputSourceType::IST_ANY)
valueSource: IST_ANY=digital and analog devices, IST_DIGITAL=only digital, IST_ANALOG=only analog
void showDashboardOverlays(bool show, ActorPtr actor)
float getPrecision() const
Definition Replay.h:51
Wrapper for classic c-string (local buffer) Refresher: strlen() excludes '\0' terminator; strncat() A...
Definition Str.h:36
const char * ToCStr() const
Definition Str.h:46
float getHeightAt(float x, float z)
Definition Terrain.cpp:512
Collisions * GetCollisions()
Definition Terrain.h:86
Wavefield * getWater()
Definition Terrain.h:87
float GetStaticWaterHeight()
Returns static water level configured in 'terrn2'.
Definition Wavefield.cpp:75
@ EDITOR_MODE
Hacky, but whatever... added by Ulteq, 2016.
@ AIRPLANE
its an airplane
Definition SimData.h:86
@ EV_CAMERA_DOWN
@ EV_COMMON_FOV_MORE
increases the current FOV value
@ EV_CAMERA_ZOOM_IN_FAST
zoom camera in faster
@ EV_CAMERA_ROTATE_LEFT
rotate camera left
@ EV_CHARACTER_ROT_UP
@ EV_COMMON_FOV_LESS
decreases the current FOV value
@ EV_CAMERA_ZOOM_OUT_FAST
zoom camera out faster
@ EV_CAMERA_ROTATE_DOWN
rotate camera down
@ EV_CAMERA_RESET
reset the camera position
@ EV_CAMERA_ZOOM_OUT
zoom camera out
@ EV_CHARACTER_SIDESTEP_LEFT
sidestep to the left
@ EV_CHARACTER_RIGHT
rotate character right
@ EV_CHARACTER_FORWARD
step forward with the character
@ EV_CAMERA_ROTATE_UP
rotate camera up
@ EV_CAMERA_ZOOM_IN
zoom camera in
@ EV_CHARACTER_LEFT
rotate character left
@ EV_CAMERA_UP
@ EV_COMMON_FOV_RESET
reset the FOV value
@ EV_CAMERA_FREE_MODE
@ EV_CAMERA_LOOKBACK
look back (toggles between normal and lookback)
@ EV_CHARACTER_ROT_DOWN
@ EV_CHARACTER_SIDESTEP_RIGHT
sidestep to the right
@ EV_CAMERA_ROTATE_RIGHT
rotate camera right
@ EV_CHARACTER_BACKWARDS
step backwards with the character
@ EV_CAMERA_CHANGE
change camera mode
@ EV_CAMERA_FREE_MODE_FIX
AppContext * GetAppContext()
CVar * gfx_static_cam_fov_exp
CVar * sim_state
OverlayWrapper * GetOverlayWrapper()
InputEngine * GetInputEngine()
CVar * gfx_extcam_mode
CVar * io_invert_orbitcam
CVar * gfx_fov_internal_default
CameraManager * GetCameraManager()
GUIManager * GetGuiManager()
GameContext * GetGameContext()
CVar * gfx_camera_height
GfxScene * GetGfxScene()
CVar * gfx_fov_external
CVar * diag_camera
Console * GetConsole()
CVar * gfx_fov_internal
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.
Ogre::Vector3 AbsPosition
absolute position in the world (shaky)
Definition SimData.h:267
Ogre::Vector3 Velocity
Definition SimData.h:268