696 lines
18 KiB
C++
696 lines
18 KiB
C++
// TerrainViewport.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "TerrainViewport.h"
|
|
#include "CryEditDoc.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTerrainViewport
|
|
|
|
// Used to give each static object type a different color
|
|
static DWORD StatObjColorArray[] =
|
|
{
|
|
0x00FF0000,
|
|
0x0000FF00,
|
|
0x000000FF,
|
|
0x00FFFFFF,
|
|
0x00FF00FF,
|
|
0x00FFFF00,
|
|
0x0000FFFF,
|
|
0x007F00FF,
|
|
0x007FFF7F,
|
|
0x00FF7F00,
|
|
0x0000FF7F,
|
|
0x007F7F7F,
|
|
0x00000000
|
|
};
|
|
|
|
CTerrainViewport::CTerrainViewport()
|
|
{
|
|
m_heightmapSize.cx = GetDocument()->m_cHeightmap.GetWidth();
|
|
m_heightmapSize.cy = GetDocument()->m_cHeightmap.GetHeight();
|
|
|
|
VERIFY(m_dcView.CreateCompatibleDC(NULL));
|
|
|
|
// Create a DC and a bitmap
|
|
VERIFY(m_dcTerrain.CreateCompatibleDC(NULL));
|
|
VERIFY(m_bmpTerrain.CreateBitmap(m_heightmapSize.cx,m_heightmapSize.cy, 1, 32, NULL));
|
|
m_dcTerrain.SelectObject(&m_bmpTerrain);
|
|
|
|
m_iBrushSize = 50;
|
|
}
|
|
|
|
CTerrainViewport::~CTerrainViewport()
|
|
{
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CTerrainViewport, CViewport)
|
|
//{{AFX_MSG_MAP(CTerrainViewport)
|
|
ON_WM_PAINT()
|
|
ON_WM_MOUSEWHEEL()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_ERASEBKGND()
|
|
ON_WM_SIZE()
|
|
ON_WM_RBUTTONDOWN()
|
|
ON_WM_RBUTTONUP()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_LBUTTONUP()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTerrainViewport message handlers
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CPoint CTerrainViewport::WorldToView( Vec3d wp )
|
|
{
|
|
CPoint p;
|
|
float x = wp.x / 2.0f;
|
|
float y = wp.y / 2.0f;
|
|
|
|
float lTemp;
|
|
|
|
// Swap the axis
|
|
lTemp = x;
|
|
x = y;
|
|
y = lTemp;
|
|
|
|
x = (x * GetZoomFactor());
|
|
y = (y * GetZoomFactor());
|
|
|
|
// Add the offset
|
|
x += GetScrollOffset().x;
|
|
y += GetScrollOffset().y;
|
|
p.x = (int)x;
|
|
p.y = (int)y;
|
|
|
|
return p;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
Vec3d CTerrainViewport::ViewToWorld( CPoint vp,bool *collideWithTerrain,bool onlyTerrain )
|
|
{
|
|
vp.x += abs(GetScrollOffset().x);
|
|
vp.y += abs(GetScrollOffset().y);
|
|
|
|
// Swap the axis
|
|
int lTemp = vp.x;
|
|
vp.x = vp.y;
|
|
vp.y = lTemp;
|
|
|
|
// Scale with the zoom factor
|
|
float x = (float)vp.x / GetZoomFactor();
|
|
float y = (float)vp.y / GetZoomFactor();
|
|
|
|
Vec3d wp;
|
|
wp.x = x * 2.0f;
|
|
wp.y = y * 2.0f;
|
|
wp.z = GetIEditor()->GetTerrainElevation(wp.x,wp.y);
|
|
|
|
if (collideWithTerrain)
|
|
*collideWithTerrain = true;
|
|
|
|
/*
|
|
CEngineSingleton::GetGameInterface()->GetInterface()->
|
|
MovePlayer(point.x * 2.0f, point.y * 2.0f, CEngineSingleton::
|
|
GetGameInterface()->GetInterface()->GetTerrainElevation(point.x * 2.0f, point.y * 2.0f));
|
|
*/
|
|
|
|
return wp;
|
|
}
|
|
|
|
void CTerrainViewport::ViewToWorldRay( CPoint vp,Vec3 &raySrc,Vec3 &rayDir )
|
|
{
|
|
raySrc = ViewToWorld( vp );
|
|
raySrc.z = 1000;
|
|
rayDir(0,0,-1);
|
|
}
|
|
|
|
bool CTerrainViewport::SetScrollOffset(long iX, long iY)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Set the scrolling offset. If the passed values are invalid, the
|
|
// nearest valid values will be set and false is returned
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
bool bRangeValid = true;
|
|
RECT rcWndPos;
|
|
long iScaledTexWidth = (long) (m_heightmapSize.cx * GetZoomFactor());
|
|
|
|
// Obtain the size of the window
|
|
GetClientRect(&rcWndPos);
|
|
|
|
// Don't allow to scroll beyond the lower right corner
|
|
if (abs(iX) > iScaledTexWidth - rcWndPos.right)
|
|
{
|
|
iX = -(iScaledTexWidth - rcWndPos.right);
|
|
bRangeValid = false;
|
|
}
|
|
|
|
if (abs(iY) > iScaledTexWidth - rcWndPos.bottom)
|
|
{
|
|
iY = -(iScaledTexWidth - rcWndPos.bottom);
|
|
bRangeValid = false;
|
|
}
|
|
|
|
// Don't allow to scroll beyond the upper left corner
|
|
if (iX > 0)
|
|
{
|
|
iX = 0;
|
|
bRangeValid = false;
|
|
}
|
|
|
|
if (iY > 0)
|
|
{
|
|
iY = 0;
|
|
bRangeValid = false;
|
|
}
|
|
|
|
// Save the (eventually corrected) scroll offset
|
|
m_cScrollOffset = CPoint(iX, iY);
|
|
|
|
RedrawWindow();
|
|
|
|
return bRangeValid;
|
|
}
|
|
|
|
|
|
void CTerrainViewport::ResetContent()
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Create a surface texture that consists entirely of water
|
|
////////////////////////////////////////////////////////////////////////
|
|
DWORD *pWaterTexData = NULL;
|
|
DWORD *pSurfaceTextureData = NULL;
|
|
DWORD *pPixData = NULL, *pPixDataEnd = NULL;
|
|
CBitmap bmpLoad;
|
|
bool bReturn;
|
|
|
|
// Load the water texture out of the ressource
|
|
bReturn = bmpLoad.LoadBitmap(MAKEINTRESOURCE(IDB_WATER));
|
|
ASSERT(bReturn);
|
|
|
|
// Allocate new memory to hold the bitmap data
|
|
pWaterTexData = new DWORD[128 * 128];
|
|
ASSERT(pWaterTexData);
|
|
|
|
// Retrieve the bits from the bitmap
|
|
VERIFY(bmpLoad.GetBitmapBits(128 * 128 * sizeof(DWORD), pWaterTexData));
|
|
|
|
|
|
// Allocate memory for the surface texture
|
|
pSurfaceTextureData = new DWORD[m_heightmapSize.cx*m_heightmapSize.cy];
|
|
ASSERT(pSurfaceTextureData);
|
|
|
|
|
|
// Fill the surface texture with the water texture, tile as needed
|
|
for (int j=0; j<m_heightmapSize.cy; j++)
|
|
for (int i=0; i<m_heightmapSize.cx; i++)
|
|
{
|
|
pSurfaceTextureData[i + j * m_heightmapSize.cx] =
|
|
pWaterTexData[(i % 128) + (j % 128) * 128];
|
|
}
|
|
|
|
|
|
// Set the loop pointers
|
|
pPixData = pSurfaceTextureData;
|
|
pPixDataEnd = &pSurfaceTextureData[m_heightmapSize.cx*m_heightmapSize.cy];
|
|
|
|
/*
|
|
// Switch R and B
|
|
while (pPixData != pPixDataEnd)
|
|
{
|
|
// Extract the bits, shift them, put them back and advance to the next pixel
|
|
*pPixData++ = ((* pPixData & 0x00FF0000) >> 16) |
|
|
(* pPixData & 0x0000FF00) | ((* pPixData & 0x000000FF) << 16);
|
|
}
|
|
*/
|
|
|
|
// Load it into the bitmap
|
|
m_bmpTerrain.SetBitmapBits(m_heightmapSize.cx*m_heightmapSize.cy*4, pSurfaceTextureData);
|
|
|
|
if (::IsWindow(m_hWnd))
|
|
RedrawWindow();
|
|
|
|
// Free surface mem
|
|
delete [] pSurfaceTextureData;
|
|
pSurfaceTextureData = 0;
|
|
|
|
// Free the water texture data
|
|
delete [] pWaterTexData;
|
|
pWaterTexData = 0;
|
|
}
|
|
|
|
void CTerrainViewport::UpdateContent( int flags )
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Generate a new surface texture
|
|
////////////////////////////////////////////////////////////////////////
|
|
DWORD *pSurfaceData = NULL;
|
|
bool bReturn;
|
|
|
|
// Allocate memory
|
|
pSurfaceData = new DWORD[m_heightmapSize.cx*m_heightmapSize.cy];
|
|
ASSERT(pSurfaceData);
|
|
|
|
bReturn = GetDocument()->GetHeightmap().GetPreviewBitmap( (DWORD*)pSurfaceData,m_heightmapSize.cx,false,false );
|
|
/*
|
|
// Fill in the surface data into the array. Apply lighting and water, use
|
|
// the settings from the document
|
|
bReturn = cSurfaceTexture.GenerateSurface(pSurfaceData, SURFACE_TEXTURE_WIDTH,
|
|
SURFACE_TEXTURE_WIDTH, true, true, GLOBAL_GET_DOC->GetWaterLevel(), true);
|
|
*/
|
|
|
|
if (bReturn)
|
|
{
|
|
m_bmpTerrain.SetBitmapBits( m_heightmapSize.cx*m_heightmapSize.cy*4, pSurfaceData);
|
|
if (IsWindow(GetSafeHwnd()))
|
|
RedrawWindow();
|
|
}
|
|
|
|
// Free the surface data array
|
|
delete [] pSurfaceData;
|
|
pSurfaceData = 0;
|
|
|
|
/*
|
|
CCryEditDoc *doc = GLOBAL_GET_DOC;
|
|
if (!doc)
|
|
return;
|
|
|
|
m_heightmapSize.cx = doc->m_cHeightmap.GetWidth();
|
|
m_heightmapSize.cy = doc->m_cHeightmap.GetHeight();
|
|
m_waterLevel = doc->GetWaterLevel();
|
|
|
|
/*
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Generate a new surface texture
|
|
////////////////////////////////////////////////////////////////////////
|
|
CTerrainTexture cSurfaceTexture;
|
|
bool bReturn;
|
|
|
|
CLogFile::FormatLine("Updating top view surface data (%i x %i)...",
|
|
m_textureSize.cx, m_textureSize.cy);
|
|
|
|
// Allocate memory
|
|
if (m_textureData)
|
|
delete []m_textureData;
|
|
|
|
if (!m_bShowHeightmap)
|
|
{
|
|
m_textureSize.cx = SURFACE_TEXTURE_WIDTH;
|
|
m_textureSize.cy = SURFACE_TEXTURE_WIDTH;
|
|
|
|
m_textureData = new uint[m_textureSize.cx * m_textureSize.cy];
|
|
ASSERT(m_textureData);
|
|
|
|
// Fill in the surface data into the array. Apply lighting and water, use
|
|
// the settings from the document
|
|
bReturn = cSurfaceTexture.GenerateSurface( (unsigned long*)m_textureData,m_textureSize.cx,m_textureSize.cy,true,true,m_waterLevel,true);
|
|
}
|
|
else
|
|
{
|
|
m_textureSize.cx = 512;
|
|
m_textureSize.cy = 512;
|
|
m_textureData = new uint[m_textureSize.cx * m_textureSize.cy];
|
|
ASSERT(m_textureData);
|
|
|
|
// Show heightmap data.
|
|
//GLOBAL_GET_DOC->m_cHeightmap.GetDataEx(pHeightmap, (m_rcView.right - m_rcView.left), false, false);
|
|
GLOBAL_GET_DOC->m_cHeightmap.GetPreviewBitmap( (DWORD*)m_textureData,m_textureSize.cx,false,false );
|
|
}
|
|
m_textureValid = false;
|
|
|
|
if (bReturn)
|
|
{
|
|
if (::IsWindow(m_hWnd))
|
|
RedrawWindow();
|
|
}
|
|
|
|
if (m_bShowStatObjects)
|
|
{
|
|
int w,h;
|
|
GetIEditor()->GetDocument()->GetStatObjDistArray( w,h );
|
|
if (m_statObjTexData)
|
|
delete []m_statObjTexData;
|
|
m_statObjTexSize.cx = w;
|
|
m_statObjTexSize.cy = h;
|
|
m_statObjTexData = new uint[w*h];
|
|
memset( m_statObjTexData,0,w*h );
|
|
|
|
DrawStaticObjects();
|
|
}
|
|
*/
|
|
|
|
SetZoomFactor( GetZoomFactor() );
|
|
}
|
|
|
|
void CTerrainViewport::SetZoomFactor(float fZoomFactor)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Adjust the zoom factor of the view. If the passed values are invalid,
|
|
// the nearest valid values will be set and false is returned
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
RECT rcWndPos;
|
|
bool bRangeValid = true;
|
|
float fNewSizeTemp = 0;
|
|
float fEnlargementFactor;
|
|
|
|
// Zero can produce artifacts and errors
|
|
if (fZoomFactor == 0.0f)
|
|
{
|
|
fZoomFactor = m_fZoomFactor;
|
|
bRangeValid = false;
|
|
}
|
|
// Obtain the dimensions of the window
|
|
GetClientRect(&rcWndPos);
|
|
|
|
// Is the new zoom factor smaller than the last one ?
|
|
if (fZoomFactor < m_fZoomFactor)
|
|
{
|
|
// We might run into the problem that the map is smaller than the
|
|
// the window when displayed with the specified zoom factor
|
|
|
|
if (m_heightmapSize.cx * fZoomFactor < rcWndPos.right)
|
|
{
|
|
// Calculate the new size
|
|
fZoomFactor = (float) rcWndPos.right / m_heightmapSize.cx;
|
|
|
|
bRangeValid = false;
|
|
}
|
|
|
|
if (m_heightmapSize.cx * fZoomFactor < rcWndPos.bottom)
|
|
{
|
|
// Calculate the new size
|
|
fNewSizeTemp = (float) rcWndPos.bottom / m_heightmapSize.cx;
|
|
|
|
// Only set the new zoom if it is larger than the previous
|
|
fZoomFactor = (fZoomFactor > fNewSizeTemp) ? fZoomFactor : fNewSizeTemp;
|
|
|
|
bRangeValid = false;
|
|
}
|
|
}
|
|
|
|
// Calculate how much larger the new zoom is compared to the old one
|
|
fEnlargementFactor = fZoomFactor / m_fZoomFactor;
|
|
|
|
// Save the new zoom factor
|
|
m_fZoomFactor = fZoomFactor;
|
|
|
|
if (m_cScrollOffset.x + m_heightmapSize.cx*fZoomFactor < rcWndPos.right)
|
|
m_cScrollOffset.x = rcWndPos.right - m_heightmapSize.cx*fZoomFactor;
|
|
|
|
if (m_cScrollOffset.y + m_heightmapSize.cy*fZoomFactor < rcWndPos.bottom)
|
|
m_cScrollOffset.y = rcWndPos.bottom - m_heightmapSize.cy*fZoomFactor;
|
|
|
|
if (m_cScrollOffset.x > 0) m_cScrollOffset.x = 0;
|
|
if (m_cScrollOffset.y > 0) m_cScrollOffset.y = 0;
|
|
|
|
RedrawWindow();
|
|
}
|
|
|
|
void CTerrainViewport::OnPaint()
|
|
{
|
|
CPaintDC dc(this); // device context for painting
|
|
|
|
if (!GetDocument()) return;
|
|
|
|
int iX, iY, iWidth, iHeight;
|
|
|
|
/* OLD
|
|
// Blit the image
|
|
dc.SetStretchBltMode(HALFTONE);
|
|
dc.StretchBlt(iX, iY, iWidth, iHeight, &m_dcTerrain, 0, 0, m_heightmapSize.cx, m_heightmapSize.cy, SRCCOPY);
|
|
// Reset brush origin after strech blit.
|
|
dc.SetBrushOrg( 0,0 );
|
|
*/
|
|
|
|
// Free any old bitmap first
|
|
|
|
if (m_bmpView.GetSafeHandle())
|
|
{
|
|
//m_dcView.SelectObject(NULL);
|
|
::SelectObject(m_dcView.m_hDC, NULL);
|
|
m_bmpView.DeleteObject();
|
|
}
|
|
|
|
CRect rc( dc.m_ps.rcPaint );
|
|
|
|
// Calculate the position and dimension of the image
|
|
iX = m_cScrollOffset.x;
|
|
iY = m_cScrollOffset.y;
|
|
iWidth = (m_heightmapSize.cx * m_fZoomFactor);
|
|
iHeight = (m_heightmapSize.cy * m_fZoomFactor);
|
|
|
|
CPoint hp1 = ViewToHeightmap( CPoint(rc.left,rc.top) );
|
|
CPoint hp2 = ViewToHeightmap( CPoint(rc.right,rc.bottom) );
|
|
|
|
// Create bitmap
|
|
BITMAPINFO BmpInfo;
|
|
BmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
BmpInfo.bmiHeader.biWidth = hp2.x - hp1.x;
|
|
BmpInfo.bmiHeader.biHeight = -(hp2.y - hp1.y);
|
|
BmpInfo.bmiHeader.biPlanes = 1;
|
|
BmpInfo.bmiHeader.biBitCount = 32;
|
|
BmpInfo.bmiHeader.biCompression = BI_RGB;
|
|
BmpInfo.bmiHeader.biSizeImage = 0;
|
|
BmpInfo.bmiHeader.biXPelsPerMeter = 0;
|
|
BmpInfo.bmiHeader.biYPelsPerMeter = 0;
|
|
BmpInfo.bmiHeader.biClrUsed = 0;
|
|
BmpInfo.bmiHeader.biClrImportant = 0;
|
|
|
|
DWORD *pBits = NULL;
|
|
// Create the DIB section to draw into
|
|
HBITMAP bmpView = ::CreateDIBSection(m_dcView.m_hDC, &BmpInfo, DIB_RGB_COLORS,(void**)&pBits, NULL, 0);
|
|
ASSERT(bmpView);
|
|
m_bmpView.Attach(bmpView);
|
|
|
|
// Select the DIB into the DC
|
|
m_dcView.SelectObject( m_bmpView );
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Draw the heightmap into the final image
|
|
////////////////////////////////////////////////////////////////////////
|
|
//m_dcView.BitBlt( 0,0,m_heightmapSize.cx,m_heightmapSize.cy,&m_dcTerrain, 0, 0, SRCCOPY);
|
|
m_dcView.BitBlt( 0, 0,hp2.x-hp1.x,hp2.y-hp1.y, &m_dcTerrain, hp1.x,hp1.y, SRCCOPY);
|
|
//m_dcView.SetBrushOrg( 0,0 );
|
|
|
|
DrawStaticObjects( pBits, hp2.x-hp1.x,hp2.y-hp1.y, CRect(hp1,hp2) );
|
|
|
|
//dc.BitBlt( 0,0,rc.right,rc.bottom,&m_dcView, 0, 0, SRCCOPY);
|
|
|
|
dc.SetStretchBltMode(COLORONCOLOR);
|
|
dc.StretchBlt(iX, iY, iWidth, iHeight, &m_dcView, 0, 0, hp2.x-hp1.x,hp2.y-hp1.y, SRCCOPY);
|
|
//dc.BitBlt(0,0,rc.right,rc.bottom, &m_dcView, 0, 0, SRCCOPY);
|
|
// Reset brush origin after strech blit.
|
|
dc.SetBrushOrg( 0,0 );
|
|
|
|
/*
|
|
CPoint p;
|
|
p.x = m_viewerPos.x;
|
|
p.y = m_viewerPos.y;
|
|
HMCoordToWndCoord( &p );
|
|
dc.Ellipse( p.x-3,p.y-3,p.x+3,p.y+3 );
|
|
*/
|
|
// Do not call CViewport::OnPaint() for painting messages
|
|
}
|
|
|
|
void CTerrainViewport::DrawStaticObjects( DWORD* pBits,int trgWidth,int trgHeight,CRect rc )
|
|
{
|
|
}
|
|
|
|
BOOL CTerrainViewport::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
|
|
{
|
|
float prevz = GetZoomFactor();
|
|
|
|
float z = GetZoomFactor() + (zDelta / 120.0f) * 2.0f;
|
|
|
|
// Zoom to mouse position.
|
|
float x = (float)(m_cMousePos.x - m_cScrollOffset.x)/prevz;
|
|
float y = (float)(m_cMousePos.y - m_cScrollOffset.y)/prevz;
|
|
m_cScrollOffset.x = m_cMousePos.x - z*x;
|
|
m_cScrollOffset.y = m_cMousePos.y - z*y;
|
|
|
|
SetZoomFactor( z );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CTerrainViewport::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
m_cMousePos = point;
|
|
|
|
if (GetViewMode() == ScrollZoomMode)
|
|
{
|
|
CRect rc;
|
|
// You can only scroll while the middle or right 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_cMouseDownPos.y) * 0.1f;
|
|
float x = (float)(m_cMouseDownPos.x - m_prevScrollOffset.cx)/m_prevZoomFactor;
|
|
float y = (float)(m_cMouseDownPos.y - m_prevScrollOffset.cy)/m_prevZoomFactor;
|
|
m_cScrollOffset.x = m_cMouseDownPos.x - z*x;
|
|
m_cScrollOffset.y = m_cMouseDownPos.y - z*y;
|
|
SetZoomFactor( z );
|
|
}
|
|
else
|
|
{
|
|
// Set the new scrolled coordinates
|
|
SetScrollOffset(GetScrollOffset() + (point - m_cPrevMousePos));
|
|
}
|
|
m_cPrevMousePos = point;
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Only proceed when the mouse is over the drawing area
|
|
if (nFlags & MK_LBUTTON)
|
|
{
|
|
// Calculate the coordinates in heightmap coordinates
|
|
|
|
// Translate into drawing window coordinates
|
|
CPoint hp = ViewToHeightmap(point);
|
|
|
|
/*
|
|
if (!(nFlags & MK_CONTROL))
|
|
{
|
|
// Add new static objects
|
|
GetIEditor()->GetDocument()->GetStatObjMap()->DistributeObjects( hp, m_iBrushSize );
|
|
}
|
|
else
|
|
{
|
|
// Remove static objects
|
|
GetIEditor()->GetDocument()->GetStatObjMap()->ClearObjects( hp, m_iBrushSize );
|
|
}
|
|
*/
|
|
/*
|
|
// Redraw the modified area
|
|
rcRedraw.left = point.x - m_scaledBrushSize;
|
|
rcRedraw.top = point.y - m_scaledBrushSize;
|
|
rcRedraw.right = point.x + m_scaledBrushSize;
|
|
rcRedraw.bottom = point.y + m_scaledBrushSize;
|
|
RedrawWindow(&rcRedraw, NULL, RDW_NOERASE | RDW_INVALIDATE);
|
|
*/
|
|
RedrawWindow();
|
|
}
|
|
|
|
CViewport::OnMouseMove(nFlags, point);
|
|
}
|
|
|
|
BOOL CTerrainViewport::OnEraseBkgnd(CDC* pDC)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
void CTerrainViewport::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
CViewport::OnSize(nType, cx, cy);
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Re-evaluate the zoom / scroll offset values
|
|
// TODO: Restore the zoom rectangle instead of resetting it
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
float fZoomFac1, fZoomFac2;
|
|
|
|
fZoomFac1 = (float) cx / m_heightmapSize.cx;
|
|
fZoomFac2 = (float) cx / m_heightmapSize.cy;
|
|
|
|
SetZoomFactor((fZoomFac1 < fZoomFac2) ? fZoomFac1 : fZoomFac2);
|
|
}
|
|
|
|
void CTerrainViewport::OnRButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
if (GetViewMode() != NothingMode)
|
|
return;
|
|
/*
|
|
if (GetIEditor()->GetEditMode() == eEditModeCreate)
|
|
{
|
|
// Stop creation.
|
|
GetIEditor()->GetObjectManager()->MouseCreateCallback( this,MOUSECREATE_RPOINT,point,0 );
|
|
}
|
|
*/
|
|
|
|
// Save the mouse down position
|
|
m_cMouseDownPos = point;
|
|
m_cPrevMousePos = point;
|
|
|
|
m_prevZoomFactor = GetZoomFactor();
|
|
m_prevScrollOffset = m_cScrollOffset;
|
|
|
|
SetCapture();
|
|
SetViewMode( ScrollZoomMode );
|
|
|
|
CViewport::OnRButtonDown(nFlags, point);
|
|
}
|
|
|
|
void CTerrainViewport::OnRButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
ReleaseCapture();
|
|
SetViewMode( NothingMode );
|
|
|
|
CViewport::OnRButtonUp(nFlags, point);
|
|
}
|
|
|
|
void CTerrainViewport::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
|
|
CViewport::OnLButtonDown(nFlags, point);
|
|
}
|
|
|
|
void CTerrainViewport::OnLButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
|
|
CViewport::OnLButtonUp(nFlags, point);
|
|
}
|
|
|
|
CPoint CTerrainViewport::ViewToHeightmap( CPoint hp )
|
|
{
|
|
hp.x -= m_cScrollOffset.x;
|
|
hp.y -= m_cScrollOffset.y;
|
|
|
|
// Scale with the zoom factor
|
|
float z1 = 1.0f / GetZoomFactor();
|
|
int x = FloatToIntRet((float)hp.x * z1);
|
|
int y = FloatToIntRet((float)hp.y * z1);
|
|
if (x < 0) x = 0;
|
|
if (y < 0) y = 0;
|
|
if (x >= m_heightmapSize.cx) x = m_heightmapSize.cx-1;
|
|
if (y >= m_heightmapSize.cx) y = m_heightmapSize.cx-1;
|
|
|
|
return CPoint( x,y );
|
|
}
|
|
|
|
CPoint CTerrainViewport::HeightmapToView( CPoint hp )
|
|
{
|
|
int x = FloatToIntRet(hp.x * GetZoomFactor());
|
|
int y = FloatToIntRet(hp.y * GetZoomFactor());
|
|
|
|
// Add the offset
|
|
x += m_cScrollOffset.x;
|
|
y += m_cScrollOffset.y;
|
|
|
|
return CPoint( x,y );
|
|
} |