Fix #56 (add unit-following camera mode (press 'F')), based on patch from markelov.
Remove obsolete IsNewSimulation function. This was SVN commit r8190.
This commit is contained in:
parent
9bdbc3906f
commit
82691683cb
@ -113,6 +113,7 @@ hotkey.archive.abort = "Alt+F4" ; Prematurely terminate the archive builder
|
||||
|
||||
; > CAMERA SETTINGS
|
||||
hotkey.camera.reset = "H" ; Reset camera rotation to default.
|
||||
hotkey.camera.follow = "F" ; Follow the first unit in the selection
|
||||
hotkey.camera.reset.origin = "Ctrl+H" ; Reset camera to origin.
|
||||
hotkey.camera.zoom.in = Plus, Equals, NumPlus ; Zoom camera in.
|
||||
hotkey.camera.zoom.out = Minus, NumMinus ; Zoom camera out.
|
||||
|
@ -759,3 +759,22 @@ function performCommand(entity, commandName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the camera to follow the given unit
|
||||
function setCameraFollow(entity)
|
||||
{
|
||||
// Follow the given entity if it's a unit
|
||||
if (entity)
|
||||
{
|
||||
var entState = GetEntityState(entity);
|
||||
if (entState && isUnit(entState))
|
||||
{
|
||||
Engine.CameraFollow(entity);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise stop following
|
||||
Engine.CameraFollow(0);
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,11 @@
|
||||
<action on="Press">performCommand(g_Selection.toList()[0], "delete");</action>
|
||||
</object>
|
||||
|
||||
<!-- camera.follow mode - follow the first unit in the selection -->
|
||||
<object hotkey="camera.follow">
|
||||
<action on="Press">setCameraFollow(g_Selection.toList()[0]);</action>
|
||||
</object>
|
||||
|
||||
<!-- ================================ ================================ -->
|
||||
<!-- Developer / Debug items -->
|
||||
<!-- ================================ ================================ -->
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "scripting/ScriptableObject.h"
|
||||
#include "simulation/LOSManager.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/components/ICmpPosition.h"
|
||||
|
||||
extern int g_xres, g_yres;
|
||||
|
||||
@ -157,6 +158,7 @@ public:
|
||||
LockCullCamera(false),
|
||||
ConstrainCamera(true),
|
||||
Culling(true),
|
||||
FollowEntity(INVALID_ENTITY),
|
||||
|
||||
// Dummy values (these will be filled in by the config file)
|
||||
ViewScrollSpeed(0),
|
||||
@ -235,6 +237,11 @@ public:
|
||||
|
||||
CCinemaManager TrackManager;
|
||||
|
||||
/**
|
||||
* Entity for the camera to follow, or INVALID_ENTITY if none.
|
||||
*/
|
||||
entity_id_t FollowEntity;
|
||||
|
||||
////////////////////////////////////////
|
||||
// Settings
|
||||
float ViewScrollSpeed;
|
||||
@ -574,7 +581,7 @@ void CGameView::Update(float DeltaTime)
|
||||
|
||||
// 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)
|
||||
if (!g_Game->m_Paused)
|
||||
if (!m->Game->m_Paused)
|
||||
g_Renderer.GetWaterManager()->m_WaterTexTimer += DeltaTime;
|
||||
|
||||
if (m->TrackManager.IsActive() && m->TrackManager.IsPlaying())
|
||||
@ -639,6 +646,9 @@ void CGameView::Update(float DeltaTime)
|
||||
|
||||
if (moveRightward || moveForward)
|
||||
{
|
||||
// Break out of following mode when the user starts scrolling
|
||||
m->FollowEntity = INVALID_ENTITY;
|
||||
|
||||
float s = sin(m->RotateY.GetSmoothedValue());
|
||||
float c = cos(m->RotateY.GetSmoothedValue());
|
||||
m->PosX.AddSmoothly(c * moveRightward);
|
||||
@ -647,6 +657,37 @@ void CGameView::Update(float DeltaTime)
|
||||
m->PosZ.AddSmoothly(c * moveForward);
|
||||
}
|
||||
|
||||
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();
|
||||
CVector3D pos = cmpPosition->GetInterpolatedTransform(frameOffset, false).GetTranslation();
|
||||
|
||||
// move the camera after unit
|
||||
// use smoothed values of rotation around X and Y, since we need to hold user's rotation done
|
||||
// in this function above
|
||||
CCamera targetCam = m->ViewCamera;
|
||||
targetCam.m_Orientation.SetIdentity();
|
||||
targetCam.m_Orientation.RotateX(m->RotateX.GetSmoothedValue());
|
||||
targetCam.m_Orientation.RotateY(m->RotateY.GetSmoothedValue());
|
||||
targetCam.m_Orientation.Translate(m->PosX.GetValue(), m->PosY.GetValue(), m->PosZ.GetValue());
|
||||
|
||||
CVector3D pivot = targetCam.GetFocus();
|
||||
CVector3D delta = pos - pivot;
|
||||
m->PosX.AddSmoothly(delta.X);
|
||||
m->PosY.AddSmoothly(delta.Y);
|
||||
m->PosZ.AddSmoothly(delta.Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The unit disappeared (died or garrisoned etc), so stop following it
|
||||
m->FollowEntity = INVALID_ENTITY;
|
||||
}
|
||||
}
|
||||
|
||||
if (hotkeys[HOTKEY_CAMERA_ZOOM_IN])
|
||||
m->Zoom.AddSmoothly(m->ViewZoomSpeed * DeltaTime);
|
||||
if (hotkeys[HOTKEY_CAMERA_ZOOM_OUT])
|
||||
@ -785,6 +826,9 @@ void CGameView::MoveCameraTarget(const CVector3D& target)
|
||||
m->PosZ.SetValueSmoothly(delta.Z + m->PosZ.GetValue());
|
||||
|
||||
ClampDistance(m, false);
|
||||
|
||||
// Break out of following mode so the camera really moves to the target
|
||||
m->FollowEntity = INVALID_ENTITY;
|
||||
}
|
||||
|
||||
void CGameView::ResetCameraTarget(const CVector3D& target)
|
||||
@ -803,6 +847,9 @@ void CGameView::ResetCameraTarget(const CVector3D& target)
|
||||
|
||||
SetupCameraMatrix(m, &m->ViewCamera.m_Orientation);
|
||||
m->ViewCamera.UpdateFrustum();
|
||||
|
||||
// Break out of following mode so the camera really moves to the target
|
||||
m->FollowEntity = INVALID_ENTITY;
|
||||
}
|
||||
|
||||
void CGameView::ResetCameraAngleZoom()
|
||||
@ -824,6 +871,11 @@ void CGameView::ResetCameraAngleZoom()
|
||||
m->RotateY.SetValueSmoothly(DEGTORAD(m->ViewRotateYDefault));
|
||||
}
|
||||
|
||||
void CGameView::CameraFollow(entity_id_t entity)
|
||||
{
|
||||
m->FollowEntity = entity;
|
||||
}
|
||||
|
||||
InReaction game_view_handler(const SDL_Event_* ev)
|
||||
{
|
||||
// put any events that must be processed even if inactive here
|
||||
|
@ -23,6 +23,7 @@ extern float g_MaxZoomHeight; //note: Max terrain height is this minus YMinOffs
|
||||
extern float g_YMinOffset;
|
||||
|
||||
#include "renderer/Scene.h"
|
||||
#include "simulation2/system/Entity.h"
|
||||
|
||||
#include "lib/input.h" // InReaction - can't forward-declare enum
|
||||
|
||||
@ -85,6 +86,7 @@ public:
|
||||
void MoveCameraTarget(const CVector3D& target);
|
||||
void ResetCameraTarget(const CVector3D& target);
|
||||
void ResetCameraAngleZoom();
|
||||
void CameraFollow(entity_id_t entity);
|
||||
|
||||
CCamera *GetCamera();
|
||||
CCinemaManager* GetCinema();
|
||||
|
@ -73,11 +73,6 @@ void PopGuiPage(void* UNUSED(cbdata))
|
||||
g_GUI->PopPage();
|
||||
}
|
||||
|
||||
bool IsNewSimulation(void* UNUSED(cbdata))
|
||||
{
|
||||
return true; // XXX: delete this function
|
||||
}
|
||||
|
||||
CScriptVal GuiInterfaceCall(void* cbdata, std::wstring name, CScriptVal data)
|
||||
{
|
||||
CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
|
||||
@ -317,6 +312,16 @@ void SetRevealMap(void* UNUSED(cbdata), bool enabled)
|
||||
cmpRangeManager->SetLosRevealAll(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start / stop camera following mode
|
||||
* @param entityid unit id to follow. If zero, stop following mode
|
||||
*/
|
||||
void CameraFollow(void* UNUSED(cbdata), entity_id_t entityid)
|
||||
{
|
||||
if (g_Game && g_Game->GetView())
|
||||
g_Game->GetView()->CameraFollow(entityid);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void GuiScriptingInit(ScriptInterface& scriptInterface)
|
||||
@ -328,7 +333,6 @@ void GuiScriptingInit(ScriptInterface& scriptInterface)
|
||||
scriptInterface.RegisterFunction<void, &PopGuiPage>("PopGuiPage");
|
||||
|
||||
// Simulation<->GUI interface functions:
|
||||
scriptInterface.RegisterFunction<bool, &IsNewSimulation>("IsNewSimulation");
|
||||
scriptInterface.RegisterFunction<CScriptVal, std::wstring, CScriptVal, &GuiInterfaceCall>("GuiInterfaceCall");
|
||||
scriptInterface.RegisterFunction<void, CScriptVal, &PostNetworkCommand>("PostNetworkCommand");
|
||||
|
||||
@ -357,4 +361,5 @@ void GuiScriptingInit(ScriptInterface& scriptInterface)
|
||||
scriptInterface.RegisterFunction<bool, &AtlasIsAvailable>("AtlasIsAvailable");
|
||||
scriptInterface.RegisterFunction<CScriptVal, std::wstring, &LoadMapData>("LoadMapData");
|
||||
scriptInterface.RegisterFunction<void, bool, &SetRevealMap>("SetRevealMap");
|
||||
scriptInterface.RegisterFunction<void, entity_id_t, &CameraFollow>("CameraFollow");
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ static SHotkeyInfo hotkeyInfo[] =
|
||||
{ HOTKEY_WIREFRAME, "wireframe", SDLK_w, 0 },
|
||||
{ HOTKEY_TOGGLEFULLSCREEN, "togglefullscreen", 0, 0 },
|
||||
{ HOTKEY_CAMERA_RESET, "camera.reset", 0, 0 },
|
||||
{ HOTKEY_CAMERA_FOLLOW, "camera.follow", 0, 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 },
|
||||
|
@ -55,6 +55,7 @@ enum
|
||||
HOTKEY_WIREFRAME,
|
||||
HOTKEY_TOGGLEFULLSCREEN,
|
||||
HOTKEY_CAMERA_RESET,
|
||||
HOTKEY_CAMERA_FOLLOW,
|
||||
HOTKEY_CAMERA_ZOOM_IN,
|
||||
HOTKEY_CAMERA_ZOOM_OUT,
|
||||
HOTKEY_CAMERA_ZOOM_WHEEL_IN,
|
||||
|
@ -83,6 +83,7 @@ public:
|
||||
m_ComponentManager.ResetState();
|
||||
|
||||
m_DeltaTime = 0.0;
|
||||
m_LastFrameOffset = 0.0f;
|
||||
m_TurnNumber = 0;
|
||||
|
||||
CParamNode noParam;
|
||||
@ -133,6 +134,7 @@ public:
|
||||
CSimContext m_SimContext;
|
||||
CComponentManager m_ComponentManager;
|
||||
double m_DeltaTime;
|
||||
float m_LastFrameOffset;
|
||||
|
||||
std::wstring m_StartupScript;
|
||||
CScriptValRooted m_MapSettings;
|
||||
@ -245,6 +247,8 @@ bool CSimulation2Impl::Update(int turnLength, const std::vector<SimulationComman
|
||||
|
||||
void CSimulation2Impl::Interpolate(float frameLength, float frameOffset)
|
||||
{
|
||||
m_LastFrameOffset = frameOffset;
|
||||
|
||||
CMessageInterpolate msg(frameLength, frameOffset);
|
||||
m_ComponentManager.BroadcastMessage(msg);
|
||||
}
|
||||
@ -376,6 +380,11 @@ void CSimulation2::RenderSubmit(SceneCollector& collector, const CFrustum& frust
|
||||
m->m_ComponentManager.BroadcastMessage(msg);
|
||||
}
|
||||
|
||||
float CSimulation2::GetLastFrameOffset() const
|
||||
{
|
||||
return m->m_LastFrameOffset;
|
||||
}
|
||||
|
||||
bool CSimulation2::LoadScripts(const VfsPath& path)
|
||||
{
|
||||
return m->LoadScripts(path);
|
||||
|
@ -114,6 +114,12 @@ public:
|
||||
void Interpolate(float frameLength, float frameOffset);
|
||||
void RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling);
|
||||
|
||||
/**
|
||||
* Returns the last frame offset passed to Interpolate(), i.e. the offset corresponding
|
||||
* to the currently-rendered scene.
|
||||
*/
|
||||
float GetLastFrameOffset() const;
|
||||
|
||||
/**
|
||||
* Construct a new entity and add it to the world.
|
||||
* @param templateName see ICmpTemplateManager for syntax
|
||||
|
Loading…
Reference in New Issue
Block a user