You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
4.4 KiB
203 lines
4.4 KiB
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose: Default implementation for interface common to 2D and 3D views.
|
|
//
|
|
// $Workfile: $
|
|
// $Date: $
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// $Log: $
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
|
|
#include "stdafx.h"
|
|
#include "MapDoc.h"
|
|
#include "MapView.h"
|
|
#include "History.h"
|
|
#include "mapsolid.h"
|
|
#include "camera.h"
|
|
|
|
#define MMNOMIXER
|
|
#include <mmsystem.h>
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include <tier0/memdbgon.h>
|
|
|
|
|
|
#pragma warning(disable:4244 4305)
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Constructor, sets to inactive.
|
|
//-----------------------------------------------------------------------------
|
|
CMapView::CMapView(void)
|
|
{
|
|
m_bActive = false;
|
|
m_bUpdateView = false;
|
|
m_eDrawType = VIEW_INVALID;
|
|
m_pCamera = NULL;
|
|
m_dwTimeLastRender = 0;
|
|
m_nRenderedFrames = 0;
|
|
m_pToolManager = NULL;
|
|
}
|
|
|
|
bool CMapView::IsOrthographic()
|
|
{
|
|
return m_pCamera->IsOrthographic();
|
|
}
|
|
|
|
void CMapView::UpdateView( int nFlags )
|
|
{
|
|
m_bUpdateView = true;
|
|
|
|
if ( nFlags & MAPVIEW_RENDER_NOW )
|
|
{
|
|
RenderView();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CMapView::ActivateView(bool bActivate)
|
|
{
|
|
if ( bActivate != m_bActive )
|
|
{
|
|
m_bActive = bActivate;
|
|
m_bUpdateView = true;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Recalculates framerate since the last call to this function and
|
|
// determines whether or not we are exceeding the framerate limit.
|
|
// Output : Returns true if we are beyond the framerate limit, false if not.
|
|
//-----------------------------------------------------------------------------
|
|
bool CMapView::ShouldRender()
|
|
{
|
|
DWORD dwTimeNow = timeGetTime();
|
|
|
|
if (m_dwTimeLastRender != 0)
|
|
{
|
|
DWORD dwTimeElapsed = dwTimeNow - m_dwTimeLastRender;
|
|
|
|
if ( dwTimeElapsed <= 0 )
|
|
return false;
|
|
|
|
float flFrameRate = (1000.0f / dwTimeElapsed);
|
|
|
|
if (flFrameRate > 100.0f)
|
|
{
|
|
// never update view faster then 100Hz
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// update view if needed
|
|
if ( m_bUpdateView )
|
|
{
|
|
m_dwTimeLastRender = dwTimeNow;
|
|
m_nRenderedFrames++;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : point - Point in client coordinates.
|
|
// bMakeFirst -
|
|
// Output : Returns true on success, false on failure.
|
|
//-----------------------------------------------------------------------------
|
|
bool CMapView::SelectAt(const Vector2D &ptClient, bool bMakeFirst, bool bFace)
|
|
{
|
|
CMapDoc *pDoc = GetMapDoc();
|
|
CSelection *pSelection = pDoc->GetSelection();
|
|
const CMapObjectList *pSelList = pSelection->GetList();
|
|
|
|
pSelection->ClearHitList();
|
|
|
|
GetHistory()->MarkUndoPosition(pSelList, "Selection");
|
|
|
|
//
|
|
// Check all the objects in the world for a hit at this point.
|
|
//
|
|
|
|
HitInfo_t HitData[MAX_PICK_HITS];
|
|
int nHits = ObjectsAt(ptClient, HitData, MAX_PICK_HITS);
|
|
|
|
//
|
|
// If there were no hits at the given point, clear selection.
|
|
//
|
|
if ( nHits == 0 )
|
|
{
|
|
if (bMakeFirst)
|
|
{
|
|
pDoc->SelectFace(NULL, 0, scClear|scSaveChanges );
|
|
pDoc->SelectObject(NULL, scClear|scSaveChanges );
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
SelectMode_t eSelectMode = pSelection->GetMode();
|
|
|
|
for ( int i=0; i<nHits; i++ )
|
|
{
|
|
if ( HitData[i].pObject )
|
|
{
|
|
CMapClass *pSelObject = HitData[i].pObject->PrepareSelection( eSelectMode );
|
|
if (pSelObject)
|
|
{
|
|
pSelection->AddHit(pSelObject);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// If we're selecting faces, mark all faces on the first solid we hit.
|
|
//
|
|
if ( bFace )
|
|
{
|
|
const CMapObjectList *pList = pSelection->GetHitList();
|
|
FOR_EACH_OBJ( *pList, pos )
|
|
{
|
|
CMapClass *pObject = pList->Element(pos);
|
|
if (pObject->IsMapClass(MAPCLASS_TYPE(CMapSolid)))
|
|
{
|
|
pDoc->SelectFace((CMapSolid*)pObject, -1, scSelect | (bMakeFirst ? scClear : 0));
|
|
break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// Select a single object.
|
|
//
|
|
if ( bMakeFirst )
|
|
{
|
|
pDoc->SelectFace(NULL, 0, scClear|scSaveChanges);
|
|
pDoc->SelectObject(NULL, scClear|scSaveChanges);
|
|
}
|
|
|
|
pSelection->SetCurrentHit(hitFirst);
|
|
|
|
return true;
|
|
}
|
|
|
|
void CMapView::BuildRay( const Vector2D &vView, Vector& vStart, Vector& vEnd )
|
|
{
|
|
m_pCamera->BuildRay( vView, vStart, vEnd );
|
|
}
|
|
|
|
const Vector &CMapView::GetViewAxis()
|
|
{
|
|
static Vector vForward;
|
|
m_pCamera->GetViewForward(vForward);
|
|
return vForward;
|
|
}
|
|
|
|
|