2011-03-04 21:02:05 +01:00
|
|
|
/* Copyright (C) 2011 Wildfire Games.
|
2009-04-18 19:00:33 +02:00
|
|
|
* This file is part of 0 A.D.
|
|
|
|
*
|
|
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 0 A.D. is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2004-07-27 23:00:53 +02:00
|
|
|
#include "precompiled.h"
|
|
|
|
|
|
|
|
#include "GameView.h"
|
|
|
|
|
2006-06-09 20:32:00 +02:00
|
|
|
#include "graphics/Camera.h"
|
2007-01-08 02:56:46 +01:00
|
|
|
#include "graphics/CinemaTrack.h"
|
2007-03-01 19:52:53 +01:00
|
|
|
#include "graphics/ColladaManager.h"
|
2006-06-09 20:32:00 +02:00
|
|
|
#include "graphics/HFTracer.h"
|
|
|
|
#include "graphics/LightEnv.h"
|
2011-02-03 02:12:24 +01:00
|
|
|
#include "graphics/LOSTexture.h"
|
2006-06-09 20:32:00 +02:00
|
|
|
#include "graphics/Model.h"
|
|
|
|
#include "graphics/ObjectManager.h"
|
|
|
|
#include "graphics/Patch.h"
|
2007-03-01 19:52:53 +01:00
|
|
|
#include "graphics/SkeletonAnimManager.h"
|
2006-06-09 20:32:00 +02:00
|
|
|
#include "graphics/Terrain.h"
|
2010-09-04 23:26:52 +02:00
|
|
|
#include "graphics/TerrainTextureManager.h"
|
2011-07-20 21:48:06 +02:00
|
|
|
#include "graphics/TerritoryTexture.h"
|
2006-06-09 20:32:00 +02:00
|
|
|
#include "graphics/Unit.h"
|
|
|
|
#include "graphics/UnitManager.h"
|
|
|
|
#include "lib/input.h"
|
|
|
|
#include "lib/timer.h"
|
2006-06-02 04:10:27 +02:00
|
|
|
#include "maths/Bound.h"
|
2006-06-09 20:32:00 +02:00
|
|
|
#include "maths/MathUtil.h"
|
|
|
|
#include "maths/Matrix3D.h"
|
|
|
|
#include "maths/Quaternion.h"
|
2006-06-02 04:10:27 +02:00
|
|
|
#include "ps/ConfigDB.h"
|
2006-06-09 20:32:00 +02:00
|
|
|
#include "ps/Game.h"
|
|
|
|
#include "ps/Globals.h"
|
|
|
|
#include "ps/Hotkey.h"
|
2010-12-30 20:45:13 +01:00
|
|
|
#include "ps/Joystick.h"
|
2006-06-02 04:10:27 +02:00
|
|
|
#include "ps/Loader.h"
|
2005-10-20 17:27:39 +02:00
|
|
|
#include "ps/LoaderThunks.h"
|
2006-06-09 20:32:00 +02:00
|
|
|
#include "ps/Profile.h"
|
|
|
|
#include "ps/Pyrogenesis.h"
|
2010-05-20 20:09:23 +02:00
|
|
|
#include "ps/World.h"
|
2006-06-09 20:32:00 +02:00
|
|
|
#include "renderer/Renderer.h"
|
|
|
|
#include "renderer/WaterManager.h"
|
2007-01-08 02:56:46 +01:00
|
|
|
#include "scripting/ScriptableObject.h"
|
2010-01-09 20:20:14 +01:00
|
|
|
#include "simulation2/Simulation2.h"
|
2010-09-27 01:05:25 +02:00
|
|
|
#include "simulation2/components/ICmpPosition.h"
|
2011-03-04 21:02:05 +01:00
|
|
|
#include "simulation2/components/ICmpRangeManager.h"
|
2004-12-12 20:43:55 +01:00
|
|
|
|
2004-07-31 17:57:18 +02:00
|
|
|
extern int g_xres, g_yres;
|
|
|
|
|
2011-03-04 21:02:05 +01:00
|
|
|
// Maximum distance outside the edge of the map that the camera's
|
|
|
|
// focus point can be moved
|
|
|
|
static const float CAMERA_EDGE_MARGIN = 2.0f*CELL_SIZE;
|
2006-03-21 21:55:45 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
|
2010-08-14 02:52:19 +02:00
|
|
|
// Wrap so 'target' is in the range [min, max]
|
|
|
|
void Wrap(float min, float max)
|
|
|
|
{
|
|
|
|
double t = fmod(m_Target - min, (double)(max - min));
|
|
|
|
if (t < 0)
|
|
|
|
t += max - min;
|
|
|
|
t += min;
|
|
|
|
|
|
|
|
m_Current += t - m_Target;
|
|
|
|
m_Target = t;
|
|
|
|
}
|
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2009-01-03 19:40:28 +01:00
|
|
|
class CGameViewImpl : public CJSObject<CGameViewImpl>
|
2007-01-08 02:56:46 +01:00
|
|
|
{
|
2009-01-03 19:40:28 +01:00
|
|
|
NONCOPYABLE(CGameViewImpl);
|
2007-01-08 02:56:46 +01:00
|
|
|
public:
|
|
|
|
CGameViewImpl(CGame* game)
|
2007-03-01 19:52:53 +01:00
|
|
|
: Game(game),
|
|
|
|
ColladaManager(), MeshManager(ColladaManager), SkeletonAnimManager(ColladaManager),
|
2010-06-03 03:29:43 +02:00
|
|
|
ObjectManager(MeshManager, SkeletonAnimManager, *game->GetSimulation2()),
|
2011-04-05 22:32:03 +02:00
|
|
|
LOSTexture(*game->GetSimulation2()),
|
2011-07-20 21:48:06 +02:00
|
|
|
TerritoryTexture(*game->GetSimulation2()),
|
2007-01-08 02:56:46 +01:00
|
|
|
ViewCamera(),
|
|
|
|
CullCamera(),
|
|
|
|
LockCullCamera(false),
|
2010-08-13 15:26:29 +02:00
|
|
|
ConstrainCamera(true),
|
2007-01-08 02:56:46 +01:00
|
|
|
Culling(true),
|
2010-09-27 01:05:25 +02:00
|
|
|
FollowEntity(INVALID_ENTITY),
|
2010-11-01 22:40:29 +01:00
|
|
|
FollowFirstPerson(false),
|
2010-08-13 15:26:29 +02:00
|
|
|
|
|
|
|
// 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),
|
2010-12-30 20:45:13 +01:00
|
|
|
JoystickPanX(-1),
|
|
|
|
JoystickPanY(-1),
|
|
|
|
JoystickRotateX(-1),
|
|
|
|
JoystickRotateY(-1),
|
|
|
|
JoystickZoomIn(-1),
|
|
|
|
JoystickZoomOut(-1),
|
2010-08-13 15:26:29 +02:00
|
|
|
|
|
|
|
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)
|
2007-01-08 02:56:46 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
CGame* Game;
|
2007-03-01 19:52:53 +01:00
|
|
|
CColladaManager ColladaManager;
|
2007-01-08 02:56:46 +01:00
|
|
|
CMeshManager MeshManager;
|
2007-03-01 19:52:53 +01:00
|
|
|
CSkeletonAnimManager SkeletonAnimManager;
|
2007-01-08 02:56:46 +01:00
|
|
|
CObjectManager ObjectManager;
|
2011-02-03 02:12:24 +01:00
|
|
|
CLOSTexture LOSTexture;
|
2011-07-20 21:48:06 +02:00
|
|
|
CTerritoryTexture TerritoryTexture;
|
2007-01-08 02:56:46 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* this camera controls the eye position when rendering
|
|
|
|
*/
|
|
|
|
CCamera ViewCamera;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this camera controls the frustum that is used for culling
|
|
|
|
* and shadow calculations
|
|
|
|
*
|
|
|
|
* Note that all code that works with camera movements should only change
|
|
|
|
* m_ViewCamera. The render functions automatically sync the cull camera to
|
|
|
|
* the view camera depending on the value of m_LockCullCamera.
|
|
|
|
*/
|
|
|
|
CCamera CullCamera;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* When @c true, the cull camera is locked in place.
|
|
|
|
* When @c false, the cull camera follows the view camera.
|
|
|
|
*
|
|
|
|
* Exposed to JS as gameView.lockCullCamera
|
|
|
|
*/
|
|
|
|
bool LockCullCamera;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* When @c true, culling is enabled so that only models that have a chance of
|
|
|
|
* being visible are sent to the renderer.
|
|
|
|
* Otherwise, the entire world is sent to the renderer.
|
|
|
|
*
|
|
|
|
* Exposed to JS as gameView.culling
|
|
|
|
*/
|
|
|
|
bool Culling;
|
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
/**
|
|
|
|
* Whether the camera movement should be constrained by min/max limits
|
|
|
|
* and terrain avoidance.
|
|
|
|
*/
|
|
|
|
bool ConstrainCamera;
|
|
|
|
|
2007-01-08 02:56:46 +01:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
CLightEnv CachedLightEnv;
|
|
|
|
|
|
|
|
CCinemaManager TrackManager;
|
|
|
|
|
2010-09-27 01:05:25 +02:00
|
|
|
/**
|
|
|
|
* Entity for the camera to follow, or INVALID_ENTITY if none.
|
|
|
|
*/
|
|
|
|
entity_id_t FollowEntity;
|
|
|
|
|
2010-11-01 22:40:29 +01:00
|
|
|
/**
|
|
|
|
* Whether to follow FollowEntity in first-person mode.
|
|
|
|
*/
|
|
|
|
bool FollowFirstPerson;
|
|
|
|
|
2007-01-08 02:56:46 +01:00
|
|
|
////////////////////////////////////////
|
|
|
|
// Settings
|
|
|
|
float ViewScrollSpeed;
|
2010-08-13 15:26:29 +02:00
|
|
|
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;
|
2011-11-18 00:34:01 +01:00
|
|
|
float ViewFOV;
|
|
|
|
float ViewNear;
|
|
|
|
float ViewFar;
|
2010-12-30 20:45:13 +01:00
|
|
|
int JoystickPanX;
|
|
|
|
int JoystickPanY;
|
|
|
|
int JoystickRotateX;
|
|
|
|
int JoystickRotateY;
|
|
|
|
int JoystickZoomIn;
|
|
|
|
int JoystickZoomOut;
|
2007-01-08 02:56:46 +01:00
|
|
|
|
|
|
|
////////////////////////////////////////
|
|
|
|
// Camera Controls State
|
2010-08-13 15:26:29 +02:00
|
|
|
CSmoothedValue PosX;
|
|
|
|
CSmoothedValue PosY;
|
|
|
|
CSmoothedValue PosZ;
|
|
|
|
CSmoothedValue Zoom;
|
|
|
|
CSmoothedValue RotateX; // inclination around x axis (relative to camera)
|
|
|
|
CSmoothedValue RotateY; // rotation around y (vertical) axis
|
2007-01-08 02:56:46 +01:00
|
|
|
|
|
|
|
static void ScriptingInit();
|
|
|
|
};
|
|
|
|
|
2011-03-04 21:02:05 +01:00
|
|
|
static void SetupCameraMatrixSmooth(CGameViewImpl* m, CMatrix3D* orientation)
|
2010-08-13 15:26:29 +02:00
|
|
|
{
|
|
|
|
orientation->SetIdentity();
|
|
|
|
orientation->RotateX(m->RotateX.GetSmoothedValue());
|
|
|
|
orientation->RotateY(m->RotateY.GetSmoothedValue());
|
|
|
|
orientation->Translate(m->PosX.GetSmoothedValue(), m->PosY.GetSmoothedValue(), m->PosZ.GetSmoothedValue());
|
|
|
|
}
|
|
|
|
|
2011-03-04 21:02:05 +01:00
|
|
|
static void SetupCameraMatrixSmoothRot(CGameViewImpl* m, CMatrix3D* orientation)
|
|
|
|
{
|
|
|
|
orientation->SetIdentity();
|
|
|
|
orientation->RotateX(m->RotateX.GetSmoothedValue());
|
|
|
|
orientation->RotateY(m->RotateY.GetSmoothedValue());
|
|
|
|
orientation->Translate(m->PosX.GetValue(), m->PosY.GetValue(), m->PosZ.GetValue());
|
|
|
|
}
|
|
|
|
|
|
|
|
static void SetupCameraMatrixNonSmooth(CGameViewImpl* m, CMatrix3D* orientation)
|
|
|
|
{
|
|
|
|
orientation->SetIdentity();
|
|
|
|
orientation->RotateX(m->RotateX.GetValue());
|
|
|
|
orientation->RotateY(m->RotateY.GetValue());
|
|
|
|
orientation->Translate(m->PosX.GetValue(), m->PosY.GetValue(), m->PosZ.GetValue());
|
|
|
|
}
|
|
|
|
|
2004-07-27 23:00:53 +02:00
|
|
|
CGameView::CGameView(CGame *pGame):
|
2007-01-08 02:56:46 +01:00
|
|
|
m(new CGameViewImpl(pGame))
|
2004-07-31 17:57:18 +02:00
|
|
|
{
|
|
|
|
SViewPort vp;
|
|
|
|
vp.m_X=0;
|
|
|
|
vp.m_Y=0;
|
|
|
|
vp.m_Width=g_xres;
|
|
|
|
vp.m_Height=g_yres;
|
2010-06-03 21:07:59 +02:00
|
|
|
m->ViewCamera.SetViewPort(vp);
|
2004-07-31 17:57:18 +02:00
|
|
|
|
2011-11-18 00:34:01 +01:00
|
|
|
m->ViewCamera.SetProjection(m->ViewNear, m->ViewFar, m->ViewFOV);
|
2011-03-04 21:02:05 +01:00
|
|
|
SetupCameraMatrixSmooth(m, &m->ViewCamera.m_Orientation);
|
2010-08-13 15:26:29 +02:00
|
|
|
m->ViewCamera.UpdateFrustum();
|
|
|
|
|
2007-01-08 02:56:46 +01:00
|
|
|
m->CullCamera = m->ViewCamera;
|
|
|
|
g_Renderer.SetSceneCamera(m->ViewCamera, m->CullCamera);
|
2004-09-28 18:01:11 +02:00
|
|
|
}
|
|
|
|
|
2004-12-16 13:41:54 +01:00
|
|
|
CGameView::~CGameView()
|
|
|
|
{
|
|
|
|
UnloadResources();
|
2007-01-08 02:56:46 +01:00
|
|
|
|
|
|
|
delete m;
|
2004-12-16 13:41:54 +01:00
|
|
|
}
|
|
|
|
|
2010-06-03 21:07:59 +02:00
|
|
|
void CGameView::SetViewport(const SViewPort& vp)
|
|
|
|
{
|
|
|
|
m->ViewCamera.SetViewPort(vp);
|
2011-11-18 00:34:01 +01:00
|
|
|
m->ViewCamera.SetProjection(m->ViewNear, m->ViewFar, m->ViewFOV);
|
2010-06-03 21:07:59 +02:00
|
|
|
}
|
|
|
|
|
2007-01-08 02:56:46 +01:00
|
|
|
CObjectManager& CGameView::GetObjectManager() const
|
2005-05-18 07:32:09 +02:00
|
|
|
{
|
2007-01-08 02:56:46 +01:00
|
|
|
return m->ObjectManager;
|
|
|
|
}
|
2005-05-18 07:32:09 +02:00
|
|
|
|
2007-01-08 02:56:46 +01:00
|
|
|
JSObject* CGameView::GetScript()
|
|
|
|
{
|
|
|
|
return m->GetScript();
|
2005-05-18 07:32:09 +02:00
|
|
|
}
|
2005-03-22 03:17:55 +01:00
|
|
|
|
2008-04-06 16:03:23 +02:00
|
|
|
/*static*/ void CGameView::ScriptingInit()
|
|
|
|
{
|
|
|
|
return CGameViewImpl::ScriptingInit();
|
|
|
|
}
|
|
|
|
|
2007-01-08 02:56:46 +01:00
|
|
|
CCamera* CGameView::GetCamera()
|
|
|
|
{
|
|
|
|
return &m->ViewCamera;
|
|
|
|
}
|
|
|
|
|
|
|
|
CCinemaManager* CGameView::GetCinema()
|
2004-09-28 18:01:11 +02:00
|
|
|
{
|
2007-01-08 02:56:46 +01:00
|
|
|
return &m->TrackManager;
|
|
|
|
};
|
2004-07-31 17:57:18 +02:00
|
|
|
|
2011-02-03 02:12:24 +01:00
|
|
|
CLOSTexture& CGameView::GetLOSTexture()
|
2007-01-08 02:56:46 +01:00
|
|
|
{
|
2011-02-03 02:12:24 +01:00
|
|
|
return m->LOSTexture;
|
2007-01-08 02:56:46 +01:00
|
|
|
}
|
2004-07-27 23:00:53 +02:00
|
|
|
|
2011-07-20 21:48:06 +02:00
|
|
|
CTerritoryTexture& CGameView::GetTerritoryTexture()
|
|
|
|
{
|
|
|
|
return m->TerritoryTexture;
|
|
|
|
}
|
|
|
|
|
2005-03-22 03:17:55 +01:00
|
|
|
|
2007-01-08 02:56:46 +01:00
|
|
|
void CGameViewImpl::ScriptingInit()
|
|
|
|
{
|
|
|
|
AddProperty(L"culling", &CGameViewImpl::Culling);
|
|
|
|
AddProperty(L"lockCullCamera", &CGameViewImpl::LockCullCamera);
|
2010-08-13 15:26:29 +02:00
|
|
|
AddProperty(L"constrainCamera", &CGameViewImpl::ConstrainCamera);
|
2005-03-22 03:17:55 +01:00
|
|
|
|
2007-01-08 02:56:46 +01:00
|
|
|
CJSObject<CGameViewImpl>::ScriptingInit("GameView");
|
|
|
|
}
|
2005-03-22 22:00:56 +01:00
|
|
|
|
2010-06-30 23:41:04 +02:00
|
|
|
int CGameView::Initialize()
|
2007-01-08 02:56:46 +01:00
|
|
|
{
|
2010-08-13 15:26:29 +02:00
|
|
|
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);
|
|
|
|
|
2010-12-30 20:45:13 +01:00
|
|
|
CFG_GET_SYS_VAL("joystick.camera.pan.x", Int, m->JoystickPanX);
|
|
|
|
CFG_GET_SYS_VAL("joystick.camera.pan.y", Int, m->JoystickPanY);
|
|
|
|
CFG_GET_SYS_VAL("joystick.camera.rotate.x", Int, m->JoystickRotateX);
|
|
|
|
CFG_GET_SYS_VAL("joystick.camera.rotate.y", Int, m->JoystickRotateY);
|
|
|
|
CFG_GET_SYS_VAL("joystick.camera.zoom.in", Int, m->JoystickZoomIn);
|
|
|
|
CFG_GET_SYS_VAL("joystick.camera.zoom.out", Int, m->JoystickZoomOut);
|
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
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);
|
|
|
|
|
2011-11-18 00:34:01 +01:00
|
|
|
CFG_GET_SYS_VAL("view.near", Float, m->ViewNear);
|
|
|
|
CFG_GET_SYS_VAL("view.far", Float, m->ViewFar);
|
|
|
|
CFG_GET_SYS_VAL("view.fov", Float, m->ViewFOV);
|
|
|
|
|
|
|
|
// Convert to radians
|
2010-08-13 15:26:29 +02:00
|
|
|
m->RotateX.SetValue(DEGTORAD(m->ViewRotateXDefault));
|
|
|
|
m->RotateY.SetValue(DEGTORAD(m->ViewRotateYDefault));
|
2011-11-18 00:34:01 +01:00
|
|
|
m->ViewFOV = DEGTORAD(m->ViewFOV);
|
2005-03-22 22:00:56 +01:00
|
|
|
|
2007-01-08 02:56:46 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2005-03-22 22:00:56 +01:00
|
|
|
|
|
|
|
|
2005-03-22 03:17:55 +01:00
|
|
|
|
2010-06-30 23:41:04 +02:00
|
|
|
void CGameView::RegisterInit()
|
2005-03-22 03:17:55 +01:00
|
|
|
{
|
2005-03-22 22:00:56 +01:00
|
|
|
// CGameView init
|
2010-06-30 23:41:04 +02:00
|
|
|
RegMemFun(this, &CGameView::Initialize, L"CGameView init", 1);
|
2005-03-22 22:00:56 +01:00
|
|
|
|
|
|
|
// previously done by CGameView::InitResources
|
2010-09-04 23:26:52 +02:00
|
|
|
RegMemFun(g_TexMan.GetSingletonPtr(), &CTerrainTextureManager::LoadTerrainTextures, L"LoadTerrainTextures", 60);
|
2006-03-18 22:25:03 +01:00
|
|
|
RegMemFun(g_Renderer.GetSingletonPtr(), &CRenderer::LoadAlphaMaps, L"LoadAlphaMaps", 5);
|
|
|
|
RegMemFun(g_Renderer.GetSingletonPtr()->GetWaterManager(), &WaterManager::LoadWaterTextures, L"LoadWaterTextures", 80);
|
2005-03-22 03:17:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-26 21:17:21 +01:00
|
|
|
void CGameView::BeginFrame()
|
2004-07-27 23:00:53 +02:00
|
|
|
{
|
2007-01-08 02:56:46 +01:00
|
|
|
if (m->LockCullCamera == false)
|
2006-12-06 03:52:14 +01:00
|
|
|
{
|
2006-12-09 03:30:19 +01:00
|
|
|
// Set up cull camera
|
2007-01-08 02:56:46 +01:00
|
|
|
m->CullCamera = m->ViewCamera;
|
2006-12-09 03:30:19 +01:00
|
|
|
|
2010-05-21 20:31:47 +02:00
|
|
|
// One way to fix shadows popping in at the edge of the screen is to widen the culling frustum so that
|
|
|
|
// objects aren't culled as early. The downside is that objects will get rendered even though they appear
|
|
|
|
// off screen, which is somewhat inefficient. A better solution would be to decouple shadow map rendering
|
|
|
|
// from model rendering; as it is now, a shadow map is only rendered if its associated model is to be
|
|
|
|
// rendered.
|
|
|
|
// (See http://trac.wildfiregames.com/ticket/504)
|
2011-11-18 00:34:01 +01:00
|
|
|
m->CullCamera.SetProjection(m->ViewNear, m->ViewFar, GetCullFOV());
|
2010-05-21 20:31:47 +02:00
|
|
|
m->CullCamera.UpdateFrustum();
|
2006-12-06 03:52:14 +01:00
|
|
|
}
|
2007-01-08 02:56:46 +01:00
|
|
|
g_Renderer.SetSceneCamera(m->ViewCamera, m->CullCamera);
|
2004-08-05 15:07:51 +02:00
|
|
|
|
2006-02-15 01:45:16 +01:00
|
|
|
CheckLightEnv();
|
|
|
|
|
2011-03-26 21:17:21 +01:00
|
|
|
m->Game->CachePlayerColours();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CGameView::Render()
|
|
|
|
{
|
2011-04-05 22:32:03 +02:00
|
|
|
g_Renderer.RenderScene(*this);
|
2004-07-27 23:00:53 +02:00
|
|
|
}
|
|
|
|
|
2006-09-24 13:25:11 +02:00
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// This callback is part of the Scene interface
|
|
|
|
// Submit all objects visible in the given frustum
|
|
|
|
void CGameView::EnumerateObjects(const CFrustum& frustum, SceneCollector* c)
|
2004-07-27 23:00:53 +02:00
|
|
|
{
|
2011-11-04 02:35:50 +01:00
|
|
|
{
|
|
|
|
PROFILE3("submit terrain");
|
|
|
|
|
2007-01-08 02:56:46 +01:00
|
|
|
CTerrain* pTerrain = m->Game->GetWorld()->GetTerrain();
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
const ssize_t patchesPerSide = pTerrain->GetPatchesPerSide();
|
2007-05-06 09:58:16 +02:00
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
// find out which patches will be drawn
|
|
|
|
for (ssize_t j=0; j<patchesPerSide; j++) {
|
|
|
|
for (ssize_t i=0; i<patchesPerSide; i++) {
|
2009-11-08 17:49:52 +01:00
|
|
|
CPatch* patch=pTerrain->GetPatch(i,j); // can't fail
|
2006-05-29 02:49:09 +02:00
|
|
|
|
|
|
|
// If the patch is underwater, calculate a bounding box that also contains the water plane
|
|
|
|
CBound bounds = patch->GetBounds();
|
|
|
|
float waterHeight = g_Renderer.GetWaterManager()->m_WaterHeight + 0.001f;
|
|
|
|
if(bounds[1].Y < waterHeight) {
|
|
|
|
bounds[1].Y = waterHeight;
|
|
|
|
}
|
|
|
|
|
2007-01-08 02:56:46 +01:00
|
|
|
if (!m->Culling || frustum.IsBoxVisible (CVector3D(0,0,0), bounds)) {
|
2007-05-06 09:58:16 +02:00
|
|
|
//c->Submit(patch);
|
2007-05-10 17:28:59 +02:00
|
|
|
|
|
|
|
// set the renderstate for this patch
|
|
|
|
patch->setDrawState(true);
|
|
|
|
|
|
|
|
// set the renderstate for the neighbors
|
|
|
|
CPatch *nPatch;
|
|
|
|
|
|
|
|
nPatch = pTerrain->GetPatch(i-1,j-1);
|
|
|
|
if(nPatch) nPatch->setDrawState(true);
|
|
|
|
|
|
|
|
nPatch = pTerrain->GetPatch(i,j-1);
|
|
|
|
if(nPatch) nPatch->setDrawState(true);
|
|
|
|
|
|
|
|
nPatch = pTerrain->GetPatch(i+1,j-1);
|
|
|
|
if(nPatch) nPatch->setDrawState(true);
|
|
|
|
|
|
|
|
nPatch = pTerrain->GetPatch(i-1,j);
|
|
|
|
if(nPatch) nPatch->setDrawState(true);
|
|
|
|
|
|
|
|
nPatch = pTerrain->GetPatch(i+1,j);
|
|
|
|
if(nPatch) nPatch->setDrawState(true);
|
|
|
|
|
|
|
|
nPatch = pTerrain->GetPatch(i-1,j+1);
|
|
|
|
if(nPatch) nPatch->setDrawState(true);
|
|
|
|
|
|
|
|
nPatch = pTerrain->GetPatch(i,j+1);
|
|
|
|
if(nPatch) nPatch->setDrawState(true);
|
|
|
|
|
|
|
|
nPatch = pTerrain->GetPatch(i+1,j+1);
|
|
|
|
if(nPatch) nPatch->setDrawState(true);
|
2007-05-06 09:58:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// draw the patches
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
for (ssize_t j=0; j<patchesPerSide; j++)
|
2007-05-06 09:58:16 +02:00
|
|
|
{
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
for (ssize_t i=0; i<patchesPerSide; i++)
|
2007-05-06 09:58:16 +02:00
|
|
|
{
|
2009-11-08 17:49:52 +01:00
|
|
|
CPatch* patch=pTerrain->GetPatch(i,j); // can't fail
|
2007-05-06 09:58:16 +02:00
|
|
|
if(patch->getDrawState() == true)
|
|
|
|
{
|
2006-09-24 13:25:11 +02:00
|
|
|
c->Submit(patch);
|
2007-05-10 17:28:59 +02:00
|
|
|
patch->setDrawState(false);
|
2004-07-27 23:00:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-11-04 02:35:50 +01:00
|
|
|
}
|
2004-07-27 23:00:53 +02:00
|
|
|
|
2010-05-20 20:09:23 +02:00
|
|
|
m->Game->GetSimulation2()->RenderSubmit(*c, frustum, m->Culling);
|
2004-07-27 23:00:53 +02:00
|
|
|
}
|
|
|
|
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2006-02-15 01:45:16 +01:00
|
|
|
void CGameView::CheckLightEnv()
|
|
|
|
{
|
2007-01-08 02:56:46 +01:00
|
|
|
if (m->CachedLightEnv == g_LightEnv)
|
2006-02-15 01:45:16 +01:00
|
|
|
return;
|
2011-03-26 21:17:21 +01:00
|
|
|
|
|
|
|
if (m->CachedLightEnv.GetLightingModel() != g_LightEnv.GetLightingModel())
|
|
|
|
g_Renderer.MakeShadersDirty();
|
2006-02-15 01:45:16 +01:00
|
|
|
|
2007-01-08 02:56:46 +01:00
|
|
|
m->CachedLightEnv = g_LightEnv;
|
|
|
|
CTerrain* pTerrain = m->Game->GetWorld()->GetTerrain();
|
2006-02-15 01:45:16 +01:00
|
|
|
|
|
|
|
if (!pTerrain)
|
|
|
|
return;
|
|
|
|
|
|
|
|
PROFILE("update light env");
|
|
|
|
pTerrain->MakeDirty(RENDERDATA_UPDATE_COLOR);
|
|
|
|
|
2007-01-08 02:56:46 +01:00
|
|
|
const std::vector<CUnit*>& units = m->Game->GetWorld()->GetUnitManager().GetUnits();
|
2011-03-13 20:22:05 +01:00
|
|
|
for (size_t i = 0; i < units.size(); ++i)
|
|
|
|
units[i]->GetModel().SetDirtyRec(RENDERDATA_UPDATE_COLOR);
|
2006-02-15 01:45:16 +01:00
|
|
|
}
|
|
|
|
|
2004-07-31 17:57:18 +02:00
|
|
|
|
2004-12-16 13:41:54 +01:00
|
|
|
void CGameView::UnloadResources()
|
|
|
|
{
|
2005-11-06 06:05:07 +01:00
|
|
|
g_TexMan.UnloadTerrainTextures();
|
2004-12-16 13:41:54 +01:00
|
|
|
g_Renderer.UnloadAlphaMaps();
|
2006-01-07 02:04:26 +01:00
|
|
|
g_Renderer.GetWaterManager()->UnloadWaterTextures();
|
2004-12-16 13:41:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
static void ClampDistance(CGameViewImpl* m, bool smooth)
|
2004-07-31 17:57:18 +02:00
|
|
|
{
|
2010-08-13 15:26:29 +02:00
|
|
|
if (!m->ConstrainCamera)
|
|
|
|
return;
|
2004-08-03 01:14:54 +02:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
CCamera targetCam = m->ViewCamera;
|
2011-03-04 21:02:05 +01:00
|
|
|
SetupCameraMatrixSmoothRot(m, &targetCam.m_Orientation);
|
2004-07-31 17:57:18 +02:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
CVector3D forwards = targetCam.m_Orientation.GetIn();
|
2004-08-03 01:14:54 +02:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
CVector3D delta = targetCam.GetFocus() - targetCam.m_Orientation.GetTranslation();
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
float dist = delta.Dot(forwards);
|
|
|
|
float clampedDist = Clamp(dist, m->ViewZoomMin, m->ViewZoomMax);
|
|
|
|
float diff = clampedDist - dist;
|
2004-08-03 01:14:54 +02:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
if (!diff)
|
|
|
|
return;
|
2004-08-03 01:14:54 +02:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
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);
|
|
|
|
}
|
2004-07-31 17:57:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CGameView::Update(float DeltaTime)
|
|
|
|
{
|
2005-10-31 19:36:36 +01:00
|
|
|
if (!g_app_has_focus)
|
2004-07-31 17:57:18 +02:00
|
|
|
return;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2010-03-27 18:19:00 +01:00
|
|
|
// TODO: this is probably not an ideal place for this, it should probably go
|
|
|
|
// in a CCmpWaterManager or some such thing (once such a thing exists)
|
2010-09-27 01:05:25 +02:00
|
|
|
if (!m->Game->m_Paused)
|
2010-08-22 00:50:57 +02:00
|
|
|
g_Renderer.GetWaterManager()->m_WaterTexTimer += DeltaTime;
|
2010-03-27 18:19:00 +01:00
|
|
|
|
2007-01-08 02:56:46 +01:00
|
|
|
if (m->TrackManager.IsActive() && m->TrackManager.IsPlaying())
|
2005-12-06 07:58:30 +01:00
|
|
|
{
|
2007-01-08 02:56:46 +01:00
|
|
|
if (! m->TrackManager.Update(DeltaTime))
|
2010-08-13 15:26:29 +02:00
|
|
|
{
|
|
|
|
// ResetCamera();
|
|
|
|
}
|
2007-01-08 02:56:46 +01:00
|
|
|
return;
|
2005-12-06 07:58:30 +01:00
|
|
|
}
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2004-07-31 17:57:18 +02:00
|
|
|
// Calculate mouse movement
|
|
|
|
static int mouse_last_x = 0;
|
|
|
|
static int mouse_last_y = 0;
|
2005-01-23 18:35:36 +01:00
|
|
|
int mouse_dx = g_mouse_x - mouse_last_x;
|
|
|
|
int mouse_dy = g_mouse_y - mouse_last_y;
|
|
|
|
mouse_last_x = g_mouse_x;
|
|
|
|
mouse_last_y = g_mouse_y;
|
2004-07-31 17:57:18 +02:00
|
|
|
|
2010-10-23 04:37:00 +02:00
|
|
|
if (HotkeyIsPressed("camera.rotate.cw"))
|
2010-08-13 15:26:29 +02:00
|
|
|
m->RotateY.AddSmoothly(m->ViewRotateYSpeed * DeltaTime);
|
2010-10-23 04:37:00 +02:00
|
|
|
if (HotkeyIsPressed("camera.rotate.ccw"))
|
2010-08-13 15:26:29 +02:00
|
|
|
m->RotateY.AddSmoothly(-m->ViewRotateYSpeed * DeltaTime);
|
2010-10-23 04:37:00 +02:00
|
|
|
if (HotkeyIsPressed("camera.rotate.up"))
|
2010-08-13 15:26:29 +02:00
|
|
|
m->RotateX.AddSmoothly(-m->ViewRotateXSpeed * DeltaTime);
|
2010-10-23 04:37:00 +02:00
|
|
|
if (HotkeyIsPressed("camera.rotate.down"))
|
2010-08-13 15:26:29 +02:00
|
|
|
m->RotateX.AddSmoothly(m->ViewRotateXSpeed * DeltaTime);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
float moveRightward = 0.f;
|
|
|
|
float moveForward = 0.f;
|
2004-07-31 17:57:18 +02:00
|
|
|
|
2010-10-23 04:37:00 +02:00
|
|
|
if (HotkeyIsPressed("camera.pan"))
|
2004-07-31 17:57:18 +02:00
|
|
|
{
|
2010-08-13 15:26:29 +02:00
|
|
|
moveRightward += m->ViewDragSpeed * mouse_dx;
|
|
|
|
moveForward += m->ViewDragSpeed * -mouse_dy;
|
2004-07-31 17:57:18 +02:00
|
|
|
}
|
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
if (g_mouse_active)
|
|
|
|
{
|
|
|
|
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)
|
|
|
|
moveRightward -= m->ViewScrollSpeed * DeltaTime;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
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)
|
|
|
|
moveForward += m->ViewScrollSpeed * DeltaTime;
|
2004-11-11 08:09:32 +01:00
|
|
|
}
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2010-11-07 21:42:52 +01:00
|
|
|
if (HotkeyIsPressed("camera.right"))
|
|
|
|
moveRightward += m->ViewScrollSpeed * DeltaTime;
|
|
|
|
if (HotkeyIsPressed("camera.left"))
|
|
|
|
moveRightward -= m->ViewScrollSpeed * DeltaTime;
|
|
|
|
if (HotkeyIsPressed("camera.up"))
|
|
|
|
moveForward += m->ViewScrollSpeed * DeltaTime;
|
|
|
|
if (HotkeyIsPressed("camera.down"))
|
|
|
|
moveForward -= m->ViewScrollSpeed * DeltaTime;
|
2004-11-11 08:09:32 +01:00
|
|
|
|
2010-12-30 20:45:13 +01:00
|
|
|
if (g_Joystick.IsEnabled())
|
|
|
|
{
|
|
|
|
// This could all be improved with extra speed and sensitivity settings
|
|
|
|
// (maybe use pow to allow finer control?), and inversion settings
|
|
|
|
|
|
|
|
moveRightward += g_Joystick.GetAxisValue(m->JoystickPanX) * m->ViewScrollSpeed * DeltaTime;
|
|
|
|
moveForward -= g_Joystick.GetAxisValue(m->JoystickPanY) * m->ViewScrollSpeed * DeltaTime;
|
|
|
|
|
|
|
|
m->RotateX.AddSmoothly(g_Joystick.GetAxisValue(m->JoystickRotateX) * m->ViewRotateXSpeed * DeltaTime);
|
|
|
|
m->RotateY.AddSmoothly(-g_Joystick.GetAxisValue(m->JoystickRotateY) * m->ViewRotateYSpeed * DeltaTime);
|
|
|
|
|
|
|
|
// Use a +1 bias for zoom because I want this to work with trigger buttons that default to -1
|
|
|
|
m->Zoom.AddSmoothly((g_Joystick.GetAxisValue(m->JoystickZoomIn) + 1.0f) / 2.0f * m->ViewZoomSpeed * DeltaTime);
|
|
|
|
m->Zoom.AddSmoothly(-(g_Joystick.GetAxisValue(m->JoystickZoomOut) + 1.0f) / 2.0f * m->ViewZoomSpeed * DeltaTime);
|
|
|
|
}
|
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
if (moveRightward || moveForward)
|
|
|
|
{
|
2010-09-27 01:05:25 +02:00
|
|
|
// Break out of following mode when the user starts scrolling
|
|
|
|
m->FollowEntity = INVALID_ENTITY;
|
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
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);
|
|
|
|
}
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2010-09-27 01:05:25 +02:00
|
|
|
if (m->FollowEntity)
|
|
|
|
{
|
|
|
|
CmpPtr<ICmpPosition> cmpPosition(*(m->Game->GetSimulation2()), m->FollowEntity);
|
|
|
|
if (!cmpPosition.null() && cmpPosition->IsInWorld())
|
|
|
|
{
|
|
|
|
// Get the most recent interpolated position
|
|
|
|
float frameOffset = m->Game->GetSimulation2()->GetLastFrameOffset();
|
2010-11-01 22:40:29 +01:00
|
|
|
CMatrix3D transform = cmpPosition->GetInterpolatedTransform(frameOffset, false);
|
|
|
|
CVector3D pos = transform.GetTranslation();
|
2010-09-27 01:05:25 +02:00
|
|
|
|
2010-11-01 22:40:29 +01:00
|
|
|
if (m->FollowFirstPerson)
|
|
|
|
{
|
|
|
|
float x, z, angle;
|
|
|
|
cmpPosition->GetInterpolatedPosition2D(frameOffset, x, z, angle);
|
|
|
|
float height = 4.f;
|
|
|
|
m->ViewCamera.m_Orientation.SetIdentity();
|
2010-11-17 00:00:52 +01:00
|
|
|
m->ViewCamera.m_Orientation.RotateX((float)M_PI/24.f);
|
2010-11-01 22:40:29 +01:00
|
|
|
m->ViewCamera.m_Orientation.RotateY(angle);
|
|
|
|
m->ViewCamera.m_Orientation.Translate(pos.X, pos.Y + height, pos.Z);
|
|
|
|
|
|
|
|
m->ViewCamera.UpdateFrustum();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-03-04 21:02:05 +01:00
|
|
|
// Move the camera to match the unit
|
2010-11-01 22:40:29 +01:00
|
|
|
CCamera targetCam = m->ViewCamera;
|
2011-03-04 21:02:05 +01:00
|
|
|
SetupCameraMatrixSmoothRot(m, &targetCam.m_Orientation);
|
2010-11-01 22:40:29 +01:00
|
|
|
|
|
|
|
CVector3D pivot = targetCam.GetFocus();
|
|
|
|
CVector3D delta = pos - pivot;
|
|
|
|
m->PosX.AddSmoothly(delta.X);
|
|
|
|
m->PosY.AddSmoothly(delta.Y);
|
|
|
|
m->PosZ.AddSmoothly(delta.Z);
|
|
|
|
}
|
2010-09-27 01:05:25 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// The unit disappeared (died or garrisoned etc), so stop following it
|
|
|
|
m->FollowEntity = INVALID_ENTITY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-23 04:37:00 +02:00
|
|
|
if (HotkeyIsPressed("camera.zoom.in"))
|
2010-08-13 15:26:29 +02:00
|
|
|
m->Zoom.AddSmoothly(m->ViewZoomSpeed * DeltaTime);
|
2010-10-23 04:37:00 +02:00
|
|
|
if (HotkeyIsPressed("camera.zoom.out"))
|
2010-08-13 15:26:29 +02:00
|
|
|
m->Zoom.AddSmoothly(-m->ViewZoomSpeed * DeltaTime);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
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);
|
|
|
|
}
|
2004-11-11 08:09:32 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
if (m->ConstrainCamera)
|
|
|
|
m->RotateX.ClampSmoothly(DEGTORAD(m->ViewRotateXMin), DEGTORAD(m->ViewRotateXMax));
|
2004-11-11 08:09:32 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
ClampDistance(m, true);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2010-09-04 14:50:27 +02:00
|
|
|
// Ensure the ViewCamera focus is inside the map with the chosen margins
|
|
|
|
// if not so - apply margins to the camera
|
|
|
|
if (m->ConstrainCamera)
|
|
|
|
{
|
|
|
|
CCamera targetCam = m->ViewCamera;
|
2011-03-04 21:02:05 +01:00
|
|
|
SetupCameraMatrixSmoothRot(m, &targetCam.m_Orientation);
|
2010-09-04 14:50:27 +02:00
|
|
|
|
|
|
|
CTerrain* pTerrain = m->Game->GetWorld()->GetTerrain();
|
2011-03-04 21:02:05 +01:00
|
|
|
|
|
|
|
CVector3D pivot = targetCam.GetFocus();
|
|
|
|
CVector3D delta = targetCam.m_Orientation.GetTranslation() - pivot;
|
|
|
|
|
|
|
|
CVector3D desiredPivot = pivot;
|
|
|
|
|
|
|
|
CmpPtr<ICmpRangeManager> cmpRangeManager(*m->Game->GetSimulation2(), SYSTEM_ENTITY);
|
|
|
|
if (!cmpRangeManager.null() && cmpRangeManager->GetLosCircular())
|
|
|
|
{
|
|
|
|
// Clamp to a circular region around the center of the map
|
|
|
|
float r = pTerrain->GetMaxX() / 2;
|
|
|
|
CVector3D center(r, desiredPivot.Y, r);
|
|
|
|
float dist = (desiredPivot - center).Length();
|
|
|
|
if (dist > r + CAMERA_EDGE_MARGIN)
|
|
|
|
desiredPivot = center + (desiredPivot - center).Normalized() * (r + CAMERA_EDGE_MARGIN);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Clamp to the square edges of the map
|
|
|
|
desiredPivot.X = Clamp(desiredPivot.X, pTerrain->GetMinX() - CAMERA_EDGE_MARGIN, pTerrain->GetMaxX() + CAMERA_EDGE_MARGIN);
|
|
|
|
desiredPivot.Z = Clamp(desiredPivot.Z, pTerrain->GetMinZ() - CAMERA_EDGE_MARGIN, pTerrain->GetMaxZ() + CAMERA_EDGE_MARGIN);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update the position so that pivot is within the margin
|
|
|
|
m->PosX.SetValueSmoothly(desiredPivot.X + delta.X);
|
|
|
|
m->PosZ.SetValueSmoothly(desiredPivot.Z + delta.Z);
|
2010-09-04 14:50:27 +02:00
|
|
|
}
|
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
m->PosX.Update(DeltaTime);
|
|
|
|
m->PosY.Update(DeltaTime);
|
|
|
|
m->PosZ.Update(DeltaTime);
|
2004-11-11 08:09:32 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
// Handle rotation around the Y (vertical) axis
|
|
|
|
{
|
|
|
|
CCamera targetCam = m->ViewCamera;
|
2011-03-04 21:02:05 +01:00
|
|
|
SetupCameraMatrixSmooth(m, &targetCam.m_Orientation);
|
2004-11-11 08:09:32 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
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).
|
2004-11-11 08:09:32 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
CVector3D upwards(0.0f, 1.0f, 0.0f);
|
2004-11-11 08:09:32 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
CVector3D pivot = targetCam.GetFocus();
|
|
|
|
CVector3D delta = targetCam.m_Orientation.GetTranslation() - pivot;
|
2004-11-11 08:09:32 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
CQuaternion q;
|
|
|
|
q.FromAxisAngle(upwards, rotateYDelta);
|
|
|
|
CVector3D d = q.Rotate(delta) - delta;
|
2004-11-11 08:09:32 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
m->PosX.Add(d.X);
|
|
|
|
m->PosY.Add(d.Y);
|
|
|
|
m->PosZ.Add(d.Z);
|
2004-11-11 08:09:32 +01:00
|
|
|
}
|
2004-07-31 17:57:18 +02:00
|
|
|
}
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
// Handle rotation around the X (sideways, relative to camera) axis
|
2004-07-31 17:57:18 +02:00
|
|
|
{
|
2010-08-13 15:26:29 +02:00
|
|
|
CCamera targetCam = m->ViewCamera;
|
2011-03-04 21:02:05 +01:00
|
|
|
SetupCameraMatrixSmooth(m, &targetCam.m_Orientation);
|
2004-07-31 17:57:18 +02:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
float rotateXDelta = m->RotateX.Update(DeltaTime);
|
|
|
|
if (rotateXDelta)
|
|
|
|
{
|
|
|
|
CVector3D rightwards = targetCam.m_Orientation.GetLeft() * -1.0f;
|
2004-07-31 17:57:18 +02:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
CVector3D pivot = m->ViewCamera.GetFocus();
|
|
|
|
CVector3D delta = targetCam.m_Orientation.GetTranslation() - pivot;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
CQuaternion q;
|
|
|
|
q.FromAxisAngle(rightwards, rotateXDelta);
|
|
|
|
CVector3D d = q.Rotate(delta) - delta;
|
2005-09-28 05:49:11 +02:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
m->PosX.Add(d.X);
|
|
|
|
m->PosY.Add(d.Y);
|
|
|
|
m->PosZ.Add(d.Z);
|
|
|
|
}
|
2004-11-11 08:09:32 +01:00
|
|
|
}
|
2006-02-15 01:45:16 +01:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
/* This is disabled since it doesn't seem necessary:
|
2004-07-31 17:57:18 +02:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
// Ensure the camera's near point is never inside the terrain
|
|
|
|
if (m->ConstrainCamera)
|
2004-07-31 17:57:18 +02:00
|
|
|
{
|
2010-08-13 15:26:29 +02:00
|
|
|
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);
|
2004-07-31 17:57:18 +02:00
|
|
|
}
|
2010-08-13 15:26:29 +02:00
|
|
|
*/
|
2004-07-31 17:57:18 +02:00
|
|
|
|
2010-08-14 22:09:45 +02:00
|
|
|
m->RotateY.Wrap(-(float)M_PI, (float)M_PI);
|
2010-08-14 02:52:19 +02:00
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
// Update the camera matrix
|
2011-11-18 00:34:01 +01:00
|
|
|
m->ViewCamera.SetProjection(m->ViewNear, m->ViewFar, m->ViewFOV);
|
2011-03-04 21:02:05 +01:00
|
|
|
SetupCameraMatrixSmooth(m, &m->ViewCamera.m_Orientation);
|
2010-08-13 15:26:29 +02:00
|
|
|
m->ViewCamera.UpdateFrustum();
|
2004-07-31 17:57:18 +02:00
|
|
|
}
|
|
|
|
|
2010-11-21 05:59:59 +01:00
|
|
|
void CGameView::MoveCameraTarget(const CVector3D& target, bool minimap)
|
2004-07-31 17:57:18 +02:00
|
|
|
{
|
|
|
|
// Maintain the same orientation and level of zoom, if we can
|
|
|
|
// (do this by working out the point the camera is looking at, saving
|
2005-10-09 05:26:16 +02:00
|
|
|
// the difference between that position and the camera point, and restoring
|
2004-07-31 17:57:18 +02:00
|
|
|
// that difference to our new target)
|
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
CCamera targetCam = m->ViewCamera;
|
2011-03-04 21:02:05 +01:00
|
|
|
SetupCameraMatrixNonSmooth(m, &targetCam.m_Orientation);
|
2010-08-13 15:26:29 +02:00
|
|
|
|
|
|
|
CVector3D pivot = targetCam.GetFocus();
|
|
|
|
CVector3D delta = target - pivot;
|
2010-11-21 05:59:59 +01:00
|
|
|
|
|
|
|
//If minimap movement, maintain previous zoom level by not changing Y position
|
|
|
|
// - this prevents strange behavior when moving across changes in terrain height
|
|
|
|
if (!minimap)
|
|
|
|
m->PosY.SetValueSmoothly(delta.Y + m->PosY.GetValue());
|
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
m->PosX.SetValueSmoothly(delta.X + m->PosX.GetValue());
|
|
|
|
m->PosZ.SetValueSmoothly(delta.Z + m->PosZ.GetValue());
|
|
|
|
|
|
|
|
ClampDistance(m, false);
|
2010-09-27 01:05:25 +02:00
|
|
|
|
|
|
|
// Break out of following mode so the camera really moves to the target
|
|
|
|
m->FollowEntity = INVALID_ENTITY;
|
2004-07-31 17:57:18 +02:00
|
|
|
}
|
|
|
|
|
2010-08-13 15:26:29 +02:00
|
|
|
void CGameView::ResetCameraTarget(const CVector3D& target)
|
2004-07-31 17:57:18 +02:00
|
|
|
{
|
2010-08-13 15:26:29 +02:00
|
|
|
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);
|
2011-04-01 19:57:04 +02:00
|
|
|
m->RotateX.SetValue(DEGTORAD(m->ViewRotateXDefault));
|
|
|
|
m->RotateY.SetValue(DEGTORAD(m->ViewRotateYDefault));
|
2010-08-13 15:26:29 +02:00
|
|
|
|
|
|
|
ClampDistance(m, false);
|
|
|
|
|
2011-03-04 21:02:05 +01:00
|
|
|
SetupCameraMatrixSmooth(m, &m->ViewCamera.m_Orientation);
|
2010-08-13 15:26:29 +02:00
|
|
|
m->ViewCamera.UpdateFrustum();
|
2010-09-27 01:05:25 +02:00
|
|
|
|
|
|
|
// Break out of following mode so the camera really moves to the target
|
|
|
|
m->FollowEntity = INVALID_ENTITY;
|
2004-07-31 17:57:18 +02:00
|
|
|
}
|
|
|
|
|
2010-08-14 02:52:19 +02:00
|
|
|
void CGameView::ResetCameraAngleZoom()
|
|
|
|
{
|
|
|
|
CCamera targetCam = m->ViewCamera;
|
2011-03-04 21:02:05 +01:00
|
|
|
SetupCameraMatrixNonSmooth(m, &targetCam.m_Orientation);
|
2010-08-14 02:52:19 +02:00
|
|
|
|
|
|
|
// Compute the zoom adjustment to get us back to the default
|
|
|
|
CVector3D forwards = targetCam.m_Orientation.GetIn();
|
|
|
|
CVector3D delta = targetCam.GetFocus() - targetCam.m_Orientation.GetTranslation();
|
|
|
|
float dist = delta.Dot(forwards);
|
|
|
|
m->Zoom.AddSmoothly(dist - m->ViewZoomDefault);
|
|
|
|
|
|
|
|
// Reset orientations to default
|
|
|
|
m->RotateX.SetValueSmoothly(DEGTORAD(m->ViewRotateXDefault));
|
|
|
|
m->RotateY.SetValueSmoothly(DEGTORAD(m->ViewRotateYDefault));
|
|
|
|
}
|
|
|
|
|
2010-11-01 22:40:29 +01:00
|
|
|
void CGameView::CameraFollow(entity_id_t entity, bool firstPerson)
|
2010-09-27 01:05:25 +02:00
|
|
|
{
|
|
|
|
m->FollowEntity = entity;
|
2010-11-01 22:40:29 +01:00
|
|
|
m->FollowFirstPerson = firstPerson;
|
2010-09-27 01:05:25 +02:00
|
|
|
}
|
|
|
|
|
2011-07-05 23:29:11 +02:00
|
|
|
entity_id_t CGameView::GetFollowedEntity()
|
|
|
|
{
|
|
|
|
return m->FollowEntity;
|
|
|
|
}
|
|
|
|
|
2011-11-18 00:34:01 +01:00
|
|
|
float CGameView::GetNear() const
|
|
|
|
{
|
|
|
|
return m->ViewNear;
|
|
|
|
}
|
|
|
|
|
|
|
|
float CGameView::GetFar() const
|
|
|
|
{
|
|
|
|
return m->ViewFar;
|
|
|
|
}
|
|
|
|
|
|
|
|
float CGameView::GetFOV() const
|
|
|
|
{
|
|
|
|
return m->ViewFOV;
|
|
|
|
}
|
|
|
|
|
|
|
|
float CGameView::GetCullFOV() const
|
|
|
|
{
|
|
|
|
return m->ViewFOV + DEGTORAD(6.0f); //add 6 degrees to the default FOV for use with the culling frustum;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CGameView::SetCameraProjection()
|
|
|
|
{
|
|
|
|
m->ViewCamera.SetProjection(m->ViewNear, m->ViewFar, m->ViewFOV);
|
|
|
|
}
|
|
|
|
|
2006-08-26 23:52:18 +02:00
|
|
|
InReaction game_view_handler(const SDL_Event_* ev)
|
2004-07-31 17:57:18 +02:00
|
|
|
{
|
|
|
|
// put any events that must be processed even if inactive here
|
2011-07-03 20:36:43 +02:00
|
|
|
if(!g_app_has_focus || !g_Game || !g_Game->IsGameStarted())
|
2005-10-20 19:44:56 +02:00
|
|
|
return IN_PASS;
|
2004-07-31 17:57:18 +02:00
|
|
|
|
2004-08-05 15:07:51 +02:00
|
|
|
CGameView *pView=g_Game->GetView();
|
|
|
|
|
2005-09-29 01:57:55 +02:00
|
|
|
return pView->HandleEvent(ev);
|
|
|
|
}
|
|
|
|
|
2006-08-26 23:52:18 +02:00
|
|
|
InReaction CGameView::HandleEvent(const SDL_Event_* ev)
|
2005-09-29 01:57:55 +02:00
|
|
|
{
|
2006-08-26 23:52:18 +02:00
|
|
|
switch(ev->ev.type)
|
2004-07-31 17:57:18 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
case SDL_HOTKEYDOWN:
|
2010-10-23 04:37:00 +02:00
|
|
|
std::string hotkey = static_cast<const char*>(ev->ev.user.data1);
|
|
|
|
|
|
|
|
if (hotkey == "wireframe")
|
2004-07-31 17:57:18 +02:00
|
|
|
{
|
2005-10-26 03:43:49 +02:00
|
|
|
if (g_Renderer.GetModelRenderMode() == SOLID)
|
|
|
|
{
|
|
|
|
g_Renderer.SetTerrainRenderMode(EDGED_FACES);
|
|
|
|
g_Renderer.SetModelRenderMode(EDGED_FACES);
|
|
|
|
}
|
|
|
|
else if (g_Renderer.GetModelRenderMode() == EDGED_FACES)
|
|
|
|
{
|
2004-07-31 17:57:18 +02:00
|
|
|
g_Renderer.SetTerrainRenderMode(WIREFRAME);
|
2005-10-26 03:43:49 +02:00
|
|
|
g_Renderer.SetModelRenderMode(WIREFRAME);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_Renderer.SetTerrainRenderMode(SOLID);
|
|
|
|
g_Renderer.SetModelRenderMode(SOLID);
|
2004-07-31 17:57:18 +02:00
|
|
|
}
|
2010-08-13 15:26:29 +02:00
|
|
|
return IN_HANDLED;
|
2010-10-23 04:37:00 +02:00
|
|
|
}
|
2005-09-29 01:57:55 +02:00
|
|
|
// Mouse wheel must be treated using events instead of polling,
|
2005-10-13 20:05:55 +02:00
|
|
|
// because SDL auto-generates a sequence of mousedown/mouseup events
|
|
|
|
// and we never get to see the "down" state inside Update().
|
2010-10-23 04:37:00 +02:00
|
|
|
else if (hotkey == "camera.zoom.wheel.in")
|
|
|
|
{
|
2010-08-13 15:26:29 +02:00
|
|
|
m->Zoom.AddSmoothly(m->ViewZoomSpeedWheel);
|
|
|
|
return IN_HANDLED;
|
2010-10-23 04:37:00 +02:00
|
|
|
}
|
|
|
|
else if (hotkey == "camera.zoom.wheel.out")
|
|
|
|
{
|
2010-08-13 15:26:29 +02:00
|
|
|
m->Zoom.AddSmoothly(-m->ViewZoomSpeedWheel);
|
|
|
|
return IN_HANDLED;
|
2010-10-23 04:37:00 +02:00
|
|
|
}
|
|
|
|
else if (hotkey == "camera.rotate.wheel.cw")
|
|
|
|
{
|
2010-08-13 15:26:29 +02:00
|
|
|
m->RotateY.AddSmoothly(m->ViewRotateYSpeedWheel);
|
|
|
|
return IN_HANDLED;
|
2010-10-23 04:37:00 +02:00
|
|
|
}
|
|
|
|
else if (hotkey == "camera.rotate.wheel.ccw")
|
|
|
|
{
|
2010-08-13 15:26:29 +02:00
|
|
|
m->RotateY.AddSmoothly(-m->ViewRotateYSpeedWheel);
|
|
|
|
return IN_HANDLED;
|
2010-10-23 04:37:00 +02:00
|
|
|
}
|
|
|
|
else if (hotkey == "camera.reset")
|
|
|
|
{
|
2010-08-14 02:52:19 +02:00
|
|
|
ResetCameraAngleZoom();
|
|
|
|
return IN_HANDLED;
|
2004-08-03 01:14:54 +02:00
|
|
|
}
|
2004-07-31 17:57:18 +02:00
|
|
|
}
|
|
|
|
|
2005-10-20 19:44:56 +02:00
|
|
|
return IN_PASS;
|
2004-07-31 17:57:18 +02:00
|
|
|
}
|