1409 lines
34 KiB
C++
1409 lines
34 KiB
C++
// TopRendererWnd.cpp: implementation of the C2DViewport class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "StdAfx.h"
|
|
#include "2DViewport.h"
|
|
#include "CryEditDoc.h"
|
|
|
|
#include "Grid.h"
|
|
#include "DisplaySettings.h"
|
|
#include "EditTool.h"
|
|
#include "ViewManager.h"
|
|
#include "Settings.h"
|
|
#include "Objects\ObjectManager.h"
|
|
|
|
// Include OpenGL
|
|
//#include "GL\gl.h"
|
|
#include "Brush\Brush.h"
|
|
#include "Objects\BrushObject.h"
|
|
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[]=__FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
#define MARKER_SIZE 6.0f
|
|
#define MARKER_DIR_SIZE 10.0f
|
|
#define SELECTION_RADIUS 30.0f
|
|
|
|
#define GL_RGBA 0x1908
|
|
#define GL_BGRA 0x80E1
|
|
|
|
#define BACKGROUND_COLOR Vec3(1.0f,1.0f,1.0f)
|
|
#define SELECTION_RECT_COLOR Vec3(0.8f,0.8f,0.8f)
|
|
#define MINOR_GRID_COLOR Vec3(0.55f,0.55f,0.55f)
|
|
#define MAJOR_GRID_COLOR Vec3(0.6f,0.6f,0.6f)
|
|
#define AXIS_GRID_COLOR Vec3(0,0,0)
|
|
#define GRID_TEXT_COLOR Vec3(0,0,1.0f)
|
|
|
|
#define MAX_WORLD_SIZE 10000
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
IMPLEMENT_DYNCREATE(C2DViewport,CViewport)
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
BEGIN_MESSAGE_MAP(C2DViewport, CViewport)
|
|
//{{AFX_MSG_MAP(C2DViewport)
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_MBUTTONUP()
|
|
ON_WM_LBUTTONUP()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_SIZE()
|
|
ON_WM_ERASEBKGND()
|
|
ON_WM_PAINT()
|
|
ON_WM_CREATE()
|
|
ON_WM_RBUTTONDOWN()
|
|
ON_WM_RBUTTONUP()
|
|
ON_WM_MOUSEWHEEL()
|
|
//}}AFX_MSG_MAP
|
|
ON_WM_DESTROY()
|
|
END_MESSAGE_MAP()
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
static int m_fontList = 0;
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
C2DViewport::C2DViewport()
|
|
{
|
|
CLogFile::WriteLine("2D Viewport Created");
|
|
|
|
// Scroll offset equals origin
|
|
m_rcSelect.SetRect( 0,0,0,0 );
|
|
|
|
m_viewType = ET_ViewportXY;
|
|
m_axis = VPA_XY;
|
|
|
|
m_bShowTerrain = true;
|
|
m_gridAlpha = 1;
|
|
|
|
m_origin2D.Set(0,0,0);
|
|
|
|
//m_colorGridText = RGB(0,0,255);
|
|
//m_colorAxisText = RGB(0,0,0);
|
|
//m_colorBackground = Vec2Rgb(BACKGROUND_COLOR);
|
|
//m_gridAlpha = 0.3f;
|
|
m_colorGridText = RGB(220,220,220);
|
|
m_colorAxisText = RGB(220,220,220);
|
|
m_colorBackground = RGB(128,128,128);
|
|
|
|
m_screenTM.SetIdentity();
|
|
|
|
m_fZoomFactor = 1;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
C2DViewport::~C2DViewport()
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::SetType( EViewportType type )
|
|
{
|
|
//assert( type == ET_ViewportXY || type == ET_ViewportXZ || type == ET_ViewportYZ );
|
|
m_viewType = type;
|
|
|
|
switch (m_viewType)
|
|
{
|
|
case ET_ViewportXY:
|
|
m_axis = VPA_XY;
|
|
break;
|
|
case ET_ViewportXZ:
|
|
m_axis = VPA_XZ;
|
|
break;
|
|
case ET_ViewportYZ:
|
|
m_axis = VPA_YZ;
|
|
break;
|
|
};
|
|
|
|
SetAxis( m_axis );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::SetAxis( EViewportAxis axis )
|
|
{
|
|
m_axis = axis;
|
|
switch (m_axis)
|
|
{
|
|
case VPA_XY:
|
|
m_cullAxis = 2;
|
|
break;
|
|
case VPA_XZ:
|
|
m_cullAxis = 1;
|
|
break;
|
|
case VPA_YZ:
|
|
m_cullAxis = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::CalculateViewTM()
|
|
{
|
|
Matrix44 tm;
|
|
tm.SetIdentity();
|
|
m_constructionViewTM.SetIdentity();
|
|
float fScale = GetZoomFactor();
|
|
Vec3 origin = GetOrigin2D();
|
|
//float origin[2] = { -m_cScrollOffset.x,-m_cScrollOffset.y };
|
|
|
|
float height = m_rcClient.Height()/fScale;
|
|
|
|
Vec3 v1;
|
|
switch (m_axis)
|
|
{
|
|
case VPA_XY:
|
|
|
|
tm = Matrix33::CreateScale( Vec3(fScale,-fScale,fScale) ) * tm; // No fScale for Z
|
|
|
|
tm.SetTranslationOLD( Vec3(-origin.x,height+origin.y,0)*fScale );
|
|
break;
|
|
case VPA_XZ:
|
|
//tm.ScaleMatrix( fScale,fScale,fScale );
|
|
//tm.RotateX( 90 * PI/180.0f );
|
|
m_constructionViewTM.BuildFromVectors( Vec3(1,0,0),Vec3(0,0,1),Vec3(0,1,0),Vec3(0,0,0) );
|
|
//m_constructionViewTM.BuildFromVectors( Vec3(1,0,0),Vec3(0,0,1),Vec3(0,1,0),Vec3(0,0,0) );
|
|
tm.BuildFromVectors( Vec3(1,0,0)*fScale,Vec3(0,0,1)*fScale,Vec3(0,-1,0)*fScale,Vec3(0,0,0) );
|
|
tm.SetTranslationOLD( Vec3(-origin.x,height+origin.z,0)*fScale );
|
|
break;
|
|
|
|
case VPA_YZ:
|
|
//tm.RotateY( 180 * PI/180.0f );
|
|
m_constructionViewTM.BuildFromVectors( Vec3(0,1,0),Vec3(0,0,1),Vec3(1,0,0),Vec3(0,0,0) );
|
|
//m_constructionViewTM.BuildFromVectors( Vec3(0,0,1),Vec3(1,0,0),Vec3(0,1,0),Vec3(0,0,0) );
|
|
tm.BuildFromVectors( Vec3(0,0,1)*fScale,Vec3(1,0,0)*fScale,Vec3(0,-1,0)*fScale,Vec3(0,0,0) ); // No fScale for Z
|
|
tm.SetTranslationOLD( Vec3(-origin.y,height+origin.z,0)*fScale );
|
|
break;
|
|
}
|
|
SetViewTM( m_constructionViewTM );
|
|
m_screenTM = tm;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::ResetContent()
|
|
{
|
|
CViewport::ResetContent();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::UpdateContent( int flags )
|
|
{
|
|
CViewport::UpdateContent(flags);
|
|
if (flags & eUpdateObjects)
|
|
{
|
|
Invalidate(FALSE);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::OnRButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
m_bRMouseDown = true;
|
|
SetObjectCursor(0);
|
|
|
|
if (GetIEditor()->IsInGameMode())
|
|
return;
|
|
|
|
if (GetIEditor()->GetEditTool())
|
|
{
|
|
GetIEditor()->GetEditTool()->MouseCallback( this,eMouseRDown,point,nFlags );
|
|
}
|
|
|
|
// Save the mouse down position
|
|
m_RMouseDownPos = point;
|
|
|
|
m_prevZoomFactor = GetZoomFactor();
|
|
//m_prevScrollOffset = m_cScrollOffset;
|
|
|
|
CaptureMouse();
|
|
SetViewMode( ScrollZoomMode );
|
|
|
|
CViewport::OnRButtonDown(nFlags, point);
|
|
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::OnRButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
m_bRMouseDown = false;
|
|
ReleaseMouse();
|
|
SetViewMode( NothingMode );
|
|
|
|
CViewport::OnRButtonUp(nFlags, point);
|
|
|
|
GetViewManager()->UpdateViews(eUpdateObjects);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::OnMButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// User pressed the middle mouse button
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
CViewport::OnMButtonDown(nFlags, point);
|
|
|
|
// Save the mouse down position
|
|
m_RMouseDownPos = point;
|
|
|
|
/*
|
|
// Are we in spline mode or scroll / zoom mode ?
|
|
if (GetViewMode() == SplineMode)
|
|
{
|
|
// TODO
|
|
}
|
|
else*/
|
|
CaptureMouse();
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::OnMButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
ReleaseMouse();
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// User pressed the left mouse button
|
|
////////////////////////////////////////////////////////////////////////
|
|
if (GetViewMode() != NothingMode)
|
|
return;
|
|
|
|
m_cMouseDownPos = point;
|
|
m_prevZoomFactor = GetZoomFactor();
|
|
//m_prevScrollOffset = m_cScrollOffset;
|
|
|
|
CViewport::OnLButtonDown(nFlags, point);
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::OnLButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Process the various events depending on the selection and the view
|
|
// mode
|
|
////////////////////////////////////////////////////////////////////////
|
|
CViewport::OnLButtonUp(nFlags, point);
|
|
|
|
GetViewManager()->UpdateViews(eUpdateObjects);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
BOOL C2DViewport::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
|
|
{
|
|
float z = GetZoomFactor();
|
|
float scale = 1.2f * fabs(zDelta/120.0f);
|
|
if (zDelta > 0)
|
|
{
|
|
z = z * scale;
|
|
}
|
|
else
|
|
{
|
|
z = z / scale;
|
|
}
|
|
SetZoom( z,m_cMousePos );
|
|
|
|
GetViewManager()->UpdateViews(eUpdateObjects);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
m_cMousePos = point;
|
|
|
|
if (GetViewMode() == ScrollZoomMode)
|
|
{
|
|
CRect rc;
|
|
// You can only scroll while the middle mouse button is down
|
|
if (nFlags & MK_RBUTTON || nFlags & MK_MBUTTON)
|
|
{
|
|
if (nFlags & MK_SHIFT)
|
|
{
|
|
// Get the dimensions of the window
|
|
GetClientRect(&rc);
|
|
|
|
CRect rc;
|
|
GetClientRect( rc );
|
|
int w = rc.right;
|
|
int h = rc.bottom;
|
|
|
|
// Zoom to mouse position.
|
|
float z = m_prevZoomFactor + (point.y - m_RMouseDownPos.y) * 0.02f;
|
|
SetZoom( z,m_RMouseDownPos );
|
|
}
|
|
else
|
|
{
|
|
// Set the new scrolled coordinates
|
|
float fScale = GetZoomFactor();
|
|
float ofsx,ofsy;
|
|
GetScrollOffset( ofsx,ofsy );
|
|
ofsx -= (point.x - m_RMouseDownPos.x)/fScale;
|
|
ofsy += (point.y - m_RMouseDownPos.y)/fScale;
|
|
SetScrollOffset( ofsx,ofsy );
|
|
m_RMouseDownPos = point;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
CViewport::OnMouseMove(nFlags, point);
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//@FIXME: REMOVE
|
|
//GetViewManager()->UpdateViews(eUpdateObjects);
|
|
Invalidate(FALSE);
|
|
//////////////////////////////////////////////////////////////////////////
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::SetScrollOffset( float x,float y,bool bLimits )
|
|
{
|
|
if (bLimits)
|
|
{
|
|
float maxMapSize = 4096;
|
|
// Limit scroll offsets.
|
|
x = max(x,-maxMapSize);
|
|
y = max(y,-maxMapSize);
|
|
x = min(x,maxMapSize);
|
|
y = min(y,maxMapSize);
|
|
}
|
|
|
|
Vec3 org = GetOrigin2D();
|
|
switch (m_axis)
|
|
{
|
|
case VPA_XY:
|
|
org.x = x; org.y = y;
|
|
break;
|
|
case VPA_XZ:
|
|
org.x = x; org.z = y;
|
|
break;
|
|
case VPA_YZ:
|
|
org.y = x; org.z = y;
|
|
break;
|
|
}
|
|
|
|
SetOrigin2D(org);
|
|
|
|
CalculateViewTM();
|
|
//GetViewManager()->UpdateViews(eUpdateObjects);
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::GetScrollOffset( float &x,float &y )
|
|
{
|
|
Vec3 origin = GetOrigin2D();
|
|
switch (m_axis)
|
|
{
|
|
case VPA_XY:
|
|
x = origin.x;
|
|
y = origin.y;
|
|
break;
|
|
case VPA_XZ:
|
|
x = origin.x;
|
|
y = origin.z;
|
|
break;
|
|
case VPA_YZ:
|
|
x = origin.y;
|
|
y = origin.z;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::SetZoom( float fZoomFactor,CPoint center )
|
|
{
|
|
if (fZoomFactor < 0.01f)
|
|
fZoomFactor = 0.01f;
|
|
|
|
float prevz = GetZoomFactor();
|
|
|
|
// Zoom to mouse position.
|
|
float ofsx,ofsy;
|
|
GetScrollOffset( ofsx,ofsy );
|
|
|
|
float s1 = GetZoomFactor();
|
|
float s2 = fZoomFactor;
|
|
|
|
SetZoomFactor( fZoomFactor );
|
|
|
|
// Calculate new offset to center zoom on mouse.
|
|
float x2 = center.x;
|
|
float y2 = m_rcClient.Height() - center.y;
|
|
ofsx = -(x2/s2 - x2/s1 - ofsx);
|
|
ofsy = -(y2/s2 - y2/s1 - ofsy);
|
|
SetScrollOffset( ofsx,ofsy,false );
|
|
|
|
CalculateViewTM();
|
|
|
|
//GetViewManager()->UpdateViews(eUpdateObjects);
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
afx_msg void C2DViewport::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Re-evaluate the zoom / scroll offset values
|
|
// TODO: Restore the zoom rectangle instead of resetting it
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
CViewport::OnSize(nType, cx, cy);
|
|
|
|
GetClientRect( &m_rcClient );
|
|
CalculateViewTM();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::OnPaint()
|
|
{
|
|
CRect rc;
|
|
CPaintDC dc(this); // device context for painting
|
|
|
|
//Draw( dc,dc.m_ps.rcPaint );
|
|
Render();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
BOOL C2DViewport::OnEraseBkgnd(CDC* pDC)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
int C2DViewport::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
if (CViewport::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
m_renderer = GetIEditor()->GetRenderer();
|
|
if (!m_renderer)
|
|
{
|
|
// Create renderer.
|
|
m_renderer = GetIEditor()->GetSystem()->CreateRenderer( false,AfxGetInstanceHandle(),GetSafeHwnd() );
|
|
}
|
|
|
|
if (m_renderer)
|
|
{
|
|
m_renderer->CreateContext( m_hWnd );
|
|
m_renderer->MakeCurrent();
|
|
|
|
|
|
/*
|
|
if (!m_fontList)
|
|
{
|
|
// Create font list for this view.
|
|
// create GL font
|
|
|
|
CFont font;
|
|
|
|
font.CreateFont(
|
|
12, // logical height of font
|
|
6, // logical average character width
|
|
0, // angle of escapement
|
|
0, // base-line orientation angle
|
|
0, // font weight
|
|
0, // italic attribute flag
|
|
0, // underline attribute flag
|
|
0, // strikeout attribute flag
|
|
0, // character set identifier
|
|
0, // output precision
|
|
0, // clipping precision
|
|
0, // output quality
|
|
0, // pitch and family
|
|
"system font" // pointer to typeface name string
|
|
);
|
|
|
|
CClientDC dc(this);
|
|
CFont* def_font = dc.SelectObject(&font);
|
|
|
|
m_fontList = glGenLists (256);
|
|
if (m_fontList == 0)
|
|
CLogFile::WriteLine( "Couldn't create font drawlists" );
|
|
|
|
if (!wglUseFontBitmapsA( dc.GetSafeHdc(), 0, 255, m_fontList) )
|
|
CLogFile::WriteLine( "wglUseFontBitmaps failed" );
|
|
|
|
dc.SelectObject(def_font);
|
|
// Done with the font. Delete the font object.
|
|
font.DeleteObject();
|
|
}
|
|
*/
|
|
}
|
|
|
|
// Caluclate view tranform.
|
|
CalculateViewTM();
|
|
|
|
return 0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::Update()
|
|
{
|
|
//Render();
|
|
CViewport::Update();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CPoint C2DViewport::WorldToView( Vec3 wp )
|
|
{
|
|
CPoint p;
|
|
|
|
float fScale = GetZoomFactor();
|
|
Vec3 origin = GetOrigin2D();
|
|
|
|
int ix = 0;
|
|
int iy = 0;
|
|
switch (m_axis)
|
|
{
|
|
case VPA_XY:
|
|
ix = 0; iy = 1;
|
|
break;
|
|
case VPA_XZ:
|
|
ix = 0; iy = 2;
|
|
break;
|
|
case VPA_YZ:
|
|
ix = 1; iy = 2;
|
|
break;
|
|
}
|
|
|
|
p.x = (wp[ix] - origin[ix])*fScale;
|
|
p.y = m_rcClient.Height() - (wp[iy] - origin[iy])*fScale;
|
|
|
|
return p;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
Vec3 C2DViewport::ViewToWorld( CPoint vp,bool *collideWithTerrain,bool onlyTerrain )
|
|
{
|
|
Vec3 wp(0,0,0);
|
|
|
|
float fScale = GetZoomFactor();
|
|
Vec3 origin = GetOrigin2D();
|
|
|
|
int ix = 0;
|
|
int iy = 0;
|
|
switch (m_axis)
|
|
{
|
|
case VPA_XY:
|
|
ix = 0; iy = 1;
|
|
break;
|
|
case VPA_XZ:
|
|
ix = 0; iy = 2;
|
|
break;
|
|
case VPA_YZ:
|
|
ix = 1; iy = 2;
|
|
break;
|
|
}
|
|
wp[ix] = (vp.x)/fScale + origin[ix];
|
|
wp[iy] = (m_rcClient.Height()-vp.y)/fScale + origin[iy];
|
|
return wp;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::ViewToWorldRay( CPoint vp,Vec3 &raySrc,Vec3 &rayDir )
|
|
{
|
|
raySrc = ViewToWorld( vp );
|
|
switch (m_axis)
|
|
{
|
|
case VPA_XY:
|
|
raySrc.z = MAX_WORLD_SIZE;
|
|
rayDir(0,0,-1);
|
|
break;
|
|
case VPA_XZ:
|
|
raySrc.y = MAX_WORLD_SIZE;
|
|
rayDir(0,-1,0);
|
|
break;
|
|
case VPA_YZ:
|
|
raySrc.x = MAX_WORLD_SIZE;
|
|
rayDir(-1,0,0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
float C2DViewport::GetScreenScaleFactor( const Vec3 &worldPoint )
|
|
{
|
|
return 400.0f / GetZoomFactor();
|
|
//return 100.0f / ;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::OnTitleMenu( CMenu &menu )
|
|
{
|
|
bool labels = GetIEditor()->GetDisplaySettings()->IsDisplayLabels();
|
|
bool bGrid = GetIEditor()->GetViewManager()->GetGrid()->bEnabled;
|
|
menu.AppendMenu( MF_STRING|(labels)?MF_CHECKED:MF_UNCHECKED,1,"Labels" );
|
|
menu.AppendMenu( MF_STRING|(bGrid)?MF_CHECKED:MF_UNCHECKED,2,"Grid" );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::OnTitleMenuCommand( int id )
|
|
{
|
|
switch (id)
|
|
{
|
|
case 1:
|
|
GetIEditor()->GetDisplaySettings()->DisplayLabels( !GetIEditor()->GetDisplaySettings()->IsDisplayLabels() );
|
|
break;
|
|
case 2:
|
|
{
|
|
CGrid *grid = GetIEditor()->GetViewManager()->GetGrid();
|
|
grid->Enable( !grid->IsEnabled() );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::OnDestroy()
|
|
{
|
|
if (m_renderer)
|
|
m_renderer->DeleteContext( m_hWnd );
|
|
CViewport::OnDestroy();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::Render()
|
|
{
|
|
if (GetIEditor()->IsInGameMode())
|
|
return;
|
|
|
|
if (!m_renderer)
|
|
return;
|
|
|
|
if (!IsWindowVisible())
|
|
return;
|
|
|
|
if (!GetIEditor()->GetDocument()->IsDocumentReady())
|
|
return;
|
|
|
|
FUNCTION_PROFILER( GetIEditor()->GetSystem(),PROFILE_EDITOR );
|
|
|
|
CRect rc;
|
|
GetClientRect( rc );
|
|
|
|
CalculateViewTM();
|
|
|
|
// Render
|
|
m_renderer->SetCurrentContext( m_hWnd );
|
|
m_renderer->BeginFrame();
|
|
m_renderer->ChangeViewport(0,0,rc.right,rc.bottom);
|
|
m_renderer->SetPolygonMode( R_SOLID_MODE );
|
|
m_renderer->ClearColorBuffer( Rgb2Vec(m_colorBackground) );
|
|
m_renderer->Set2DMode( true,m_rcClient.right,m_rcClient.bottom );
|
|
|
|
/*
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
glOrtho(0.0, m_rcClient.right, 0,m_rcClient.bottom, -9999.0, 9999.0);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
*/
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Draw viewport elements here.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Calc world bounding box for objects rendering.
|
|
m_displayBounds = GetWorldBounds( CPoint(0,0),CPoint(m_rcClient.Width(),m_rcClient.Height()) );
|
|
|
|
// Draw all objects.
|
|
DisplayContext dc;
|
|
dc.settings = GetIEditor()->GetDisplaySettings();
|
|
dc.view = this;
|
|
dc.renderer = m_renderer;
|
|
dc.engine = GetIEditor()->Get3DEngine();
|
|
dc.flags = DISPLAY_2D;
|
|
dc.box = m_displayBounds;
|
|
dc.camera = &GetIEditor()->GetSystem()->GetViewCamera();
|
|
|
|
if (!dc.settings->IsDisplayLabels())
|
|
{
|
|
dc.flags |= DISPLAY_HIDENAMES;
|
|
}
|
|
if (dc.settings->IsDisplayLinks())
|
|
{
|
|
dc.flags |= DISPLAY_LINKS;
|
|
}
|
|
if (m_bDegradateQuality)
|
|
{
|
|
dc.flags |= DISPLAY_DEGRADATED;
|
|
}
|
|
|
|
m_renderer->EF_StartEf();
|
|
|
|
//m_renderer->EnableDepthTest(false);
|
|
//m_renderer->EnableDepthWrites(false);
|
|
m_renderer->SetState(GS_NODEPTHTEST);
|
|
Draw( dc );
|
|
//m_renderer->EnableDepthTest(true);
|
|
//m_renderer->EnableDepthWrites(true);
|
|
m_renderer->EF_EndEf3D(SHDF_SORT);
|
|
|
|
m_renderer->FlushTextMessages();
|
|
m_renderer->Update();
|
|
|
|
// Return back from 2D mode.
|
|
m_renderer->Set2DMode( false,m_rcClient.right,m_rcClient.bottom );
|
|
|
|
|
|
GetIEditor()->GetRenderer()->MakeCurrent();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::Draw( DisplayContext &dc )
|
|
{
|
|
DrawGrid(dc);
|
|
DrawObjects(dc);
|
|
DrawSelection(dc);
|
|
DrawViewerMarker(dc);
|
|
DrawAxis(dc);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::DrawGrid( DisplayContext &dc,bool bNoXNumbers )
|
|
{
|
|
CGrid *pGrid = GetIEditor()->GetViewManager()->GetGrid();
|
|
float gridSize = pGrid->size;
|
|
|
|
if (gridSize < 0.00001)
|
|
return;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool bShowGrid = pGrid->IsEnabled();
|
|
|
|
///if (!bShowGrid)
|
|
//return;
|
|
|
|
float fScale = GetZoomFactor();
|
|
|
|
int width = m_rcClient.Width();
|
|
int height = m_rcClient.Height();
|
|
|
|
float origin[2];
|
|
GetScrollOffset( origin[0],origin[1] );
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Draw major blocks
|
|
|
|
Matrix44 tm;
|
|
tm.SetIdentity();
|
|
dc.PushMatrix( tm );
|
|
|
|
//Matrix tm = GetViewTM();
|
|
//glMultMatrixf( (float*)(&tm) );
|
|
|
|
int gx,gy;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Draw Minor grid lines.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
int firstGridLineX = origin[0] / gridSize - 1;
|
|
int firstGridLineY = origin[1] / gridSize - 1;
|
|
|
|
int numGridLinesX = (m_rcClient.Width()/fScale) / gridSize + 1;
|
|
int numGridLinesY = (m_rcClient.Height()/fScale) / gridSize + 1;
|
|
|
|
float pixelsPerGrid = gridSize*fScale;
|
|
|
|
if (pixelsPerGrid > 4)
|
|
{
|
|
dc.SetColor( MINOR_GRID_COLOR,m_gridAlpha );
|
|
|
|
// Draw horizontal grid lines.
|
|
for (gy = firstGridLineY; gy < firstGridLineY+numGridLinesY+1; gy++)
|
|
{
|
|
float y = height - (gy*gridSize - origin[1])*fScale;
|
|
m_renderer->DrawLine( Vec3(0,y,0),Vec3(width,y,0) );
|
|
}
|
|
// Draw vertical grid lines.
|
|
for (gx = firstGridLineX; gx < firstGridLineX+numGridLinesX+1; gx++)
|
|
{
|
|
float x = (gx*gridSize - origin[0])*fScale;
|
|
m_renderer->DrawLine( Vec3(x,0,0),Vec3(x,height,0) );
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Draw Major grid lines.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
gridSize = gridSize * pGrid->majorLine;
|
|
|
|
int iters = 0;
|
|
pixelsPerGrid = gridSize*fScale;
|
|
while (pixelsPerGrid < 20 && iters < 20)
|
|
{
|
|
gridSize = gridSize*2;
|
|
pixelsPerGrid = gridSize*fScale;
|
|
iters++;
|
|
}
|
|
if (pixelsPerGrid < 20)
|
|
return;
|
|
|
|
dc.SetColor( MAJOR_GRID_COLOR,m_gridAlpha );
|
|
|
|
// Draw major grid lines.
|
|
firstGridLineX = origin[0] / gridSize;
|
|
firstGridLineY = origin[1] / gridSize;
|
|
firstGridLineX--;
|
|
firstGridLineX--;
|
|
|
|
numGridLinesX = 2 + (m_rcClient.Width()/fScale) / gridSize;
|
|
numGridLinesY = 2 + (m_rcClient.Height()/fScale) / gridSize;
|
|
numGridLinesX += 2;
|
|
numGridLinesX += 2;
|
|
|
|
// Draw horizontal grid lines.
|
|
for (gy = firstGridLineY; gy < firstGridLineY+numGridLinesY; gy++)
|
|
{
|
|
float y = height - (gy*gridSize - origin[1])*fScale;
|
|
if (gy != 0)
|
|
{
|
|
m_renderer->DrawLine( Vec3(0,y,0),Vec3(width,y,0) );
|
|
}
|
|
else
|
|
{
|
|
dc.SetColor( AXIS_GRID_COLOR );
|
|
m_renderer->DrawLine( Vec3(0,y,0),Vec3(width,y,0) );
|
|
dc.SetColor( MAJOR_GRID_COLOR,m_gridAlpha );
|
|
}
|
|
}
|
|
// Draw vertical grid lines.
|
|
for (gx = firstGridLineX; gx < firstGridLineX+numGridLinesX; gx++)
|
|
{
|
|
float x = (gx*gridSize - origin[0])*fScale;
|
|
if (gx != 0)
|
|
m_renderer->DrawLine( Vec3(x,0,0),Vec3(x,height,0) );
|
|
else
|
|
{
|
|
dc.SetColor( AXIS_GRID_COLOR );
|
|
m_renderer->DrawLine( Vec3(x,0,0),Vec3(x,height,0) );
|
|
dc.SetColor( MAJOR_GRID_COLOR,m_gridAlpha );
|
|
}
|
|
}
|
|
|
|
// Draw numbers.
|
|
{
|
|
char text[64];
|
|
dc.SetColor( m_colorGridText );
|
|
|
|
if (!bNoXNumbers)
|
|
{
|
|
// Draw horizontal grid text.
|
|
for (gx = firstGridLineX; gx < firstGridLineX+numGridLinesX; gx++)
|
|
{
|
|
sprintf( text, "%i",(int)(gx*gridSize) );
|
|
float x = (gx*gridSize - origin[0])*fScale;
|
|
dc.Draw2dTextLabel( x,10,1,text );
|
|
}
|
|
}
|
|
// Draw vertical grid text.
|
|
for (gy = firstGridLineY; gy < firstGridLineY+numGridLinesY; gy++)
|
|
{
|
|
sprintf( text, "%i",(int)(gy*gridSize) );
|
|
float y = (gy*gridSize - origin[1])*fScale;
|
|
dc.Draw2dTextLabel( 2,height-y,1,text );
|
|
}
|
|
}
|
|
|
|
dc.PopMatrix();
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::DrawAxis( DisplayContext &dc )
|
|
{
|
|
int ix = 0;
|
|
int iy = 0;
|
|
float cl = 0.85f;
|
|
char xstr[2],ystr[2],zstr[2];
|
|
Vec3 colx,coly,colz;
|
|
Vec3 colorX(cl,0,0);
|
|
Vec3 colorY(0,cl,0);
|
|
Vec3 colorZ(0,0,cl);
|
|
switch (m_axis)
|
|
{
|
|
case VPA_XY:
|
|
strcpy( xstr,"x" );
|
|
strcpy( ystr,"y" );
|
|
strcpy( zstr,"z" );
|
|
colx = colorX;
|
|
coly = colorY;
|
|
colz = colorZ;
|
|
break;
|
|
case VPA_XZ:
|
|
strcpy( xstr,"x" );
|
|
strcpy( ystr,"z" );
|
|
strcpy( zstr,"y" );
|
|
colx = colorX;
|
|
coly = colorZ;
|
|
colz = colorY;
|
|
break;
|
|
case VPA_YZ:
|
|
strcpy( xstr,"y" );
|
|
strcpy( ystr,"z" );
|
|
strcpy( zstr,"x" );
|
|
colx = colorY;
|
|
coly = colorZ;
|
|
colz = colorX;
|
|
break;
|
|
}
|
|
|
|
int width = m_rcClient.Width();
|
|
int height = m_rcClient.Height();
|
|
|
|
int size = 25;
|
|
Vec3 pos( 30,height-15,0 );
|
|
|
|
m_renderer->SetMaterialColor( colx.x,colx.y,colx.z,1 );
|
|
m_renderer->DrawLine( pos,pos + Vec3(size,0,0) );
|
|
|
|
|
|
m_renderer->SetMaterialColor( coly.x,coly.y,coly.z,1 );
|
|
m_renderer->DrawLine( pos,pos - Vec3(0,size,0) );
|
|
|
|
|
|
//m_renderer->SetMaterialColor( 0,0,1,1 );
|
|
//m_renderer->DrawLine( pos,pos + Vec3(0,0,20) );
|
|
//gl.PrintText( pos.x+size,pos.y,"x" );
|
|
|
|
dc.SetColor( m_colorAxisText );
|
|
pos.x -= 3;
|
|
pos.y -= 4;
|
|
dc.Draw2dTextLabel( pos.x+size+4,pos.y-2,1,xstr );
|
|
dc.Draw2dTextLabel( pos.x+3,pos.y-size,1,ystr );
|
|
dc.Draw2dTextLabel( pos.x-5,pos.y+5,1,zstr );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::DrawSelection( DisplayContext &dc )
|
|
{
|
|
BBox box;
|
|
GetIEditor()->GetSelectedRegion( box );
|
|
if (!IsEquivalent(box.min,box.max,0))
|
|
{
|
|
//m_renderer->SetMaterialColor( SELECTION_RECT_COLOR.x,SELECTION_RECT_COLOR.y,SELECTION_RECT_COLOR.z,1 ); // white
|
|
//m_renderer->DrawWireB
|
|
/*
|
|
CRect rc;
|
|
CPoint p1 = WorldToView( box.min );
|
|
CPoint p2 = WorldToView( box.max );
|
|
rc.SetRect( p1,p2 );
|
|
rc.NormalizeRect();
|
|
// Draw selection.
|
|
if (rc.left != rc.right || rc.top != rc.bottom)
|
|
{
|
|
// Draw select rectangle.
|
|
m_renderer->SetMaterialColor( SELECTION_RECT_COLOR.x,SELECTION_RECT_COLOR.y,SELECTION_RECT_COLOR.z,1 ); // white
|
|
m_renderer->DrawLine( Vec3(rc.left,rc.top,0),Vec3(rc.right,rc.top,0) );
|
|
m_renderer->DrawLine( Vec3(rc.right,rc.top,0),Vec3(rc.right,rc.bottom,0) );
|
|
m_renderer->DrawLine( Vec3(rc.right,rc.bottom,0),Vec3(rc.left,rc.bottom,0) );
|
|
m_renderer->DrawLine( Vec3(rc.left,rc.bottom,0),Vec3(rc.left,rc.top,0) );
|
|
}
|
|
*/
|
|
}
|
|
|
|
if (!IsEquivalent(box.min,box.max,0))
|
|
{
|
|
switch (m_axis)
|
|
{
|
|
case VPA_XY:
|
|
box.min.z = box.max.z = 0;
|
|
break;
|
|
case VPA_XZ:
|
|
box.min.y = box.max.y = 0;
|
|
break;
|
|
case VPA_YZ:
|
|
box.min.x = box.max.x = 0;
|
|
break;
|
|
}
|
|
|
|
dc.PushMatrix( GetScreenTM() );
|
|
dc.SetColor( SELECTION_RECT_COLOR.x,SELECTION_RECT_COLOR.y,SELECTION_RECT_COLOR.z,1 );
|
|
dc.DrawWireBox( box.min,box.max );
|
|
dc.PopMatrix();
|
|
}
|
|
|
|
if (!m_selectedRect.IsRectEmpty())
|
|
{
|
|
dc.SetColor( SELECTION_RECT_COLOR.x,SELECTION_RECT_COLOR.y,SELECTION_RECT_COLOR.z,1 );
|
|
CPoint p1 = CPoint( m_selectedRect.left,m_selectedRect.top );
|
|
CPoint p2 = CPoint( m_selectedRect.right,m_selectedRect.bottom );
|
|
dc.DrawLine( Vec3(p1.x,p1.y,0),Vec3(p2.x,p1.y,0) );
|
|
dc.DrawLine( Vec3(p1.x,p2.y,0),Vec3(p2.x,p2.y,0) );
|
|
dc.DrawLine( Vec3(p1.x,p1.y,0),Vec3(p1.x,p2.y,0) );
|
|
dc.DrawLine( Vec3(p2.x,p1.y,0),Vec3(p2.x,p2.y,0) );
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
Vec3 C2DViewport::SnapToGrid( Vec3 vec )
|
|
{
|
|
CGrid *pGrid = GetIEditor()->GetViewManager()->GetGrid();
|
|
return pGrid->Snap( vec );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::DrawViewerMarker( DisplayContext &dc )
|
|
{
|
|
float noScale = 1.0f/GetZoomFactor();
|
|
|
|
Vec3 viewAngles = GetIEditor()->GetViewerAngles();
|
|
|
|
Matrix44 tm;
|
|
switch (m_axis)
|
|
{
|
|
case VPA_XY:
|
|
tm = Matrix44::CreateRotationZYX(-DEG2RAD(Vec3(0,0,viewAngles.z)));
|
|
break;
|
|
case VPA_XZ:
|
|
tm = Matrix44::CreateRotationZYX(-DEG2RAD(Vec3(0,viewAngles.y,0)));
|
|
break;
|
|
case VPA_YZ:
|
|
tm = Matrix44::CreateRotationZYX(-DEG2RAD(Vec3(viewAngles.x,0,0)));
|
|
break;
|
|
}
|
|
tm.SetTranslationOLD( GetIEditor()->GetViewerPos() );
|
|
|
|
dc.PushMatrix( tm*GetScreenTM() );
|
|
|
|
Vec3 dim(MARKER_SIZE,MARKER_SIZE/2,MARKER_SIZE);
|
|
dc.SetColor( RGB(0,0,255) ); // red
|
|
dc.DrawWireBox( -dim*noScale,dim*noScale );
|
|
|
|
float fov = GetIEditor()->GetSystem()->GetViewCamera().GetFov();
|
|
|
|
Vec3 q[4];
|
|
float dist = 30;
|
|
float ta = (float)tan(0.5f*fov);
|
|
float w = dist * ta;
|
|
float h = w * gSettings.viewports.fDefaultAspectRatio; // ASPECT ??
|
|
//float h = w / GetAspect();
|
|
q[0] = Vec3( w,-dist, h) * noScale;
|
|
q[1] = Vec3(-w,-dist, h) * noScale;
|
|
q[2] = Vec3(-w,-dist,-h) * noScale;
|
|
q[3] = Vec3( w,-dist,-h) * noScale;
|
|
|
|
// Draw frustum.
|
|
dc.DrawLine( Vec3(0,0,0),q[0] );
|
|
dc.DrawLine( Vec3(0,0,0),q[1] );
|
|
dc.DrawLine( Vec3(0,0,0),q[2] );
|
|
dc.DrawLine( Vec3(0,0,0),q[3] );
|
|
|
|
// Draw quad.
|
|
dc.DrawPolyLine( q,4 );
|
|
|
|
dc.PopMatrix();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::DrawObjects( DisplayContext &dc )
|
|
{
|
|
dc.renderer->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA);
|
|
//dc.renderer->SetBlendMode();
|
|
//dc.renderer->EnableBlend(true);
|
|
dc.PushMatrix( GetScreenTM() );
|
|
GetIEditor()->GetObjectManager()->Display( dc );
|
|
|
|
// Display editing tool.
|
|
if (GetIEditor()->GetEditTool())
|
|
{
|
|
GetIEditor()->GetEditTool()->Display( dc );
|
|
}
|
|
dc.PopMatrix();
|
|
dc.renderer->SetState(GS_DEPTHWRITE);
|
|
//dc.renderer->EnableBlend(false);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::DrawBrush( DisplayContext &dc,struct SBrush *brush,const Matrix44 &brushTM,int flags )
|
|
{
|
|
float fScale = GetZoomFactor();
|
|
|
|
//Matrix tm = brushTM * GetViewTM();
|
|
//glMultMatrixf( (float*)(&tm) );
|
|
dc.PushMatrix( brushTM );
|
|
|
|
// if selected.
|
|
bool bSelected = flags == 1;
|
|
|
|
if (bSelected)
|
|
{
|
|
dc.SetLineWidth(2);
|
|
//glEnable(GL_LINE_STIPPLE);
|
|
//glLineStipple( 10,0xAAAA );
|
|
}
|
|
|
|
int i, j;
|
|
for (i = 0; i < brush->m_Faces.size(); i++)
|
|
{
|
|
SBrushFace *f = brush->m_Faces[i];
|
|
|
|
// if (f->m_Plane.normal[0] <= 0)
|
|
//if (f->m_Plane.normal[m_cullAxis] <= 0)
|
|
//continue;
|
|
|
|
//CHANGED_BY_IVO
|
|
//Vec3 norm = brushTM.TransformVector( f->m_Plane.normal );
|
|
Vec3 norm = GetTransposed44(brushTM) * ( f->m_Plane.normal );
|
|
|
|
if (norm[m_cullAxis] <= 0)
|
|
continue;
|
|
|
|
SBrushPoly *poly = f->m_Poly;
|
|
if (!poly)
|
|
continue;
|
|
|
|
int numv = poly->m_Pts.size();
|
|
//glBegin(GL_LINE_LOOP);
|
|
for (j=0; j < numv; j++)
|
|
{
|
|
int k = ((j+1) < numv) ? j+1 : 0;
|
|
SBrushVert &vert = poly->m_Pts[j];
|
|
SBrushVert &vert1 = poly->m_Pts[k];
|
|
dc.DrawLine( vert.xyz,vert1.xyz );
|
|
//glVertex3fv( &vert.xyz[0] );
|
|
//glVertex3fv(&poly->m_Pts[j].xyz[0]);
|
|
}
|
|
//glEnd();
|
|
}
|
|
|
|
brush->m_bounds;
|
|
|
|
if (bSelected)
|
|
{
|
|
//glDisable(GL_LINE_STIPPLE);
|
|
dc.SetLineWidth(1);
|
|
}
|
|
|
|
dc.PopMatrix();
|
|
|
|
if (bSelected)
|
|
{
|
|
int ix = 0;
|
|
int iy = 0;
|
|
switch (m_axis)
|
|
{
|
|
case VPA_XY:
|
|
ix = 0; iy = 1;
|
|
break;
|
|
case VPA_XZ:
|
|
ix = 0; iy = 2;
|
|
break;
|
|
case VPA_YZ:
|
|
ix = 1; iy = 2;
|
|
break;
|
|
}
|
|
Vec3 p1(brush->m_bounds.min[ix],brush->m_bounds.min[iy],0);
|
|
Vec3 p2(brush->m_bounds.max[ix],brush->m_bounds.max[iy],0);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::DrawTextLabel( DisplayContext &dc,const Vec3& pos,float size,const CFColor& color,const char *text )
|
|
{
|
|
float fCol[4] = { color.r,color.g,color.b,color.a };
|
|
Vec3 p = GetScreenTM().TransformPointOLD( pos );
|
|
m_renderer->Draw2dLabel( p.x,p.y,size,fCol,false,"%s",text);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::SetConstrPlane( CPoint cursor,const Matrix44 &xform )
|
|
{
|
|
m_constructionOriginalMatrix = xform;
|
|
m_constructionMatrix = xform;
|
|
// Remove scale component.
|
|
m_constructionMatrix.NoScale();
|
|
Vec3 pos = m_constructionMatrix.GetTranslationOLD();
|
|
// Remove position component.
|
|
m_constructionMatrix.SetTranslationOLD( Vec3(0,0,0) );
|
|
|
|
switch (m_axis)
|
|
{
|
|
case VPA_XY:
|
|
m_constructionPlane.Init( pos,pos+Vec3(1,0,0),pos+Vec3(0,1,0) );
|
|
break;
|
|
case VPA_XZ:
|
|
m_constructionPlane.Init( pos,pos+Vec3(1,0,0),pos+Vec3(0,0,1) );
|
|
break;
|
|
case VPA_YZ:
|
|
m_constructionPlane.Init( pos,pos+Vec3(0,1,0),pos+Vec3(0,0,1) );
|
|
break;
|
|
}
|
|
}
|
|
|
|
Vec3 C2DViewport::GetCPVector( const Vec3 &p1,const Vec3 &p2 )
|
|
{
|
|
return CViewport::GetCPVector(p1,p2);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
BBox C2DViewport::GetWorldBounds( CPoint pnt1,CPoint pnt2 )
|
|
{
|
|
Vec3 org;
|
|
BBox box;
|
|
box.Reset();
|
|
box.Add( ViewToWorld( pnt1 ) );
|
|
box.Add( ViewToWorld( pnt2 ) );
|
|
|
|
int maxSize = MAX_WORLD_SIZE;
|
|
switch (m_axis)
|
|
{
|
|
case VPA_XY:
|
|
box.min.z = -maxSize;
|
|
box.max.z = maxSize;
|
|
break;
|
|
case VPA_XZ:
|
|
box.min.y = -maxSize;
|
|
box.max.y = maxSize;
|
|
break;
|
|
case VPA_YZ:
|
|
box.min.x = -maxSize;
|
|
box.max.x = maxSize;
|
|
break;
|
|
}
|
|
return box;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::OnDragSelectRectangle( CPoint pnt1,CPoint pnt2,bool bNormilizeRect )
|
|
{
|
|
Vec3 org;
|
|
BBox box;
|
|
box.Reset();
|
|
|
|
Vec3 p1 = ViewToWorld( pnt1 );
|
|
Vec3 p2 = ViewToWorld( pnt2 );
|
|
org = p1;
|
|
|
|
// Calculate selection volume.
|
|
box.Add( p1 );
|
|
box.Add( p2 );
|
|
|
|
int maxSize = MAX_WORLD_SIZE;
|
|
|
|
char szNewStatusText[512];
|
|
float w,h;
|
|
|
|
switch (m_axis)
|
|
{
|
|
case VPA_XY:
|
|
box.min.z = -maxSize;
|
|
box.max.z = maxSize;
|
|
|
|
w = box.max.x - box.min.x;
|
|
h = box.max.y - box.min.y;
|
|
sprintf(szNewStatusText, "X:%g Y:%g W:%g H:%g",org.x,org.y,w,h );
|
|
break;
|
|
case VPA_XZ:
|
|
box.min.y = -maxSize;
|
|
box.max.y = maxSize;
|
|
|
|
w = box.max.x - box.min.x;
|
|
h = box.max.z - box.min.z;
|
|
sprintf(szNewStatusText, "X:%g Z:%g W:%g H:%g",org.x,org.z,w,h );
|
|
break;
|
|
case VPA_YZ:
|
|
box.min.x = -maxSize;
|
|
box.max.x = maxSize;
|
|
|
|
w = box.max.y - box.min.y;
|
|
h = box.max.z - box.min.z;
|
|
sprintf(szNewStatusText, "Y:%g Z:%g W:%g H:%g",org.y,org.z,w,h );
|
|
break;
|
|
}
|
|
|
|
GetIEditor()->SetSelectedRegion( box );
|
|
|
|
// Show marker position in the status bar
|
|
GetIEditor()->SetStatusText(szNewStatusText);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool C2DViewport::HitTest( CPoint point,ObjectHitInfo &hitInfo,int flags )
|
|
{
|
|
hitInfo.bounds = m_displayBounds;
|
|
return CViewport::HitTest( point,hitInfo,flags );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool C2DViewport::IsBoundsVisible( const BBox &box ) const
|
|
{
|
|
// If at least part of bbox is visible then its visible.
|
|
if (m_displayBounds.IsIntersectBox( box ))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::CenterOnSelection()
|
|
{
|
|
CSelectionGroup *sel = GetIEditor()->GetSelection();
|
|
if (sel->IsEmpty())
|
|
return;
|
|
|
|
//SetZoomFactor(1);
|
|
|
|
BBox bounds = sel->GetBounds();
|
|
Vec3 selPos = sel->GetCenter();
|
|
|
|
float size = GetLength(bounds.max - bounds.min);
|
|
|
|
//CPoint p1 = WorldToView(bounds.min);
|
|
//CPoint p2 = WorldToView(bounds.max);
|
|
|
|
Vec3 v1 = ViewToWorld( CPoint(m_rcClient.left,m_rcClient.bottom) );
|
|
Vec3 v2 = ViewToWorld( CPoint(m_rcClient.right,m_rcClient.top) );
|
|
Vec3 vofs = (v2-v1) * 0.5f;
|
|
selPos -= vofs;
|
|
SetOrigin2D( selPos );
|
|
|
|
Invalidate(FALSE);
|
|
|
|
//SetZoomFactor( size / 10 );
|
|
|
|
/*
|
|
CSelectionGroup *sel = GetIEditor()->GetSelection();
|
|
BBox bounds = sel->GetBounds();
|
|
Vec3 selPos = sel->GetCenter();
|
|
float size = GetLength(bounds.max - bounds.min);
|
|
Vec3 pos = selPos;
|
|
pos += Vec3(0,size*2,size);
|
|
//pos.z = GetIEditor()->GetTerrainElevation(pos.x,pos.y)+5;
|
|
GetIEditor()->SetViewerPos( pos );
|
|
Vec3 dir = GetNormalized(selPos - pos);
|
|
dir = ConvertVectorToCameraAngles(dir);
|
|
GetIEditor()->SetViewerAngles( dir );
|
|
*/
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
Vec3 C2DViewport::GetOrigin2D() const
|
|
{
|
|
if (gSettings.viewports.bSync2DViews)
|
|
return GetViewManager()->GetOrigin2D();
|
|
else
|
|
return m_origin2D;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void C2DViewport::SetOrigin2D( const Vec3 &org )
|
|
{
|
|
m_origin2D = org;
|
|
if (gSettings.viewports.bSync2DViews)
|
|
GetViewManager()->SetOrigin2D( m_origin2D );
|
|
}
|