From 6c7b82130ce296c5b07e4a5ab0fcf552d9ff7247 Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Fri, 13 Aug 2010 13:26:29 +0000 Subject: [PATCH] # Redesigned the camera control system. Add shift+wheel (and Q/E, and ctrl+arrows, and ctrl+WASD) to rotate the camera. Restrict the rotation and zoom to narrow ranges. (Constraints can be disabled in the dev overlay). Smooth the movement and rotation. Fix some stupid whitespace. Fix some const correctness. This was SVN commit r7930. --- binaries/data/config/default.cfg | 46 +- .../data/mods/public/gui/manual/intro.txt | 27 +- .../mods/public/gui/session_new/session.xml | 7 +- source/graphics/Camera.cpp | 67 +- source/graphics/Camera.h | 8 +- source/graphics/GameView.cpp | 738 +++++++++--------- source/graphics/GameView.h | 20 +- source/graphics/MapReader.cpp | 28 +- source/graphics/MapReader.h | 6 +- source/graphics/MapWriter.cpp | 7 +- source/graphics/MapWriter.h | 2 +- source/gui/MiniMap.cpp | 41 +- source/gui/MiniMap.h | 3 +- source/ps/Hotkey.cpp | 26 +- source/ps/Hotkey.h | 26 +- source/ps/World.cpp | 5 +- source/renderer/TerrainRenderer.cpp | 2 +- source/scripting/ScriptGlue.cpp | 2 +- source/simulation2/helpers/Selection.cpp | 4 +- source/simulation2/helpers/Selection.h | 4 +- .../GameInterface/Handlers/CinemaHandler.cpp | 4 +- 21 files changed, 492 insertions(+), 581 deletions(-) diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg index e512bf322d..f68dd670d7 100644 --- a/binaries/data/config/default.cfg +++ b/binaries/data/config/default.cfg @@ -72,15 +72,25 @@ max_players = 8 sound.mastergain = 0.5 -; selection.outline.quality = 9; ( higher => very slightly slower, better quality) -; view.scroll.speed = 60 -; view.rotate.speed = 0.002 -; view.rotate.abouttarget.speed = 0.01 -; view.drag.speed = 0.5 -; view.zoom.speed = 256.0 -; view.zoom.wheel.speed = 16.0 -; view.zoom.smoothness = 0.02 ; between 0 and 1 -; view.snap.smoothness = 0.02 ; less is sharper, more is softer +; Camera control settings +view.scroll.speed = 120.0 +view.rotate.x.speed = 1.2 +view.rotate.x.min = 20 +view.rotate.x.max = 60 +view.rotate.x.default = 30 +view.rotate.y.speed = 2.0 +view.rotate.y.speed.wheel = 0.1 +view.rotate.y.default 0.0 +view.drag.speed = 0.5 +view.zoom.speed = 256.0 +view.zoom.speed.wheel = 32.0 +view.zoom.min = 96.0 +view.zoom.max = 256.0 +view.zoom.default = 192.0 +view.pos.smoothness = 0.1 +view.zoom.smoothness = 0.4 +view.rotate.x.smoothness = 0.5 +view.rotate.y.smoothness = 0.3 ; HOTKEY MAPPINGS: @@ -108,12 +118,12 @@ hotkey.camera.zoom.in = Plus, Equals, NumPlus ; Zoom camera in. hotkey.camera.zoom.out = Minus, NumMinus ; Zoom camera out. hotkey.camera.zoom.wheel.in = WheelUp ; Zoom camera in (wheel speed). hotkey.camera.zoom.wheel.out = WheelDown ; Zoom camera out (wheel speed). -hotkey.camera.rotate = "Ctrl+MouseMiddle" ; Rotate view by moving mouse, maintaining the - ; absolute position of the camera -hotkey.camera.rotate.keyboard = "Shift" ; -hotkey.camera.rotate.abouttarget = "MouseLeft+MouseRight" ; Rotate view by moving mouse, maintaining the - ; world coordinates of the centre of the viewport -hotkey.camera.rotate.abouttarget.keyboard = "Ctrl" ; +hotkey.camera.rotate.wheel.cw = "Shift+WheelUp" +hotkey.camera.rotate.wheel.ccw = "Shift+WheelDown" +hotkey.camera.rotate.cw = "Ctrl+LeftArrow", "Ctrl+A", Q +hotkey.camera.rotate.ccw = "Ctrl+RightArrow", "Ctrl+D", E +hotkey.camera.rotate.up = "Ctrl+UpArrow", "Ctrl+W" +hotkey.camera.rotate.down = "Ctrl+DownArrow", "Ctrl+S" hotkey.camera.pan = MouseMiddle, ForwardSlash ; Scroll by moving mouse. hotkey.camera.pan.keyboard = "~Shift+~Ctrl" ; = holding neither Ctrl nor Shift @@ -121,12 +131,6 @@ hotkey.camera.left = A, LeftArrow ; Scroll or rotate left. hotkey.camera.right = D, RightArrow ; Scroll or rotate right. hotkey.camera.up = W, UpArrow ; Scroll or rotate up/forwards. hotkey.camera.down = S, DownArrow ; Scroll or rotate down/backwards. -hotkey.camera.bookmark.0 = F5 ; Saved bookmark 1. -hotkey.camera.bookmark.1 = F6 ; Saved bookmark 2. -hotkey.camera.bookmark.2 = F7 ; Saved bookmark 3. -hotkey.camera.bookmark.3 = F8 ; Saved bookmark 4. -hotkey.camera.bookmark.save = Ctrl ; +bookmark: Save screen as bookmark. -hotkey.camera.bookmark.snap = Alt ; +bookmark: "check up" on bookmark. ;camera.cinema.add = "L" ;camera.cinema.delete = "U" diff --git a/binaries/data/mods/public/gui/manual/intro.txt b/binaries/data/mods/public/gui/manual/intro.txt index e15e4bffa5..32bd9ecc63 100644 --- a/binaries/data/mods/public/gui/manual/intro.txt +++ b/binaries/data/mods/public/gui/manual/intro.txt @@ -5,6 +5,20 @@ Thank you for installing 0 A.D.! This page will give a brief overview of the fea [font="serif-bold-16"]Graphics settings [font="serif-14"]You can switch between fullscreen and windowed mode by pressing Alt+Enter. In windowed mode, you can resize the window. If the game runs too slowly, you can change some settings in the configuration file: look for binaries/data/config/default.cfg in the location where the game is installed, which gives instructions for editing, and try disabling the "fancywater" and "shadows" options. +[font="serif-bold-16"]Playing the game +[font="serif-14"]The controls and gameplay should be familiar to players of traditional RTS games. There are currently a lot of missing features and poorly-balanced stats – you will probably have to wait until a beta release for it to work well. + +Basic controls: +• Left-click to select units. +• Left-click-and-drag to select groups of units. +• Right-click to order units to the target. +• Arrow keys or WASD keys to move the camera. +• Ctrl + arrow keys, or shift + mouse wheel, to rotate the camera. +• Mouse wheel, or "+" and "-" keys, to zoom. +• F2 to save a screenshot (into %appdata%\0ad\screenshots\ on Windows, and ~/.local/share/0ad/screenshots/ on Unix). +• Ctrl+Alt+F2 to save a very high-resolution screenshot. +• F11 to view the built-in performance profiler. + [font="serif-bold-16"]Modes [font="serif-14"]The main menu gives access to two game modes: @@ -23,17 +37,4 @@ Next, you can use the drop-down lists in the player list to select who controls When you are ready to start, click the "Start game" button. -[font="serif-bold-16"]Playing the game -[font="serif-14"]The controls and gameplay should be familiar to players of traditional RTS games. There are currently a lot of missing features and poorly-balanced stats – you will probably have to wait until a beta release for it to work well. - -Basic controls: -• Left-click to select units. -• Left-click-and-drag to select groups of units. -• Right-click to order units to the target. -• Arrow keys or WASD keys to move the camera. -• Ctrl + arrow keys to rotate the camera. -• F2 to save a screenshot (into %appdata%\0ad\screenshots\ on Windows, and ~/.local/share/0ad/screenshots/ on Unix). -• Ctrl+Alt+F2 to save a very high-resolution screenshot. -• F11 to view the built-in performance profiler. - Use the "X" button in the top-right corner of this window to close it. diff --git a/binaries/data/mods/public/gui/session_new/session.xml b/binaries/data/mods/public/gui/session_new/session.xml index ea854883db..482b38f649 100644 --- a/binaries/data/mods/public/gui/session_new/session.xml +++ b/binaries/data/mods/public/gui/session_new/session.xml @@ -77,7 +77,7 @@ /> - diff --git a/source/graphics/Camera.cpp b/source/graphics/Camera.cpp index cbe356ac2a..4f4a923f53 100644 --- a/source/graphics/Camera.cpp +++ b/source/graphics/Camera.cpp @@ -161,23 +161,23 @@ void CCamera::GetCameraPlanePoints(float dist,CVector3D pts[4]) const pts[3].Z=dist; } -void CCamera::BuildCameraRay( int px, int py, CVector3D& origin, CVector3D& dir ) +void CCamera::BuildCameraRay(int px, int py, CVector3D& origin, CVector3D& dir) const { CVector3D cPts[4]; - GetCameraPlanePoints( m_FarPlane, cPts ); + GetCameraPlanePoints(m_FarPlane, cPts); // transform to world space CVector3D wPts[4]; - for( int i = 0; i < 4; i++) - wPts[i] = m_Orientation.Transform( cPts[i] ); + for (int i = 0; i < 4; i++) + wPts[i] = m_Orientation.Transform(cPts[i]); // get world space position of mouse point - float dx = (float)px/(float)g_Renderer.GetWidth(); - float dz=1-(float)py/(float)g_Renderer.GetHeight(); + float dx = (float)px / (float)g_Renderer.GetWidth(); + float dz = 1 - (float)py / (float)g_Renderer.GetHeight(); CVector3D vdx = wPts[1] - wPts[0]; CVector3D vdz = wPts[3] - wPts[0]; - CVector3D pt = wPts[0] + ( vdx * dx ) + ( vdz * dz ); + CVector3D pt = wPts[0] + (vdx * dx) + (vdz * dz); // copy origin origin = m_Orientation.GetTranslation(); @@ -186,39 +186,39 @@ void CCamera::BuildCameraRay( int px, int py, CVector3D& origin, CVector3D& dir dir.Normalize(); } -void CCamera::GetScreenCoordinates( const CVector3D& world, float& x, float& y ) const +void CCamera::GetScreenCoordinates(const CVector3D& world, float& x, float& y) const { CMatrix3D transform; - m_Orientation.GetInverse( transform ); - transform.Concatenate( m_ProjMat ); + m_Orientation.GetInverse(transform); + transform.Concatenate(m_ProjMat); - CVector3D screenspace = transform.Transform( world ); + CVector3D screenspace = transform.Transform(world); x = screenspace.X / screenspace.Z; y = screenspace.Y / screenspace.Z; - x = ( x + 1 ) * 0.5f * g_Renderer.GetWidth(); - y = ( 1 - y ) * 0.5f * g_Renderer.GetHeight(); + x = (x + 1) * 0.5f * g_Renderer.GetWidth(); + y = (1 - y) * 0.5f * g_Renderer.GetHeight(); } -CVector3D CCamera::GetWorldCoordinates( int px, int py, bool aboveWater ) +CVector3D CCamera::GetWorldCoordinates(int px, int py, bool aboveWater) const { - CHFTracer tracer( g_Game->GetWorld()->GetTerrain() ); + CHFTracer tracer(g_Game->GetWorld()->GetTerrain()); int x, z; CVector3D origin, dir, delta, terrainPoint, waterPoint; - BuildCameraRay( px, py, origin, dir ); + BuildCameraRay(px, py, origin, dir); - bool gotTerrain = tracer.RayIntersect( origin, dir, x, z, terrainPoint ); + bool gotTerrain = tracer.RayIntersect(origin, dir, x, z, terrainPoint); - if( !aboveWater ) + if (!aboveWater) { - if( gotTerrain ) + if (gotTerrain) return terrainPoint; // Off the edge of the world? // Work out where it /would/ hit, if the map were extended out to infinity with average height. - return GetWorldCoordinates( px, py, 50.0f ); + return GetWorldCoordinates(px, py, 50.0f); } CPlane plane; @@ -236,12 +236,12 @@ CVector3D CCamera::GetWorldCoordinates( int px, int py, bool aboveWater ) waterPoint.Z = clamp(waterPoint.Z, 0.f, (float)((mapSize-1)*CELL_SIZE)); } - if( gotTerrain ) + if (gotTerrain) { - if( gotWater ) + if (gotWater) { // Intersecting both heightmap and water plane; choose the closest of those - if( (origin - terrainPoint).LengthSquared() < (origin - waterPoint).LengthSquared() ) + if ((origin - terrainPoint).LengthSquared() < (origin - waterPoint).LengthSquared()) return terrainPoint; else return waterPoint; @@ -254,7 +254,7 @@ CVector3D CCamera::GetWorldCoordinates( int px, int py, bool aboveWater ) } else { - if( gotWater ) + if (gotWater) { // Only intersecting water plane return waterPoint; @@ -268,7 +268,7 @@ CVector3D CCamera::GetWorldCoordinates( int px, int py, bool aboveWater ) } -CVector3D CCamera::GetWorldCoordinates(int px, int py, float h) +CVector3D CCamera::GetWorldCoordinates(int px, int py, float h) const { CPlane plane; plane.Set(CVector3D(0.f, 1.f, 0.f), CVector3D(0.f, h, 0.f)); // upwards normal, passes through h @@ -289,33 +289,34 @@ CVector3D CCamera::GetFocus() { // Basically the same as GetWorldCoordinates - CHFTracer tracer( g_Game->GetWorld()->GetTerrain() ); int x, z; + CHFTracer tracer(g_Game->GetWorld()->GetTerrain()); + int x, z; CVector3D origin, dir, delta, currentTarget; origin = m_Orientation.GetTranslation(); dir = m_Orientation.GetIn(); - if( tracer.RayIntersect( origin, dir, x, z, currentTarget ) ) - return( currentTarget ); + if (tracer.RayIntersect(origin, dir, x, z, currentTarget)) + return (currentTarget); // Off the edge of the world? // Work out where it /would/ hit, if the map were extended out to infinity with average height. - return( origin + dir * ( ( 50.0f - origin.Y ) / dir.Y ) ); + return (origin + dir * ((50.0f - origin.Y) / dir.Y)); } -void CCamera::LookAt( const CVector3D& camera, const CVector3D& target, const CVector3D& up ) +void CCamera::LookAt(const CVector3D& camera, const CVector3D& target, const CVector3D& up) { CVector3D delta = target - camera; - LookAlong( camera, delta, up ); + LookAlong(camera, delta, up); } -void CCamera::LookAlong( CVector3D camera, CVector3D orientation, CVector3D up ) +void CCamera::LookAlong(CVector3D camera, CVector3D orientation, CVector3D up) { orientation.Normalize(); up.Normalize(); - CVector3D s = orientation.Cross( up ); + CVector3D s = orientation.Cross(up); m_Orientation._11 = -s.X; m_Orientation._12 = up.X; m_Orientation._13 = orientation.X; m_Orientation._14 = camera.X; m_Orientation._21 = -s.Y; m_Orientation._22 = up.Y; m_Orientation._23 = orientation.Y; m_Orientation._24 = camera.Y; diff --git a/source/graphics/Camera.h b/source/graphics/Camera.h index 8b2562943f..bb3158f8e5 100644 --- a/source/graphics/Camera.h +++ b/source/graphics/Camera.h @@ -52,7 +52,7 @@ class CCamera // everytime the view or projection matrices are // altered. void UpdateFrustum (); - const CFrustum& GetFrustum () { return m_ViewFrustum; } + const CFrustum& GetFrustum () const { return m_ViewFrustum; } void SetViewPort (const SViewPort& viewport); const SViewPort& GetViewPort () const { return m_ViewPort; } @@ -69,7 +69,7 @@ class CCamera ///////////////////////////////////////////////////////////////////////////////////////// // BuildCameraRay: calculate origin and ray direction of a ray through // the pixel (px,py) on the screen - void BuildCameraRay(int px, int py, CVector3D& origin, CVector3D& dir); + void BuildCameraRay(int px, int py, CVector3D& origin, CVector3D& dir) const; // General helpers that seem to fit here @@ -78,9 +78,9 @@ class CCamera // Get the point on the terrain corresponding to pixel (px,py) (or the mouse coordinates) // The aboveWater parameter determines whether we want to stop at the water plane or also get underwater points - CVector3D GetWorldCoordinates(int px, int py, bool aboveWater=false); + CVector3D GetWorldCoordinates(int px, int py, bool aboveWater=false) const; // Get the point on the plane at height h corresponding to pixel (px,py) - CVector3D GetWorldCoordinates(int px, int py, float h); + CVector3D GetWorldCoordinates(int px, int py, float h) const; // Get the point on the terrain the camera is pointing towards CVector3D GetFocus(); diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp index c036c8ca68..7a8b4d24cd 100644 --- a/source/graphics/GameView.cpp +++ b/source/graphics/GameView.cpp @@ -54,21 +54,84 @@ #include "simulation/LOSManager.h" #include "simulation2/Simulation2.h" -float g_MaxZoomHeight=350.0f; //note: Max terrain height is this minus YMinOffset -float g_YMinOffset=15.0f; - - extern int g_xres, g_yres; -static CVector3D cameraBookmarks[10]; -static bool bookmarkInUse[10] = { false, false, false, false, false, false, false, false, false, false }; -static i8 currentBookmark = -1; - const float CGameView::defaultFOV = DEGTORAD(20.f); const float CGameView::defaultNear = 4.f; const float CGameView::defaultFar = 4096.f; const float CGameView::defaultCullFOV = CGameView::defaultFOV + DEGTORAD(6.0f); //add 6 degrees to the default FOV for use with the culling frustum +/** + * A value with exponential decay towards the target value. + */ +class CSmoothedValue +{ +public: + CSmoothedValue(float value, float smoothness, float minDelta) + : m_Target(value), m_Current(value), m_Smoothness(smoothness), m_MinDelta(minDelta) + { + } + + float GetSmoothedValue() + { + return m_Current; + } + + void SetValueSmoothly(float value) + { + m_Target = value; + } + + void AddSmoothly(float value) + { + m_Target += value; + } + + void Add(float value) + { + m_Target += value; + m_Current += value; + } + + float GetValue() + { + return m_Target; + } + + void SetValue(float value) + { + m_Target = value; + m_Current = value; + } + + float Update(float time) + { + if (fabs(m_Target - m_Current) < m_MinDelta) + return 0.0f; + + double p = pow((double)m_Smoothness, 10.0 * (double)time); + // (add the factor of 10 so that smoothnesses don't have to be tiny numbers) + + double delta = (m_Target - m_Current) * (1.0 - p); + m_Current += delta; + return (float)delta; + } + + void ClampSmoothly(float min, float max) + { + m_Target = Clamp(m_Target, (double)min, (double)max); + } + +private: + double m_Target; // the value which m_Current is tending towards + double m_Current; + // (We use double because the extra precision is worthwhile here) + + float m_MinDelta; // cutoff where we stop moving (to avoid ugly shimmering effects) +public: + float m_Smoothness; +}; + class CGameViewImpl : public CJSObject { NONCOPYABLE(CGameViewImpl); @@ -80,20 +143,31 @@ public: ViewCamera(), CullCamera(), LockCullCamera(false), + ConstrainCamera(true), Culling(true), - ViewScrollSpeed(60), - ViewRotateSensitivity(0.002f), - ViewRotateSensitivityKeyboard(1.0f), - ViewRotateAboutTargetSensitivity(0.010f), - ViewRotateAboutTargetSensitivityKeyboard(2.0f), - ViewDragSensitivity(0.5f), - ViewZoomSensitivityWheel(16.0f), - ViewZoomSensitivity(256.0f), - ViewZoomSmoothness(0.02f), - ViewSnapSmoothness(0.02f), - CameraDelta(), - CameraPivot(), - ZoomDelta(0) + + // Dummy values (these will be filled in by the config file) + ViewScrollSpeed(0), + ViewRotateXSpeed(0), + ViewRotateXMin(0), + ViewRotateXMax(0), + ViewRotateXDefault(0), + ViewRotateYSpeed(0), + ViewRotateYSpeedWheel(0), + ViewRotateYDefault(0), + ViewDragSpeed(0), + ViewZoomSpeed(0), + ViewZoomSpeedWheel(0), + ViewZoomMin(0), + ViewZoomMax(0), + ViewZoomDefault(0), + + PosX(0, 0, 0.01f), + PosY(0, 0, 0.01f), + PosZ(0, 0, 0.01f), + Zoom(0, 0, 0.1f), + RotateX(0, 0, 0.001f), + RotateY(0, 0, 0.001f) { } @@ -135,6 +209,12 @@ public: */ bool Culling; + /** + * Whether the camera movement should be constrained by min/max limits + * and terrain avoidance. + */ + bool ConstrainCamera; + /** * Cache global lighting environment. This is used to check whether the * environment has changed during the last frame, so that vertex data can be updated etc. @@ -146,32 +226,40 @@ public: //////////////////////////////////////// // Settings float ViewScrollSpeed; - float ViewRotateSensitivity; - float ViewRotateSensitivityKeyboard; - float ViewRotateAboutTargetSensitivity; - float ViewRotateAboutTargetSensitivityKeyboard; - float ViewDragSensitivity; - float ViewZoomSensitivityWheel; - float ViewZoomSensitivity; - float ViewZoomSmoothness; // 0.0 = instantaneous zooming, 1.0 = so slow it never moves - float ViewSnapSmoothness; // Just the same. - + float ViewRotateXSpeed; + float ViewRotateXMin; + float ViewRotateXMax; + float ViewRotateXDefault; + float ViewRotateYSpeed; + float ViewRotateYSpeedWheel; + float ViewRotateYDefault; + float ViewDragSpeed; + float ViewZoomSpeed; + float ViewZoomSpeedWheel; + float ViewZoomMin; + float ViewZoomMax; + float ViewZoomDefault; //////////////////////////////////////// // Camera Controls State - CVector3D CameraDelta; - CVector3D CameraPivot; - -// CEntity* UnitAttach; - //float m_CameraZoom; - std::vector CameraTargets; - - // Accumulate zooming changes across frames for smoothness - float ZoomDelta; + CSmoothedValue PosX; + CSmoothedValue PosY; + CSmoothedValue PosZ; + CSmoothedValue Zoom; + CSmoothedValue RotateX; // inclination around x axis (relative to camera) + CSmoothedValue RotateY; // rotation around y (vertical) axis static void ScriptingInit(); }; +static void SetupCameraMatrix(CGameViewImpl* m, CMatrix3D* orientation) +{ + orientation->SetIdentity(); + orientation->RotateX(m->RotateX.GetSmoothedValue()); + orientation->RotateY(m->RotateY.GetSmoothedValue()); + orientation->Translate(m->PosX.GetSmoothedValue(), m->PosY.GetSmoothedValue(), m->PosZ.GetSmoothedValue()); +} + CGameView::CGameView(CGame *pGame): m(new CGameViewImpl(pGame)) { @@ -183,9 +271,9 @@ CGameView::CGameView(CGame *pGame): m->ViewCamera.SetViewPort(vp); m->ViewCamera.SetProjection(defaultNear, defaultFar, defaultFOV); - m->ViewCamera.m_Orientation.SetXRotation(DEGTORAD(30)); - m->ViewCamera.m_Orientation.RotateY(DEGTORAD(0)); - m->ViewCamera.m_Orientation.Translate (100, 150, -100); + SetupCameraMatrix(m, &m->ViewCamera.m_Orientation); + m->ViewCamera.UpdateFrustum(); + m->CullCamera = m->ViewCamera; g_Renderer.SetSceneCamera(m->ViewCamera, m->CullCamera); } @@ -240,27 +328,37 @@ void CGameViewImpl::ScriptingInit() { AddProperty(L"culling", &CGameViewImpl::Culling); AddProperty(L"lockCullCamera", &CGameViewImpl::LockCullCamera); + AddProperty(L"constrainCamera", &CGameViewImpl::ConstrainCamera); CJSObject::ScriptingInit("GameView"); } int CGameView::Initialize() { - CFG_GET_SYS_VAL( "view.scroll.speed", Float, m->ViewScrollSpeed ); - CFG_GET_SYS_VAL( "view.rotate.speed", Float, m->ViewRotateSensitivity ); - CFG_GET_SYS_VAL( "view.rotate.keyboard.speed", Float, m->ViewRotateSensitivityKeyboard ); - CFG_GET_SYS_VAL( "view.rotate.abouttarget.speed", Float, m->ViewRotateAboutTargetSensitivity ); - CFG_GET_SYS_VAL( "view.rotate.keyboard.abouttarget.speed", Float, m->ViewRotateAboutTargetSensitivityKeyboard ); - CFG_GET_SYS_VAL( "view.drag.speed", Float, m->ViewDragSensitivity ); - CFG_GET_SYS_VAL( "view.zoom.speed", Float, m->ViewZoomSensitivity ); - CFG_GET_SYS_VAL( "view.zoom.wheel.speed", Float, m->ViewZoomSensitivityWheel ); - CFG_GET_SYS_VAL( "view.zoom.smoothness", Float, m->ViewZoomSmoothness ); - CFG_GET_SYS_VAL( "view.snap.smoothness", Float, m->ViewSnapSmoothness ); + CFG_GET_SYS_VAL("view.scroll.speed", Float, m->ViewScrollSpeed); + CFG_GET_SYS_VAL("view.rotate.x.speed", Float, m->ViewRotateXSpeed); + CFG_GET_SYS_VAL("view.rotate.x.min", Float, m->ViewRotateXMin); + CFG_GET_SYS_VAL("view.rotate.x.max", Float, m->ViewRotateXMax); + CFG_GET_SYS_VAL("view.rotate.x.default", Float, m->ViewRotateXDefault); + CFG_GET_SYS_VAL("view.rotate.y.speed", Float, m->ViewRotateYSpeed); + CFG_GET_SYS_VAL("view.rotate.y.speed.wheel", Float, m->ViewRotateYSpeedWheel); + CFG_GET_SYS_VAL("view.rotate.y.default", Float, m->ViewRotateYDefault); + CFG_GET_SYS_VAL("view.drag.speed", Float, m->ViewDragSpeed); + CFG_GET_SYS_VAL("view.zoom.speed", Float, m->ViewZoomSpeed); + CFG_GET_SYS_VAL("view.zoom.speed.wheel", Float, m->ViewZoomSpeedWheel); + CFG_GET_SYS_VAL("view.zoom.min", Float, m->ViewZoomMin); + CFG_GET_SYS_VAL("view.zoom.max", Float, m->ViewZoomMax); + CFG_GET_SYS_VAL("view.zoom.default", Float, m->ViewZoomDefault); - if( ( m->ViewZoomSmoothness < 0.0f ) || ( m->ViewZoomSmoothness > 1.0f ) ) - m->ViewZoomSmoothness = 0.02f; - if( ( m->ViewSnapSmoothness < 0.0f ) || ( m->ViewSnapSmoothness > 1.0f ) ) - m->ViewSnapSmoothness = 0.02f; + CFG_GET_SYS_VAL("view.pos.smoothness", Float, m->PosX.m_Smoothness); + CFG_GET_SYS_VAL("view.pos.smoothness", Float, m->PosY.m_Smoothness); + CFG_GET_SYS_VAL("view.pos.smoothness", Float, m->PosZ.m_Smoothness); + CFG_GET_SYS_VAL("view.zoom.smoothness", Float, m->Zoom.m_Smoothness); + CFG_GET_SYS_VAL("view.rotate.x.smoothness", Float, m->RotateX.m_Smoothness); + CFG_GET_SYS_VAL("view.rotate.y.smoothness", Float, m->RotateY.m_Smoothness); + + m->RotateX.SetValue(DEGTORAD(m->ViewRotateXDefault)); + m->RotateY.SetValue(DEGTORAD(m->ViewRotateYDefault)); return 0; } @@ -381,34 +479,6 @@ void CGameView::EnumerateObjects(const CFrustum& frustum, SceneCollector* c) } -//locks the camera in place -void CGameView::CameraLock(const CVector3D& Trans, bool smooth) -{ - CameraLock(Trans.X, Trans.Y, Trans.Z, smooth); -} - -void CGameView::CameraLock(float x, float y, float z, bool smooth) -{ - CTerrain* pTerrain = m->Game->GetWorld()->GetTerrain(); - float height = pTerrain->GetExactGroundLevel( - m->ViewCamera.m_Orientation._14 + x, m->ViewCamera.m_Orientation._34 + z) + - g_YMinOffset; - //is requested position within limits? - if (m->ViewCamera.m_Orientation._24 + y <= g_MaxZoomHeight) - { - if( m->ViewCamera.m_Orientation._24 + y >= height) - { - m->ViewCamera.m_Orientation.Translate(x, y, z); - } - else if (m->ViewCamera.m_Orientation._24 + y < height && smooth == true) - { - m->ViewCamera.m_Orientation.Translate(x, y, z); - m->ViewCamera.m_Orientation._24=height; - } - } -} - - static void MarkUpdateColorRecursive(CModel& model) { model.SetDirty(RENDERDATA_UPDATE_COLOR); @@ -449,37 +519,41 @@ void CGameView::UnloadResources() } -void CGameView::ResetCamera() +static void ClampDistance(CGameViewImpl* m, bool smooth) { - // quick hack to return camera home, for screenshots (after alt+tabbing) - m->ViewCamera.SetProjection (defaultNear, defaultFar, defaultFOV); - m->ViewCamera.m_Orientation.SetXRotation(DEGTORAD(30)); - m->ViewCamera.m_Orientation.RotateY(DEGTORAD(-45)); - m->ViewCamera.m_Orientation.Translate (100, 150, -100); -} + if (!m->ConstrainCamera) + return; -void CGameView::ResetCameraOrientation() -{ + CCamera targetCam = m->ViewCamera; + targetCam.m_Orientation.SetIdentity(); + targetCam.m_Orientation.RotateX(m->RotateX.GetSmoothedValue()); + targetCam.m_Orientation.RotateY(m->RotateY.GetSmoothedValue()); + // Use non-smoothed position: + targetCam.m_Orientation.Translate(m->PosX.GetValue(), m->PosY.GetValue(), m->PosZ.GetValue()); - CVector3D origin = m->ViewCamera.m_Orientation.GetTranslation(); - CVector3D dir = m->ViewCamera.m_Orientation.GetIn(); + CVector3D forwards = targetCam.m_Orientation.GetIn(); - CVector3D target = origin + dir * ( ( 50.0f - origin.Y ) / dir.Y ); + CVector3D delta = targetCam.GetFocus() - targetCam.m_Orientation.GetTranslation(); - target -= CVector3D( -22.474480f, 50.0f, 22.474480f ); + float dist = delta.Dot(forwards); + float clampedDist = Clamp(dist, m->ViewZoomMin, m->ViewZoomMax); + float diff = clampedDist - dist; - m->ViewCamera.SetProjection (defaultNear, defaultFar, defaultFOV); - m->ViewCamera.m_Orientation.SetXRotation(DEGTORAD(30)); - m->ViewCamera.m_Orientation.RotateY(DEGTORAD(-45)); + if (!diff) + return; - target += CVector3D( 100.0f, 150.0f, -100.0f ); - - m->ViewCamera.m_Orientation.Translate( target ); -} - -void CGameView::RotateAboutTarget() -{ - m->CameraPivot = m->ViewCamera.GetWorldCoordinates(g_mouse_x, g_mouse_y, true); + if (smooth) + { + m->PosX.AddSmoothly(forwards.X * -diff); + m->PosY.AddSmoothly(forwards.Y * -diff); + m->PosZ.AddSmoothly(forwards.Z * -diff); + } + else + { + m->PosX.Add(forwards.X * -diff); + m->PosY.Add(forwards.Y * -diff); + m->PosZ.Add(forwards.Z * -diff); + } } void CGameView::Update(float DeltaTime) @@ -491,33 +565,15 @@ void CGameView::Update(float DeltaTime) // in a CCmpWaterManager or some such thing (once such a thing exists) g_Renderer.GetWaterManager()->m_WaterTexTimer += DeltaTime; -/* - if (m->UnitAttach) - { - CVector3D ToMove = m->UnitAttach->m_position - m->ViewCamera.GetFocus(); - m->ViewCamera.m_Orientation._14 += ToMove.X; - m->ViewCamera.m_Orientation._34 += ToMove.Z; - m->ViewCamera.UpdateFrustum(); - return; - } -*/ - if (m->TrackManager.IsActive() && m->TrackManager.IsPlaying()) { if (! m->TrackManager.Update(DeltaTime)) - ResetCamera(); + { +// ResetCamera(); + } return; } - float delta = powf( m->ViewSnapSmoothness, DeltaTime ); - m->ViewCamera.m_Orientation.Translate( m->CameraDelta * ( 1.0f - delta ) ); - m->CameraDelta *= delta; - - - // This could be rewritten much more reliably, so it doesn't e.g. accidentally tilt - // the camera, assuming we know exactly what limits the camera should have. - - // Calculate mouse movement static int mouse_last_x = 0; static int mouse_last_y = 0; @@ -526,228 +582,194 @@ void CGameView::Update(float DeltaTime) mouse_last_x = g_mouse_x; mouse_last_y = g_mouse_y; - // Miscellaneous vectors - CVector3D forwards = m->ViewCamera.m_Orientation.GetIn(); - CVector3D rightwards = m->ViewCamera.m_Orientation.GetLeft() * -1.0f; // upwards.Cross(forwards); - CVector3D upwards( 0.0f, 1.0f, 0.0f ); - // rightwards.Normalize(); + if (hotkeys[HOTKEY_CAMERA_ROTATE_CW]) + m->RotateY.AddSmoothly(m->ViewRotateYSpeed * DeltaTime); + if (hotkeys[HOTKEY_CAMERA_ROTATE_CCW]) + m->RotateY.AddSmoothly(-m->ViewRotateYSpeed * DeltaTime); + if (hotkeys[HOTKEY_CAMERA_ROTATE_UP]) + m->RotateX.AddSmoothly(-m->ViewRotateXSpeed * DeltaTime); + if (hotkeys[HOTKEY_CAMERA_ROTATE_DOWN]) + m->RotateX.AddSmoothly(m->ViewRotateXSpeed * DeltaTime); - CVector3D forwards_horizontal = forwards; - forwards_horizontal.Y = 0.0f; - forwards_horizontal.Normalize(); + float moveRightward = 0.f; + float moveForward = 0.f; - if( hotkeys[HOTKEY_CAMERA_ROTATE] || hotkeys[HOTKEY_CAMERA_ROTATE_KEYBOARD] ) + if (hotkeys[HOTKEY_CAMERA_PAN]) { - // Ctrl + middle-drag or left-and-right-drag to rotate view - - // Untranslate the camera, so it rotates around the correct point - CVector3D position = m->ViewCamera.m_Orientation.GetTranslation(); - m->ViewCamera.m_Orientation.Translate(position*-1); - - // Sideways rotation - - float rightways = 0.0f; - if( hotkeys[HOTKEY_CAMERA_ROTATE] ) - rightways = (float)mouse_dx * m->ViewRotateSensitivity; - if( hotkeys[HOTKEY_CAMERA_ROTATE_KEYBOARD] ) - { - if( hotkeys[HOTKEY_CAMERA_LEFT] ) - rightways -= m->ViewRotateSensitivityKeyboard * DeltaTime; - if( hotkeys[HOTKEY_CAMERA_RIGHT] ) - rightways += m->ViewRotateSensitivityKeyboard * DeltaTime; - } - - m->ViewCamera.m_Orientation.RotateY( rightways ); - - // Up/down rotation - - float upways = 0.0f; - if( hotkeys[HOTKEY_CAMERA_ROTATE] ) - upways = (float)mouse_dy * m->ViewRotateSensitivity; - if( hotkeys[HOTKEY_CAMERA_ROTATE_KEYBOARD] ) - { - if( hotkeys[HOTKEY_CAMERA_UP] ) - upways -= m->ViewRotateSensitivityKeyboard * DeltaTime; - if( hotkeys[HOTKEY_CAMERA_DOWN] ) - upways += m->ViewRotateSensitivityKeyboard * DeltaTime; - } - - CQuaternion temp; - temp.FromAxisAngle(rightwards, upways); - - m->ViewCamera.m_Orientation.Rotate(temp); - - // Retranslate back to the right position - m->ViewCamera.m_Orientation.Translate(position); - - } - else if( hotkeys[HOTKEY_CAMERA_ROTATE_ABOUT_TARGET] ) - { - CVector3D origin = m->ViewCamera.m_Orientation.GetTranslation(); - CVector3D delta = origin - m->CameraPivot; - - CQuaternion rotateH, rotateV; CMatrix3D rotateM; - - // Sideways rotation - - float rightways = (float)mouse_dx * m->ViewRotateAboutTargetSensitivity; - - rotateH.FromAxisAngle( upwards, rightways ); - - // Up/down rotation - - float upways = (float)mouse_dy * m->ViewRotateAboutTargetSensitivity; - rotateV.FromAxisAngle( rightwards, upways ); - - rotateH *= rotateV; - rotateH.ToMatrix( rotateM ); - - delta = rotateM.Rotate( delta ); - - // Lock the inclination to a rather arbitrary values (for the sake of graphical decency) - - float scan = sqrt( delta.X * delta.X + delta.Z * delta.Z ) / delta.Y; - if( ( scan >= 0.5f ) ) - { - // Move the camera to the origin (in preparation for rotation ) - m->ViewCamera.m_Orientation.Translate( origin * -1.0f ); - - m->ViewCamera.m_Orientation.Rotate( rotateH ); - - // Move the camera back to where it belongs - m->ViewCamera.m_Orientation.Translate( m->CameraPivot + delta ); - } - - } - else if( hotkeys[HOTKEY_CAMERA_ROTATE_ABOUT_TARGET_KEYBOARD] ) - { - // Split up because the keyboard controls use the centre of the screen, not the mouse position. - CVector3D origin = m->ViewCamera.m_Orientation.GetTranslation(); - CVector3D pivot = m->ViewCamera.GetFocus(); - CVector3D delta = origin - pivot; - - CQuaternion rotateH, rotateV; CMatrix3D rotateM; - - // Sideways rotation - - float rightways = 0.0f; - if( hotkeys[HOTKEY_CAMERA_LEFT] ) - rightways -= m->ViewRotateAboutTargetSensitivityKeyboard * DeltaTime; - if( hotkeys[HOTKEY_CAMERA_RIGHT] ) - rightways += m->ViewRotateAboutTargetSensitivityKeyboard * DeltaTime; - - rotateH.FromAxisAngle( upwards, rightways ); - - // Up/down rotation - - float upways = 0.0f; - if( hotkeys[HOTKEY_CAMERA_UP] ) - upways -= m->ViewRotateAboutTargetSensitivityKeyboard * DeltaTime; - if( hotkeys[HOTKEY_CAMERA_DOWN] ) - upways += m->ViewRotateAboutTargetSensitivityKeyboard * DeltaTime; - - rotateV.FromAxisAngle( rightwards, upways ); - - rotateH *= rotateV; - rotateH.ToMatrix( rotateM ); - - delta = rotateM.Rotate( delta ); - - // Lock the inclination to a rather arbitrary values (for the sake of graphical decency) - - float scan = sqrt( delta.X * delta.X + delta.Z * delta.Z ) / delta.Y; - if( ( scan >= 0.5f ) ) - { - // Move the camera to the origin (in preparation for rotation ) - m->ViewCamera.m_Orientation.Translate( origin * -1.0f ); - - m->ViewCamera.m_Orientation.Rotate( rotateH ); - - // Move the camera back to where it belongs - m->ViewCamera.m_Orientation.Translate( pivot + delta ); - } - - } - else if( hotkeys[HOTKEY_CAMERA_PAN] ) - { - // Middle-drag to pan - //keep camera in bounds - CameraLock(rightwards * (m->ViewDragSensitivity * mouse_dx)); - CameraLock(forwards_horizontal * (-m->ViewDragSensitivity * mouse_dy)); + moveRightward += m->ViewDragSpeed * mouse_dx; + moveForward += m->ViewDragSpeed * -mouse_dy; } - // Mouse movement - if( g_mouse_active && !hotkeys[HOTKEY_CAMERA_ROTATE] && !hotkeys[HOTKEY_CAMERA_ROTATE_ABOUT_TARGET] ) + if (g_mouse_active) { - if (g_mouse_x >= g_xres-2 && g_mouse_x < g_xres) - CameraLock(rightwards * (m->ViewScrollSpeed * DeltaTime)); + if (g_mouse_x >= g_xres - 2 && g_mouse_x < g_xres) + moveRightward += m->ViewScrollSpeed * DeltaTime; else if (g_mouse_x <= 3 && g_mouse_x >= 0) - CameraLock(-rightwards * (m->ViewScrollSpeed * DeltaTime)); + moveRightward -= m->ViewScrollSpeed * DeltaTime; - if (g_mouse_y >= g_yres-2 && g_mouse_y < g_yres) - CameraLock(-forwards_horizontal * (m->ViewScrollSpeed * DeltaTime)); + if (g_mouse_y >= g_yres - 2 && g_mouse_y < g_yres) + moveForward -= m->ViewScrollSpeed * DeltaTime; else if (g_mouse_y <= 3 && g_mouse_y >= 0) - CameraLock(forwards_horizontal * (m->ViewScrollSpeed * DeltaTime)); - + moveForward += m->ViewScrollSpeed * DeltaTime; } - // Keyboard movement (added to mouse movement, so you can go faster if you want) - - if( hotkeys[HOTKEY_CAMERA_PAN_KEYBOARD] ) + if (hotkeys[HOTKEY_CAMERA_PAN_KEYBOARD]) { - if( hotkeys[HOTKEY_CAMERA_RIGHT] ) - CameraLock(rightwards * (m->ViewScrollSpeed * DeltaTime)); - if( hotkeys[HOTKEY_CAMERA_LEFT] ) - CameraLock(-rightwards * (m->ViewScrollSpeed * DeltaTime)); - - if( hotkeys[HOTKEY_CAMERA_DOWN] ) - CameraLock(-forwards_horizontal * (m->ViewScrollSpeed * DeltaTime)); - if( hotkeys[HOTKEY_CAMERA_UP] ) - CameraLock(forwards_horizontal * (m->ViewScrollSpeed * DeltaTime)); - + if (hotkeys[HOTKEY_CAMERA_RIGHT]) + moveRightward += m->ViewScrollSpeed * DeltaTime; + if (hotkeys[HOTKEY_CAMERA_LEFT]) + moveRightward -= m->ViewScrollSpeed * DeltaTime; + if (hotkeys[HOTKEY_CAMERA_UP]) + moveForward += m->ViewScrollSpeed * DeltaTime; + if (hotkeys[HOTKEY_CAMERA_DOWN]) + moveForward -= m->ViewScrollSpeed * DeltaTime; } - // Smoothed zooming (move a certain percentage towards the desired zoom distance every frame) - // Note that scroll wheel zooming is event-based and handled in game_view_handler - - if( hotkeys[HOTKEY_CAMERA_ZOOM_IN] ) - m->ZoomDelta += m->ViewZoomSensitivity*DeltaTime; - else if( hotkeys[HOTKEY_CAMERA_ZOOM_OUT] ) - m->ZoomDelta -= m->ViewZoomSensitivity*DeltaTime; - - if (fabsf(m->ZoomDelta) > 0.1f) // use a fairly high limit to avoid nasty flickering when zooming + if (moveRightward || moveForward) { - float zoom_proportion = powf(m->ViewZoomSmoothness, DeltaTime); - CameraLock(forwards * (m->ZoomDelta * (1.0f-zoom_proportion)), false); - m->ZoomDelta *= zoom_proportion; + float s = sin(m->RotateY.GetSmoothedValue()); + float c = cos(m->RotateY.GetSmoothedValue()); + m->PosX.AddSmoothly(c * moveRightward); + m->PosZ.AddSmoothly(-s * moveRightward); + m->PosX.AddSmoothly(s * moveForward); + m->PosZ.AddSmoothly(c * moveForward); } - m->ViewCamera.UpdateFrustum (); + if (hotkeys[HOTKEY_CAMERA_ZOOM_IN]) + m->Zoom.AddSmoothly(m->ViewZoomSpeed * DeltaTime); + if (hotkeys[HOTKEY_CAMERA_ZOOM_OUT]) + m->Zoom.AddSmoothly(-m->ViewZoomSpeed * DeltaTime); + + float zoomDelta = m->Zoom.Update(DeltaTime); + if (zoomDelta) + { + CVector3D forwards = m->ViewCamera.m_Orientation.GetIn(); + m->PosX.AddSmoothly(forwards.X * zoomDelta); + m->PosY.AddSmoothly(forwards.Y * zoomDelta); + m->PosZ.AddSmoothly(forwards.Z * zoomDelta); + } + + if (m->ConstrainCamera) + m->RotateX.ClampSmoothly(DEGTORAD(m->ViewRotateXMin), DEGTORAD(m->ViewRotateXMax)); + + ClampDistance(m, true); + + m->PosX.Update(DeltaTime); + m->PosY.Update(DeltaTime); + m->PosZ.Update(DeltaTime); + + // Handle rotation around the Y (vertical) axis + { + CCamera targetCam = m->ViewCamera; + SetupCameraMatrix(m, &targetCam.m_Orientation); + + float rotateYDelta = m->RotateY.Update(DeltaTime); + if (rotateYDelta) + { + // We've updated RotateY, and need to adjust Pos so that it's still + // facing towards the original focus point (the terrain in the center + // of the screen). + + CVector3D upwards(0.0f, 1.0f, 0.0f); + + CVector3D pivot = targetCam.GetFocus(); + CVector3D delta = targetCam.m_Orientation.GetTranslation() - pivot; + + CQuaternion q; + q.FromAxisAngle(upwards, rotateYDelta); + CVector3D d = q.Rotate(delta) - delta; + + m->PosX.Add(d.X); + m->PosY.Add(d.Y); + m->PosZ.Add(d.Z); + } + } + + // Handle rotation around the X (sideways, relative to camera) axis + { + CCamera targetCam = m->ViewCamera; + SetupCameraMatrix(m, &targetCam.m_Orientation); + + float rotateXDelta = m->RotateX.Update(DeltaTime); + if (rotateXDelta) + { + CVector3D rightwards = targetCam.m_Orientation.GetLeft() * -1.0f; + + CVector3D pivot = m->ViewCamera.GetFocus(); + CVector3D delta = targetCam.m_Orientation.GetTranslation() - pivot; + + CQuaternion q; + q.FromAxisAngle(rightwards, rotateXDelta); + CVector3D d = q.Rotate(delta) - delta; + + m->PosX.Add(d.X); + m->PosY.Add(d.Y); + m->PosZ.Add(d.Z); + } + } + + /* This is disabled since it doesn't seem necessary: + + // Ensure the camera's near point is never inside the terrain + if (m->ConstrainCamera) + { + CMatrix3D target; + target.SetIdentity(); + target.RotateX(m->RotateX.GetValue()); + target.RotateY(m->RotateY.GetValue()); + target.Translate(m->PosX.GetValue(), m->PosY.GetValue(), m->PosZ.GetValue()); + + CVector3D nearPoint = target.GetTranslation() + target.GetIn() * defaultNear; + float ground = m->Game->GetWorld()->GetTerrain()->GetExactGroundLevel(nearPoint.X, nearPoint.Z); + float limit = ground + 16.f; + if (nearPoint.Y < limit) + m->PosY.AddSmoothly(limit - nearPoint.Y); + } + */ + + // Update the camera matrix + SetupCameraMatrix(m, &m->ViewCamera.m_Orientation); + m->ViewCamera.UpdateFrustum(); } -void CGameView::PushCameraTarget( const CVector3D& target ) -{ - // Save the current position - m->CameraTargets.push_back( m->ViewCamera.m_Orientation.GetTranslation() ); - // And set the camera - SetCameraTarget( target ); -} - -void CGameView::SetCameraTarget( const CVector3D& target ) +void CGameView::MoveCameraTarget(const CVector3D& target) { // Maintain the same orientation and level of zoom, if we can // (do this by working out the point the camera is looking at, saving // the difference between that position and the camera point, and restoring // that difference to our new target) - CVector3D CurrentTarget = m->ViewCamera.GetFocus(); - m->CameraDelta = target - CurrentTarget; + CCamera targetCam = m->ViewCamera; + targetCam.m_Orientation.SetIdentity(); + targetCam.m_Orientation.RotateX(m->RotateX.GetValue()); + targetCam.m_Orientation.RotateY(m->RotateY.GetValue()); + targetCam.m_Orientation.Translate(m->PosX.GetValue(), m->PosY.GetValue(), m->PosZ.GetValue()); + + CVector3D pivot = targetCam.GetFocus(); + CVector3D delta = target - pivot; + m->PosX.SetValueSmoothly(delta.X + m->PosX.GetValue()); + m->PosY.SetValueSmoothly(delta.Y + m->PosY.GetValue()); + m->PosZ.SetValueSmoothly(delta.Z + m->PosZ.GetValue()); + + ClampDistance(m, false); } -void CGameView::PopCameraTarget() +void CGameView::ResetCameraTarget(const CVector3D& target) { - m->CameraDelta = m->CameraTargets.back() - m->ViewCamera.m_Orientation.GetTranslation(); - m->CameraTargets.pop_back(); + CMatrix3D orientation; + orientation.SetIdentity(); + orientation.RotateX(DEGTORAD(m->ViewRotateXDefault)); + orientation.RotateY(DEGTORAD(m->ViewRotateYDefault)); + + CVector3D delta = orientation.GetIn() * m->ViewZoomDefault; + m->PosX.SetValue(target.X - delta.X); + m->PosY.SetValue(target.Y - delta.Y); + m->PosZ.SetValue(target.Z - delta.Z); + + ClampDistance(m, false); + + SetupCameraMatrix(m, &m->ViewCamera.m_Orientation); + m->ViewCamera.UpdateFrustum(); } InReaction game_view_handler(const SDL_Event_* ev) @@ -786,73 +808,27 @@ InReaction CGameView::HandleEvent(const SDL_Event_* ev) g_Renderer.SetTerrainRenderMode(SOLID); g_Renderer.SetModelRenderMode(SOLID); } - return( IN_HANDLED ); - - case HOTKEY_CAMERA_RESET_ORIGIN: - ResetCamera(); - return( IN_HANDLED ); - - case HOTKEY_CAMERA_RESET: - ResetCameraOrientation(); - return( IN_HANDLED ); - - case HOTKEY_CAMERA_ROTATE_ABOUT_TARGET: - RotateAboutTarget(); - return( IN_HANDLED ); + return IN_HANDLED; // Mouse wheel must be treated using events instead of polling, // because SDL auto-generates a sequence of mousedown/mouseup events // and we never get to see the "down" state inside Update(). case HOTKEY_CAMERA_ZOOM_WHEEL_IN: - m->ZoomDelta += m->ViewZoomSensitivityWheel; - return( IN_HANDLED ); + m->Zoom.AddSmoothly(m->ViewZoomSpeedWheel); + return IN_HANDLED; case HOTKEY_CAMERA_ZOOM_WHEEL_OUT: - m->ZoomDelta -= m->ViewZoomSensitivityWheel; - return( IN_HANDLED ); + m->Zoom.AddSmoothly(-m->ViewZoomSpeedWheel); + return IN_HANDLED; - default: + case HOTKEY_CAMERA_ROTATE_WHEEL_CW: + m->RotateY.AddSmoothly(m->ViewRotateYSpeedWheel); + return IN_HANDLED; - if( ( ev->ev.user.code >= HOTKEY_CAMERA_BOOKMARK_0 ) && ( ev->ev.user.code <= HOTKEY_CAMERA_BOOKMARK_9 ) ) - { - // The above test limits it to 10 bookmarks, so don't worry about overflowing - i8 id = (i8)( ev->ev.user.code - HOTKEY_CAMERA_BOOKMARK_0 ); - - if( hotkeys[HOTKEY_CAMERA_BOOKMARK_SAVE] ) - { - // Attempt to track the ground we're looking at - cameraBookmarks[id] = GetCamera()->GetFocus(); - bookmarkInUse[id] = true; - } - else if( hotkeys[HOTKEY_CAMERA_BOOKMARK_SNAP] ) - { - if( bookmarkInUse[id] && ( currentBookmark == -1 ) ) - { - PushCameraTarget( cameraBookmarks[id] ); - currentBookmark = id; - } - } - else - { - if( bookmarkInUse[id] ) - SetCameraTarget( cameraBookmarks[id] ); - } - return( IN_HANDLED ); - } + case HOTKEY_CAMERA_ROTATE_WHEEL_CCW: + m->RotateY.AddSmoothly(-m->ViewRotateYSpeedWheel); + return IN_HANDLED; } - case SDL_HOTKEYUP: - switch( ev->ev.user.code ) - { - case HOTKEY_CAMERA_BOOKMARK_SNAP: - if( currentBookmark != -1 ) - PopCameraTarget(); - currentBookmark = -1; - break; - - default: - return( IN_PASS ); - } - return( IN_HANDLED ); } return IN_PASS; diff --git a/source/graphics/GameView.h b/source/graphics/GameView.h index 4d34798bc9..931b44d546 100644 --- a/source/graphics/GameView.h +++ b/source/graphics/GameView.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2010 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -81,22 +81,8 @@ public: InReaction HandleEvent(const SDL_Event_* ev); - //Keep the camera in between boundaries/smooth camera scrolling/translating - //Should call this whenever moving (translating) the camera - void CameraLock(const CVector3D& Trans, bool smooth=true); - void CameraLock(float x, float y, float z, bool smooth=true); - - // Camera Control Functions (used by input handler) - void ResetCamera(); - void ResetCameraOrientation(); - void RotateAboutTarget(); - - void PushCameraTarget( const CVector3D& target ); - void SetCameraTarget( const CVector3D& target ); - void PopCameraTarget(); - - //Keep view the same but follow the unit -// void AttachToUnit(CEntity* target); // TODO: reimplement this for new sim system + void MoveCameraTarget(const CVector3D& target); + void ResetCameraTarget(const CVector3D& target); CCamera *GetCamera(); CCinemaManager* GetCinema(); diff --git a/source/graphics/MapReader.cpp b/source/graphics/MapReader.cpp index ff08cc039e..953d708d03 100644 --- a/source/graphics/MapReader.cpp +++ b/source/graphics/MapReader.cpp @@ -21,6 +21,7 @@ #include "graphics/Camera.h" #include "graphics/CinemaTrack.h" +#include "graphics/GameView.h" #include "graphics/Patch.h" #include "graphics/Terrain.h" #include "graphics/TextureEntry.h" @@ -56,13 +57,13 @@ CMapReader::CMapReader() // LoadMap: try to load the map from given file; reinitialise the scene to new data if successful void CMapReader::LoadMap(const VfsPath& pathname, CTerrain *pTerrain_, WaterManager* pWaterMan_, SkyManager* pSkyMan_, - CLightEnv *pLightEnv_, CCamera *pCamera_, CCinemaManager* pCinema_, CTriggerManager* pTrigMan_, + CLightEnv *pLightEnv_, CGameView *pGameView_, CCinemaManager* pCinema_, CTriggerManager* pTrigMan_, CSimulation2 *pSimulation2_, int playerID_) { // latch parameters (held until DelayedLoadFinished) pTerrain = pTerrain_; pLightEnv = pLightEnv_; - pCamera = pCamera_; + pGameView = pGameView_; pWaterMan = pWaterMan_; pSkyMan = pSkyMan_; pCinema = pCinema_; @@ -220,22 +221,13 @@ int CMapReader::ApplyData() *pLightEnv = m_LightEnv; } - if (m_CameraStartupTarget != INVALID_ENTITY && pCamera) + if (m_CameraStartupTarget != INVALID_ENTITY && pGameView) { CmpPtr cmpPosition(*pSimulation2, m_CameraStartupTarget); if (!cmpPosition.null()) { - pCamera->m_Orientation.SetIdentity(); - - pCamera->m_Orientation.Translate(CVector3D(0.f, 0.f, -200.f)); // move backwards from the target entity - - pCamera->m_Orientation.RotateX(DEGTORAD(30)); - pCamera->m_Orientation.RotateY(DEGTORAD(0)); - CFixedVector3D pos = cmpPosition->GetPosition(); - pCamera->m_Orientation.Translate(CVector3D(pos.X.ToFloat(), pos.Y.ToFloat(), pos.Z.ToFloat())); - - pCamera->UpdateFrustum(); + pGameView->ResetCameraTarget(CVector3D(pos.X.ToFloat(), pos.Y.ToFloat(), pos.Z.ToFloat())); } } @@ -695,12 +687,12 @@ void CXMLReader::ReadCamera(XMBElement parent) debug_warn(L"Invalid map XML data"); } - if (m_MapReader.pCamera) + if (m_MapReader.pGameView) { - m_MapReader.pCamera->m_Orientation.SetXRotation(declination); - m_MapReader.pCamera->m_Orientation.RotateY(rotation); - m_MapReader.pCamera->m_Orientation.Translate(translation); - m_MapReader.pCamera->UpdateFrustum(); + m_MapReader.pGameView->GetCamera()->m_Orientation.SetXRotation(declination); + m_MapReader.pGameView->GetCamera()->m_Orientation.RotateY(rotation); + m_MapReader.pGameView->GetCamera()->m_Orientation.Translate(translation); + m_MapReader.pGameView->GetCamera()->UpdateFrustum(); } } diff --git a/source/graphics/MapReader.h b/source/graphics/MapReader.h index 6606ff6ccd..e707764aa8 100644 --- a/source/graphics/MapReader.h +++ b/source/graphics/MapReader.h @@ -30,13 +30,13 @@ class CTerrain; class WaterManager; class SkyManager; class CLightEnv; -class CCamera; class CCinemaManager; class CTriggerManager; class CSimulation2; class CTextureEntry; class CScriptValRooted; class ScriptInterface; +class CGameView; class CXMLReader; @@ -49,7 +49,7 @@ public: CMapReader(); // LoadMap: try to load the map from given file; reinitialise the scene to new data if successful void LoadMap(const VfsPath& pathname, CTerrain*, - WaterManager*, SkyManager*, CLightEnv*, CCamera*, + WaterManager*, SkyManager*, CLightEnv*, CGameView*, CCinemaManager*, CTriggerManager*, CSimulation2*, int playerID); private: @@ -89,7 +89,7 @@ private: WaterManager* pWaterMan; SkyManager* pSkyMan; CLightEnv* pLightEnv; - CCamera* pCamera; + CGameView* pGameView; CCinemaManager* pCinema; CTriggerManager* pTrigMan; CSimulation2* pSimulation2; diff --git a/source/graphics/MapWriter.cpp b/source/graphics/MapWriter.cpp index 5cf4af3409..e724a2f482 100644 --- a/source/graphics/MapWriter.cpp +++ b/source/graphics/MapWriter.cpp @@ -19,6 +19,7 @@ #include "Camera.h" #include "CinemaTrack.h" +#include "GameView.h" #include "LightEnv.h" #include "MapReader.h" #include "MapWriter.h" @@ -501,7 +502,7 @@ void CMapWriter::WriteTrigger(XMLWriter_File& xml_file_, const MapTrigger& trigg // RewriteAllMaps void CMapWriter::RewriteAllMaps(CTerrain* pTerrain, WaterManager* pWaterMan, SkyManager* pSkyMan, - CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema, + CLightEnv* pLightEnv, CGameView* pGameView, CCinemaManager* pCinema, CTriggerManager* pTrigMan, CSimulation2* pSimulation2) { VfsPaths pathnames; @@ -510,13 +511,13 @@ void CMapWriter::RewriteAllMaps(CTerrain* pTerrain, { CMapReader* reader = new CMapReader; LDR_BeginRegistering(); - reader->LoadMap(pathnames[i], pTerrain, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema, pTrigMan, pSimulation2, -1); + reader->LoadMap(pathnames[i], pTerrain, pWaterMan, pSkyMan, pLightEnv, pGameView, pCinema, pTrigMan, pSimulation2, -1); LDR_EndRegistering(); LDR_NonprogressiveLoad(); CStrW newPathname(pathnames[i].string()); newPathname.Replace(L"scenarios/", L"scenarios/new/"); CMapWriter writer; - writer.SaveMap(newPathname, pTerrain, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema, pSimulation2); + writer.SaveMap(newPathname, pTerrain, pWaterMan, pSkyMan, pLightEnv, pGameView->GetCamera(), pCinema, pSimulation2); } } diff --git a/source/graphics/MapWriter.h b/source/graphics/MapWriter.h index 8c0b79326b..20e4862110 100644 --- a/source/graphics/MapWriter.h +++ b/source/graphics/MapWriter.h @@ -51,7 +51,7 @@ public: // RewriteAllMaps: for use during development: load/save all maps, to // update them to the newest format. static void RewriteAllMaps(CTerrain* pTerrain, WaterManager* pWaterMan, - SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, + SkyManager* pSkyMan, CLightEnv* pLightEnv, CGameView* pGameView, CCinemaManager* pCinema, CTriggerManager* pTrigMan, CSimulation2* pSimulation2); diff --git a/source/gui/MiniMap.cpp b/source/gui/MiniMap.cpp index 18d3d1f700..fa1b3e9011 100644 --- a/source/gui/MiniMap.cpp +++ b/source/gui/MiniMap.cpp @@ -124,41 +124,14 @@ void CMiniMap::HandleMessage(const SGUIMessage &Message) void CMiniMap::SetCameraPos() { - CTerrain *MMTerrain=g_Game->GetWorld()->GetTerrain(); - CVector3D CamOrient=m_Camera->m_Orientation.GetTranslation(); + CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); - //get center point of screen - int x = g_Renderer.GetWidth()/2; - int y = g_Renderer.GetHeight()/2; - CVector3D ScreenMiddle=m_Camera->GetWorldCoordinates(x,y); - - //Get Vector required to go from camera position to ScreenMiddle - CVector3D TransVector; - TransVector.X=CamOrient.X-ScreenMiddle.X; - TransVector.Z=CamOrient.Z-ScreenMiddle.Z; - //world position of where mouse clicked - CVector3D Destination; - CPos MousePos = GetMousePos(); - //X and Z according to proportion of mouse position and minimap - Destination.X = CELL_SIZE * m_MapSize * - ( (MousePos.x - m_CachedActualSize.left) / m_CachedActualSize.GetWidth() ); - Destination.Z = CELL_SIZE * m_MapSize * ( (m_CachedActualSize.bottom - MousePos.y) / - m_CachedActualSize.GetHeight() ); - - m_Camera->m_Orientation._14=Destination.X; - m_Camera->m_Orientation._34=Destination.Z; - m_Camera->m_Orientation._14+=TransVector.X; - m_Camera->m_Orientation._34+=TransVector.Z; - - //Lock Y coord. No risk of zoom exceeding limit-Y does not increase - float Height=MMTerrain->GetExactGroundLevel( - m_Camera->m_Orientation._14, m_Camera->m_Orientation._34) + g_YMinOffset; - - if (m_Camera->m_Orientation._24 < Height) - { - m_Camera->m_Orientation._24=Height; - } - m_Camera->UpdateFrustum(); + CVector3D target; + CPos mousePos = GetMousePos(); + target.X = CELL_SIZE * m_MapSize * ((mousePos.x - m_CachedActualSize.left) / m_CachedActualSize.GetWidth()); + target.Z = CELL_SIZE * m_MapSize * ((m_CachedActualSize.bottom - mousePos.y) / m_CachedActualSize.GetHeight()); + target.Y = terrain->GetExactGroundLevel(target.X, target.Z); + g_Game->GetView()->MoveCameraTarget(target); } void CMiniMap::FireWorldClickEvent(int button, int clicks) diff --git a/source/gui/MiniMap.h b/source/gui/MiniMap.h index 751cd4e5a5..42907a06f2 100644 --- a/source/gui/MiniMap.h +++ b/source/gui/MiniMap.h @@ -55,8 +55,7 @@ protected: // the terrain we are mini-mapping const CTerrain* m_Terrain; - // not const: camera is moved by clicking on minimap - CCamera* m_Camera; + const CCamera* m_Camera; //Whether or not the mouse is currently down bool m_Clicking; diff --git a/source/ps/Hotkey.cpp b/source/ps/Hotkey.cpp index b00f07da5a..fc179912b1 100644 --- a/source/ps/Hotkey.cpp +++ b/source/ps/Hotkey.cpp @@ -73,36 +73,22 @@ static SHotkeyInfo hotkeyInfo[] = { HOTKEY_BIGSCREENSHOT, "bigscreenshot", 0, 0 }, { HOTKEY_WIREFRAME, "wireframe", SDLK_w, 0 }, { HOTKEY_TOGGLEFULLSCREEN, "togglefullscreen", 0, 0 }, - { HOTKEY_CAMERA_RESET, "camera.reset", 0, 0 }, - { HOTKEY_CAMERA_RESET_ORIGIN, "camera.reset.origin", SDLK_h, 0 }, { HOTKEY_CAMERA_ZOOM_IN, "camera.zoom.in", SDLK_PLUS, SDLK_KP_PLUS }, { HOTKEY_CAMERA_ZOOM_OUT, "camera.zoom.out", SDLK_MINUS, SDLK_KP_MINUS }, { HOTKEY_CAMERA_ZOOM_WHEEL_IN, "camera.zoom.wheel.in", MOUSE_WHEELUP, 0 }, { HOTKEY_CAMERA_ZOOM_WHEEL_OUT, "camera.zoom.wheel.out", MOUSE_WHEELDOWN, 0 }, - { HOTKEY_CAMERA_ROTATE, "camera.rotate", 0, 0 }, - { HOTKEY_CAMERA_ROTATE_KEYBOARD, "camera.rotate.keyboard", 0, 0 }, - { HOTKEY_CAMERA_ROTATE_ABOUT_TARGET, "camera.rotate.abouttarget", 0, 0 }, - { HOTKEY_CAMERA_ROTATE_ABOUT_TARGET_KEYBOARD, "camera.rotate.abouttarget.keyboard", 0, 0 }, + { HOTKEY_CAMERA_ROTATE_CW, "camera.rotate.cw", 0, 0 }, + { HOTKEY_CAMERA_ROTATE_CCW, "camera.rotate.ccw", 0, 0 }, + { HOTKEY_CAMERA_ROTATE_UP, "camera.rotate.up", 0, 0 }, + { HOTKEY_CAMERA_ROTATE_DOWN, "camera.rotate.down", 0, 0 }, + { HOTKEY_CAMERA_ROTATE_WHEEL_CW, "camera.rotate.wheel.cw", 0, 0 }, + { HOTKEY_CAMERA_ROTATE_WHEEL_CCW, "camera.rotate.wheel.ccw", 0, 0 }, { HOTKEY_CAMERA_PAN, "camera.pan", MOUSE_MIDDLE, 0 }, { HOTKEY_CAMERA_PAN_KEYBOARD, "camera.pan.keyboard", 0, 0 }, { HOTKEY_CAMERA_LEFT, "camera.left", SDLK_LEFT, 0 }, { HOTKEY_CAMERA_RIGHT, "camera.right", SDLK_RIGHT, 0 }, { HOTKEY_CAMERA_UP, "camera.up", SDLK_UP, 0 }, { HOTKEY_CAMERA_DOWN, "camera.down", SDLK_DOWN, 0 }, - { HOTKEY_CAMERA_UNIT_VIEW, "camera.unit.view", SDLK_u, 0 }, - { HOTKEY_CAMERA_UNIT_ATTACH, "camera.unit.attach", SDLK_l, 0 }, - { HOTKEY_CAMERA_BOOKMARK_0, "camera.bookmark.0", SDLK_F5, 0, }, - { HOTKEY_CAMERA_BOOKMARK_1, "camera.bookmark.1", SDLK_F6, 0, }, - { HOTKEY_CAMERA_BOOKMARK_2, "camera.bookmark.2", SDLK_F7, 0, }, - { HOTKEY_CAMERA_BOOKMARK_3, "camera.bookmark.3", SDLK_F8, 0, }, - { HOTKEY_CAMERA_BOOKMARK_4, "camera.bookmark.4", 0, 0, }, - { HOTKEY_CAMERA_BOOKMARK_5, "camera.bookmark.5", 0, 0, }, - { HOTKEY_CAMERA_BOOKMARK_6, "camera.bookmark.6", 0, 0, }, - { HOTKEY_CAMERA_BOOKMARK_7, "camera.bookmark.7", 0, 0, }, - { HOTKEY_CAMERA_BOOKMARK_8, "camera.bookmark.8", 0, 0, }, - { HOTKEY_CAMERA_BOOKMARK_9, "camera.bookmark.9", 0, 0, }, - { HOTKEY_CAMERA_BOOKMARK_SAVE, "camera.bookmark.save", 0, 0 }, - { HOTKEY_CAMERA_BOOKMARK_SNAP, "camera.bookmark.snap", 0, 0 }, { HOTKEY_CAMERA_CINEMA_ADD, "camera.cinema.add", SDLK_l, 0 }, { HOTKEY_CAMERA_CINEMA_DELETE, "camera.cinema.delete", SDLK_u, 0 }, { HOTKEY_CAMERA_CINEMA_DELETE_ALL, "camera.cinema.delete.all", SDLK_r, 0 }, diff --git a/source/ps/Hotkey.h b/source/ps/Hotkey.h index ffc1de401e..0421607fb2 100644 --- a/source/ps/Hotkey.h +++ b/source/ps/Hotkey.h @@ -54,36 +54,22 @@ enum HOTKEY_BIGSCREENSHOT, HOTKEY_WIREFRAME, HOTKEY_TOGGLEFULLSCREEN, - HOTKEY_CAMERA_RESET, - HOTKEY_CAMERA_RESET_ORIGIN, HOTKEY_CAMERA_ZOOM_IN, HOTKEY_CAMERA_ZOOM_OUT, HOTKEY_CAMERA_ZOOM_WHEEL_IN, HOTKEY_CAMERA_ZOOM_WHEEL_OUT, - HOTKEY_CAMERA_ROTATE, - HOTKEY_CAMERA_ROTATE_KEYBOARD, - HOTKEY_CAMERA_ROTATE_ABOUT_TARGET, - HOTKEY_CAMERA_ROTATE_ABOUT_TARGET_KEYBOARD, + HOTKEY_CAMERA_ROTATE_CW, + HOTKEY_CAMERA_ROTATE_CCW, + HOTKEY_CAMERA_ROTATE_UP, + HOTKEY_CAMERA_ROTATE_DOWN, + HOTKEY_CAMERA_ROTATE_WHEEL_CW, + HOTKEY_CAMERA_ROTATE_WHEEL_CCW, HOTKEY_CAMERA_PAN, HOTKEY_CAMERA_PAN_KEYBOARD, HOTKEY_CAMERA_LEFT, HOTKEY_CAMERA_RIGHT, HOTKEY_CAMERA_UP, HOTKEY_CAMERA_DOWN, - HOTKEY_CAMERA_UNIT_VIEW, - HOTKEY_CAMERA_UNIT_ATTACH, - HOTKEY_CAMERA_BOOKMARK_0, - HOTKEY_CAMERA_BOOKMARK_1, - HOTKEY_CAMERA_BOOKMARK_2, - HOTKEY_CAMERA_BOOKMARK_3, - HOTKEY_CAMERA_BOOKMARK_4, - HOTKEY_CAMERA_BOOKMARK_5, - HOTKEY_CAMERA_BOOKMARK_6, - HOTKEY_CAMERA_BOOKMARK_7, - HOTKEY_CAMERA_BOOKMARK_8, - HOTKEY_CAMERA_BOOKMARK_9, - HOTKEY_CAMERA_BOOKMARK_SAVE, - HOTKEY_CAMERA_BOOKMARK_SNAP, HOTKEY_CAMERA_CINEMA_ADD, HOTKEY_CAMERA_CINEMA_DELETE, HOTKEY_CAMERA_CINEMA_DELETE_ALL, diff --git a/source/ps/World.cpp b/source/ps/World.cpp index d91595625c..05ad682ab3 100644 --- a/source/ps/World.cpp +++ b/source/ps/World.cpp @@ -81,8 +81,7 @@ void CWorld::RegisterInit(const CStrW& mapFile, int playerID) reader->LoadMap(mapfilename, m_Terrain, CRenderer::IsInitialised() ? g_Renderer.GetWaterManager() : NULL, CRenderer::IsInitialised() ? g_Renderer.GetSkyManager() : NULL, - &g_LightEnv, - m_pGame->GetView() ? m_pGame->GetView()->GetCamera() : NULL, + &g_LightEnv, m_pGame->GetView(), m_pGame->GetView() ? m_pGame->GetView()->GetCinema() : NULL, pTriggerManager, m_pGame->GetSimulation2(), playerID); // fails immediately, or registers for delay loading @@ -117,7 +116,7 @@ void CWorld::RewriteMap() { CMapWriter::RewriteAllMaps(m_Terrain, g_Renderer.GetWaterManager(), g_Renderer.GetSkyManager(), - &g_LightEnv, m_pGame->GetView()->GetCamera(), + &g_LightEnv, m_pGame->GetView(), m_pGame->GetView()->GetCinema(), NULL, m_pGame->GetSimulation2()); } diff --git a/source/renderer/TerrainRenderer.cpp b/source/renderer/TerrainRenderer.cpp index 6376c7963e..78bfd3ba5a 100644 --- a/source/renderer/TerrainRenderer.cpp +++ b/source/renderer/TerrainRenderer.cpp @@ -435,7 +435,7 @@ void TerrainRenderer::RenderWater() } //(Crappy) fresnel effect - CCamera* Camera=g_Game->GetView()->GetCamera(); + const CCamera* Camera=g_Game->GetView()->GetCamera(); CVector3D CamFace=Camera->m_Orientation.GetIn(); CamFace.Normalize(); float FresnelScalar = CamFace.Dot( CVector3D(0.0f, -1.0f, 0.0f) ); diff --git a/source/scripting/ScriptGlue.cpp b/source/scripting/ScriptGlue.cpp index ddf789d85e..32694b6714 100644 --- a/source/scripting/ScriptGlue.cpp +++ b/source/scripting/ScriptGlue.cpp @@ -398,7 +398,7 @@ JSBool SetCameraTarget( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* JS_ReportError( cx, "Invalid camera target" ); return( JS_TRUE ); } - g_Game->GetView()->SetCameraTarget( *target ); + g_Game->GetView()->ResetCameraTarget( *target ); *rval = JSVAL_TRUE; return( JS_TRUE ); diff --git a/source/simulation2/helpers/Selection.cpp b/source/simulation2/helpers/Selection.cpp index afb5e081cc..ef742eabc7 100644 --- a/source/simulation2/helpers/Selection.cpp +++ b/source/simulation2/helpers/Selection.cpp @@ -25,7 +25,7 @@ #include "simulation2/components/ICmpSelectable.h" #include "simulation2/components/ICmpVisual.h" -std::vector EntitySelection::PickEntitiesAtPoint(CSimulation2& simulation, CCamera& camera, int screenX, int screenY) +std::vector EntitySelection::PickEntitiesAtPoint(CSimulation2& simulation, const CCamera& camera, int screenX, int screenY) { CVector3D origin, dir; camera.BuildCameraRay(screenX, screenY, origin, dir); @@ -71,7 +71,7 @@ std::vector EntitySelection::PickEntitiesAtPoint(CSimulation2& simu return hitEnts; } -std::vector EntitySelection::PickEntitiesInRect(CSimulation2& simulation, CCamera& camera, int sx0, int sy0, int sx1, int sy1, int owner) +std::vector EntitySelection::PickEntitiesInRect(CSimulation2& simulation, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, int owner) { // Make sure sx0 <= sx1, and sy0 <= sy1 if (sx0 > sx1) diff --git a/source/simulation2/helpers/Selection.h b/source/simulation2/helpers/Selection.h index 82447f284c..3bf631faf1 100644 --- a/source/simulation2/helpers/Selection.h +++ b/source/simulation2/helpers/Selection.h @@ -37,14 +37,14 @@ namespace EntitySelection * Finds all selectable entities under the given screen coordinates. * Returns list ordered by closeness of picking, closest first. */ -std::vector PickEntitiesAtPoint(CSimulation2& simulation, CCamera& camera, int screenX, int screenY); +std::vector PickEntitiesAtPoint(CSimulation2& simulation, const CCamera& camera, int screenX, int screenY); /** * Finds all selectable entities within the given screen coordinate rectangle, * that belong to player @p owner. * Returns unordered list. */ -std::vector PickEntitiesInRect(CSimulation2& simulation, CCamera& camera, int sx0, int sy0, int sx1, int sy1, int owner); +std::vector PickEntitiesInRect(CSimulation2& simulation, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, int owner); } // namespace diff --git a/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp b/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp index adf368ef98..ebd79125d6 100644 --- a/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp +++ b/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp @@ -161,7 +161,9 @@ MESSAGEHANDLER(CinemaEvent) else if ( msg->mode == eCinemaEventMode::IMMEDIATE_PATH ) manager->MoveToPointAt(msg->t); else if ( msg->mode == eCinemaEventMode::RESET ) - g_Game->GetView()->ResetCamera(); + { +// g_Game->GetView()->ResetCamera(); + } else if ( msg->mode == eCinemaEventMode::SELECT ) manager->SetCurrentPath(*msg->path, msg->drawCurrent, msg->lines); else