summaryrefslogtreecommitdiff
path: root/hammer/ToolCamera.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /hammer/ToolCamera.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'hammer/ToolCamera.cpp')
-rw-r--r--hammer/ToolCamera.cpp816
1 files changed, 816 insertions, 0 deletions
diff --git a/hammer/ToolCamera.cpp b/hammer/ToolCamera.cpp
new file mode 100644
index 0000000..ee54d2d
--- /dev/null
+++ b/hammer/ToolCamera.cpp
@@ -0,0 +1,816 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "stdafx.h"
+#include "ToolCamera.h"
+#include "SaveInfo.h"
+#include "MainFrm.h" // dvs: remove?
+#include "MapDefs.h"
+#include "MapDoc.h"
+#include "MapView2D.h"
+#include "MapView3D.h"
+#include "Options.h"
+#include "Render2D.h"
+#include "StatusBarIDs.h" // dvs: remove
+#include "ToolManager.h"
+#include "hammer_mathlib.h"
+#include "vgui/Cursor.h"
+#include "Selection.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include <tier0/memdbgon.h>
+
+#pragma warning(disable:4244)
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+Camera3D::Camera3D(void)
+{
+ Cameras.EnsureCapacity(16);
+ SetEmpty();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns true if we are dragging a camera, false if not. // dvs: rename
+//-----------------------------------------------------------------------------
+bool Camera3D::IsEmpty(void)
+{
+ return (Cameras.Count() == 0);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Camera3D::SetEmpty(void)
+{
+ Cameras.RemoveAll();
+ m_iActiveCamera = -1;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pt -
+// BOOL -
+// Output : int
+//-----------------------------------------------------------------------------
+int Camera3D::HitTest(CMapView *pView, const Vector2D &ptClient, bool bTestHandles)
+{
+ for(int i = 0; i < Cameras.Count(); i++)
+ {
+ for ( int j=0; j<2; j++ )
+ {
+ if( HitRect( pView, ptClient, Cameras[i].position[j], HANDLE_RADIUS ) )
+ {
+ return MAKELONG(i+1, j);
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Get rid of extra cameras if we have too many.
+//-----------------------------------------------------------------------------
+void Camera3D::EnsureMaxCameras()
+{
+ int nMax = max( Options.general.nMaxCameras, 1 );
+
+ int nToRemove = Cameras.Count() - nMax;
+ if ( nToRemove > 0 )
+ {
+ m_iActiveCamera = max( m_iActiveCamera - nToRemove, 0 );
+
+ while ( nToRemove-- )
+ Cameras.Remove( 0 );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : bSave -
+//-----------------------------------------------------------------------------
+void Camera3D::FinishTranslation(bool bSave)
+{
+ if (bSave)
+ {
+ if ( m_iActiveCamera == Cameras.Count() )
+ {
+ Cameras.AddToTail();
+ EnsureMaxCameras();
+ }
+
+ Cameras[m_iActiveCamera] = m_MoveCamera;
+ }
+
+ Tool3D::FinishTranslation(bSave);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pt -
+// uFlags -
+// CSize& -
+// Output : Returns TRUE on success, FALSE on failure.
+//-----------------------------------------------------------------------------
+bool Camera3D::UpdateTranslation(const Vector &vUpdate, UINT uFlags)
+{
+ Vector vCamDelta = m_MoveCamera.position[1] - m_MoveCamera.position[0];
+
+ Vector vNewPos = m_vOrgPos + vUpdate;
+
+ // snap point if need be
+ if ( uFlags & constrainSnap )
+ m_pDocument->Snap( vNewPos, uFlags );
+
+ m_MoveCamera.position[m_nMovePositionIndex] = vNewPos;
+
+ if(uFlags & constrainMoveAll)
+ {
+ m_MoveCamera.position[(m_nMovePositionIndex+1)%2] = vNewPos + vCamDelta;
+ }
+
+ m_pDocument->UpdateAllViews( MAPVIEW_UPDATE_TOOL );
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pCamPos -
+// iCamera -
+//-----------------------------------------------------------------------------
+void Camera3D::GetCameraPos(Vector &vViewPos, Vector &vLookAt)
+{
+ if(!inrange(m_iActiveCamera, 0, Cameras.Count()))
+ {
+ vViewPos.Init();
+ vLookAt.Init();
+ return;
+ }
+
+ vViewPos = Cameras[m_iActiveCamera].position[0];
+ vLookAt = Cameras[m_iActiveCamera].position[1];
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pCamPos -
+// iCamera -
+//-----------------------------------------------------------------------------
+void Camera3D::AddCamera(CAMSTRUCT &camera)
+{
+ Cameras.AddToTail( camera );
+ EnsureMaxCameras();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pRender -
+//-----------------------------------------------------------------------------
+void Camera3D::RenderTool2D(CRender2D *pRender)
+{
+ for (int i = 0; i < Cameras.Count(); i++)
+ {
+ CAMSTRUCT *pDrawCam = &Cameras[i];
+
+ if (IsTranslating() && (i == m_iActiveCamera))
+ {
+ pDrawCam = &m_MoveCamera;
+ }
+
+ //
+ // Draw the line between.
+ //
+ if (i == m_iActiveCamera)
+ {
+ pRender->SetDrawColor( 255, 0, 0 );
+ }
+ else
+ {
+ pRender->SetDrawColor( 0, 255, 255 );
+ }
+
+ pRender->DrawLine( pDrawCam->position[MovePos], pDrawCam->position[MoveLook] );
+
+ //
+ // Draw camera handle.
+ //
+ pRender->SetHandleStyle(HANDLE_RADIUS, CRender::HANDLE_CIRCLE );
+ pRender->SetHandleColor( 0, 255, 255 );
+ pRender->DrawHandle( pDrawCam->position[MovePos] );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles key values being read from the MAP file.
+// Input : szKey - Key being loaded.
+// szValue - Value of the key being loaded.
+// pCam - Camera structure to place the values into.
+// Output : Returns ChunkFile_Ok to indicate success.
+//-----------------------------------------------------------------------------
+ChunkFileResult_t Camera3D::LoadCameraKeyCallback(const char *szKey, const char *szValue, CAMSTRUCT *pCam)
+{
+ if (!stricmp(szKey, "look"))
+ {
+ CChunkFile::ReadKeyValueVector3(szValue, pCam->position[MoveLook]);
+ }
+ else if (!stricmp(szKey, "position"))
+ {
+ CChunkFile::ReadKeyValueVector3(szValue, pCam->position[MovePos]);
+ }
+
+ return(ChunkFile_Ok);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles key values being read from the MAP file.
+// Input : szKey - Key being loaded.
+// szValue - Value of the key being loaded.
+// pCam - Camera structure to place the values into.
+// Output : Returns ChunkFile_Ok to indicate success.
+//-----------------------------------------------------------------------------
+ChunkFileResult_t Camera3D::LoadCamerasKeyCallback(const char *szKey, const char *szValue, Camera3D *pCameras)
+{
+ if (!stricmp(szKey, "activecamera"))
+ {
+ pCameras->m_iActiveCamera = atoi(szValue);
+ }
+
+ return(ChunkFile_Ok);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pLoadInfo -
+// *pSolid -
+// Output : ChunkFileResult_t
+//-----------------------------------------------------------------------------
+ChunkFileResult_t Camera3D::LoadCameraCallback(CChunkFile *pFile, Camera3D *pCameras)
+{
+ CAMSTRUCT Cam;
+ memset(&Cam, 0, sizeof(Cam));
+
+ ChunkFileResult_t eResult = pFile->ReadChunk((KeyHandler_t)LoadCameraKeyCallback, &Cam);
+
+ if (eResult == ChunkFile_Ok)
+ {
+ pCameras->AddCamera( Cam );
+ }
+
+ return(eResult);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pFile -
+// Output : ChunkFileResult_t
+//-----------------------------------------------------------------------------
+ChunkFileResult_t Camera3D::LoadVMF(CChunkFile *pFile)
+{
+ //
+ // Set up handlers for the subchunks that we are interested in.
+ //
+ CChunkHandlerMap Handlers;
+ Handlers.AddHandler("camera", (ChunkHandler_t)LoadCameraCallback, this);
+
+ pFile->PushHandlers(&Handlers);
+ ChunkFileResult_t eResult = pFile->ReadChunk((KeyHandler_t)LoadCamerasKeyCallback, this);
+ pFile->PopHandlers();
+
+ if (eResult == ChunkFile_Ok)
+ {
+ //
+ // Make sure the active camera is legal.
+ //
+ if (Cameras.Count() == 0)
+ {
+ m_iActiveCamera = -1;
+ }
+ else if (!inrange(m_iActiveCamera, 0, Cameras.Count()))
+ {
+ m_iActiveCamera = 0;
+ }
+ }
+
+ return(eResult);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &dir -
+// &pos -
+//-----------------------------------------------------------------------------
+void Camera3D::UpdateActiveCamera(Vector &vViewPos, Vector &vDir)
+{
+ if(!inrange(m_iActiveCamera, 0, Cameras.Count()))
+ return;
+
+ Vector& camPos = Cameras[m_iActiveCamera].position[MovePos];
+ Vector& lookPos = Cameras[m_iActiveCamera].position[MoveLook];
+
+ // get current length
+ Vector delta;
+ for(int i = 0; i < 3; i++)
+ delta[i] = camPos[i] - lookPos[i];
+
+ float length = VectorLength(delta);
+
+ if ( length < 1 )
+ length = 1;
+
+ camPos = vViewPos;
+
+ for(int i = 0; i < 3; i++)
+ lookPos[i] = camPos[i] + vDir[i] * length;
+
+ if ( IsActiveTool() )
+ {
+ if (Options.view2d.bCenteroncamera)
+ {
+ VIEW2DINFO vi;
+ vi.wFlags = VI_CENTER;
+ vi.ptCenter = vViewPos;
+ m_pDocument->SetView2dInfo(vi);
+ }
+
+ m_pDocument->UpdateAllViews( MAPVIEW_UPDATE_TOOL );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : type -
+//-----------------------------------------------------------------------------
+void Camera3D::SetNextCamera(SNCTYPE type)
+{
+ if(Cameras.Count()==0)
+ {
+ m_iActiveCamera = -1;
+ return;
+ }
+
+ switch(type)
+ {
+ case sncNext:
+ ++m_iActiveCamera;
+ if(m_iActiveCamera >= Cameras.Count() )
+ m_iActiveCamera = 0;
+ break;
+ case sncPrev:
+ --m_iActiveCamera;
+ if(m_iActiveCamera < 0)
+ m_iActiveCamera = Cameras.Count()-1;
+ break;
+ case sncFirst:
+ m_iActiveCamera = 0;
+ break;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Camera3D::DeleteActiveCamera()
+{
+ if(!inrange(m_iActiveCamera, 0, Cameras.Count()))
+ return;
+
+ Cameras.Remove(m_iActiveCamera);
+
+ if(m_iActiveCamera >= Cameras.Count() )
+ m_iActiveCamera = Cameras.Count()-1;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : file -
+// fIsStoring -
+//-----------------------------------------------------------------------------
+void Camera3D::SerializeRMF(std::fstream& file, BOOL fIsStoring)
+{
+ float fVersion = 0.2f, fThisVersion;
+
+ int nCameras = Cameras.Count();
+
+ if(fIsStoring)
+ {
+ file.write((char*)&fVersion, sizeof(fVersion) );
+
+ file.write((char*)&m_iActiveCamera, sizeof(m_iActiveCamera) );
+ file.write((char*)&nCameras, sizeof(nCameras));
+ for(int i = 0; i < nCameras; i++)
+ {
+ file.write((char*)&Cameras[i], sizeof(CAMSTRUCT));
+ }
+ }
+ else
+ {
+ file.read((char*)&fThisVersion, sizeof(fThisVersion) );
+
+ if(fThisVersion >= 0.2f)
+ {
+ file.read((char*)&m_iActiveCamera, sizeof(m_iActiveCamera));
+ }
+
+ file.read((char*)&nCameras, sizeof (nCameras) );
+
+ Cameras.RemoveAll();
+ Cameras.EnsureCapacity(nCameras);
+
+ for(int i = 0; i < nCameras; i++)
+ {
+ CAMSTRUCT cam;
+ file.read((char*)&cam, sizeof(CAMSTRUCT));
+ Cameras.AddToTail( cam );
+ }
+ EnsureMaxCameras();
+
+ Assert( Cameras.Count() == nCameras );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pFile -
+// Output : ChunkFileResult_t
+//-----------------------------------------------------------------------------
+ChunkFileResult_t Camera3D::SaveVMF(CChunkFile *pFile, CSaveInfo *pSaveInfo)
+{
+ ChunkFileResult_t eResult = pFile->BeginChunk( GetVMFChunkName() );
+ if (eResult == ChunkFile_Ok)
+ {
+ eResult = pFile->WriteKeyValueInt("activecamera", m_iActiveCamera);
+ }
+
+ if (eResult == ChunkFile_Ok)
+ {
+ for (int i = 0; i < Cameras.Count(); i++)
+ {
+ eResult = pFile->BeginChunk("camera");
+
+ if (eResult == ChunkFile_Ok)
+ {
+ eResult = pFile->WriteKeyValueVector3("position", Cameras[i].position[MovePos]);
+ }
+
+ if (eResult == ChunkFile_Ok)
+ {
+ eResult = pFile->WriteKeyValueVector3("look", Cameras[i].position[MoveLook]);
+ }
+
+ if (eResult == ChunkFile_Ok)
+ {
+ eResult = pFile->EndChunk();
+ }
+
+ if (eResult != ChunkFile_Ok)
+ {
+ break;
+ }
+ }
+ }
+
+ if (eResult == ChunkFile_Ok)
+ {
+ eResult = pFile->EndChunk();
+ }
+
+ return(eResult);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the key down event in the 2D view.
+// Input : Per CWnd::OnKeyDown.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool Camera3D::OnKeyDown2D(CMapView2D *pView, UINT nChar, UINT nRepCnt, UINT nFlags)
+{
+ if (nChar == VK_DELETE || nChar == VK_NEXT || nChar == VK_PRIOR)
+ {
+ CMapDoc *pDoc = pView->GetMapDoc();
+
+ if (nChar == VK_DELETE)
+ {
+ DeleteActiveCamera();
+ }
+ else if (nChar == VK_NEXT)
+ {
+ SetNextCamera(Camera3D::sncNext);
+ }
+ else
+ {
+ SetNextCamera(Camera3D::sncPrev);
+ }
+
+ Vector viewPos,lookAt;
+
+ GetCameraPos( viewPos, lookAt );
+ pDoc->UpdateAllCameras( &viewPos, &lookAt, NULL );
+
+ return true;
+ }
+ else if (nChar == VK_ESCAPE)
+ {
+ OnEscape();
+ return true;
+ }
+
+ return false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the left mouse button down event in the 2D view.
+// Input : Per CWnd::OnLButtonDown.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool Camera3D::OnLMouseDown2D(CMapView2D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ CMapDoc *pDoc = pView->GetMapDoc();
+
+ pView->SetCapture();
+
+ //
+ // If there are no cameras created yet or they are holding down
+ // the SHIFT key, create a new camera now.
+ //
+
+ Vector vecWorld;
+ pView->ClientToWorld( vecWorld, vPoint );
+
+ if ( IsEmpty() || (nFlags & MK_SHIFT))
+ {
+ //
+ // Build a point in world space to place the new camera.
+ //
+
+ if ( !pDoc->GetSelection()->IsEmpty() )
+ {
+ Vector vecCenter;
+ pDoc->GetSelection()->GetBoundsCenter(vecCenter);
+ vecWorld[pView->axThird] = vecCenter[pView->axThird];
+ }
+ else
+ {
+ vecWorld[pView->axThird] = COORD_NOTINIT;
+ pDoc->GetBestVisiblePoint(vecWorld);
+ }
+
+ //
+ // Create a new camera.
+ //
+ m_vOrgPos = vecWorld;
+ m_MoveCamera.position[MovePos] = vecWorld;
+ m_MoveCamera.position[MoveLook] = vecWorld;
+ m_nMovePositionIndex = MoveLook;
+
+ // set as active camera
+ m_iActiveCamera = Cameras.AddToTail(m_MoveCamera);;
+ EnsureMaxCameras();
+
+ StartTranslation(pView, vPoint );
+ }
+ //
+ // Otherwise, try to drag an existing camera handle.
+ //
+ else
+ {
+ int dwHit = HitTest( pView, vPoint );
+
+ if ( dwHit )
+ {
+ m_iActiveCamera = LOWORD(dwHit)-1;
+ m_MoveCamera = Cameras[m_iActiveCamera];
+ m_nMovePositionIndex = HIWORD(dwHit);
+ m_vOrgPos = m_MoveCamera.position[m_nMovePositionIndex];
+ StartTranslation( pView, vPoint );
+ }
+ }
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the left mouse button up event in the 2D view.
+// Input : Per CWnd::OnLButtonUp.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool Camera3D::OnLMouseUp2D(CMapView2D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ ReleaseCapture();
+
+ if (IsTranslating())
+ {
+ FinishTranslation(true);
+
+ Vector viewPos, lookAt;
+ GetCameraPos( viewPos, lookAt );
+
+ m_pDocument->UpdateAllCameras( &viewPos, &lookAt, NULL );
+ }
+
+ m_pDocument->UpdateStatusbar();
+
+ return true;
+}
+
+unsigned int Camera3D::GetConstraints(unsigned int nKeyFlags)
+{
+ unsigned int uConstraints = Tool3D::GetConstraints( nKeyFlags );
+
+ if(nKeyFlags & MK_CONTROL)
+ {
+ uConstraints |= constrainMoveAll;
+ }
+
+ return uConstraints;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the mouse move event in the 2D view.
+// Input : Per CWnd::OnMouseMove.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool Camera3D::OnMouseMove2D(CMapView2D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ CMapDoc *pDoc = pView->GetMapDoc();
+ if (!pDoc)
+ {
+ return true;
+ }
+
+ vgui::HCursor hCursor = vgui::dc_arrow;
+
+ unsigned int uConstraints = GetConstraints( nFlags );
+
+ // Make sure the point is visible.
+
+ pView->ToolScrollToPoint( vPoint );
+
+ //
+ // Convert to world coords.
+ //
+ Vector vecWorld;
+ pView->ClientToWorld(vecWorld, vPoint);
+
+ //
+ // Update status bar position display.
+ //
+ char szBuf[128];
+
+ m_pDocument->Snap(vecWorld,uConstraints);
+
+ sprintf(szBuf, " @%.0f, %.0f ", vecWorld[pView->axHorz], vecWorld[pView->axVert] );
+ SetStatusText(SBI_COORDS, szBuf);
+
+ if (IsTranslating())
+ {
+ Tool3D::UpdateTranslation(pView, vPoint, uConstraints );
+
+ hCursor = vgui::dc_none;
+ }
+ else if ( !IsEmpty() )
+ {
+ //
+ // If the cursor is on a handle, set it to a cross.
+ //
+ if ( HitTest( pView, vPoint, true) )
+ {
+ hCursor = vgui::dc_crosshair;
+ }
+ }
+
+ if ( hCursor != vgui::dc_none )
+ pView->SetCursor( hCursor );
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the left mouse button down event in the 3D view.
+// Input : Per CWnd::OnLButtonDown.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool Camera3D::OnLMouseDown3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ pView->EnableRotating(true);
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the left mouse up down event in the 3D view.
+// Input : Per CWnd::OnLButtonUp.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool Camera3D::OnLMouseUp3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ pView->EnableRotating(false);
+ pView->UpdateCameraVariables();
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the right mouse button down event in the 3D view.
+// Input : Per CWnd::OnRButtonDown.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool Camera3D::OnRMouseDown3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ pView->EnableStrafing(true);
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the right mouse button up event in the 3D view.
+// Input : Per CWnd::OnRButtonUp.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool Camera3D::OnRMouseUp3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ pView->EnableStrafing(false);
+ pView->UpdateCameraVariables();
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the key down event in the 3D view.
+// Input : Per CWnd::OnKeyDown.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool Camera3D::OnKeyDown3D(CMapView3D *pView, UINT nChar, UINT nRepCnt, UINT nFlags)
+{
+ if (nChar == VK_DELETE || nChar == VK_NEXT || nChar == VK_PRIOR)
+ {
+ CMapDoc *pDoc = pView->GetMapDoc();
+
+ if (nChar == VK_DELETE)
+ {
+ DeleteActiveCamera();
+ }
+ else if (nChar == VK_NEXT)
+ {
+ SetNextCamera(Camera3D::sncNext);
+ }
+ else
+ {
+ SetNextCamera(Camera3D::sncPrev);
+ }
+
+ Vector viewPos, lookAt;
+ GetCameraPos( viewPos, lookAt );
+
+ pDoc->UpdateAllCameras( &viewPos, &lookAt, NULL );
+
+ return true;
+ }
+ else if (nChar == VK_ESCAPE)
+ {
+ OnEscape();
+ return true;
+ }
+
+ return false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the escape key in the 2D or 3D views.
+//-----------------------------------------------------------------------------
+void Camera3D::OnEscape(void)
+{
+ //
+ // Stop using the camera tool.
+ //
+ m_pDocument->GetTools()->SetTool(TOOL_POINTER);
+}
+