216 lines
5.4 KiB
C++
216 lines
5.4 KiB
C++
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Crytek Engine Source File.
|
|
// Copyright (C), Crytek Studios, 2001.
|
|
// -------------------------------------------------------------------------
|
|
// File name: TerrainHoleTool.cpp
|
|
// Version: v1.00
|
|
// Created: 11/1/2002 by Timur.
|
|
// Compilers: Visual C++ 6.0
|
|
// Description: Terrain Modification Tool implementation.
|
|
// -------------------------------------------------------------------------
|
|
// History:
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "StdAfx.h"
|
|
#include "TerrainHoleTool.h"
|
|
#include "Viewport.h"
|
|
#include "TerrainHolePanel.h"
|
|
#include "Heightmap.h"
|
|
#include "Objects\DisplayContext.h"
|
|
|
|
#include "I3DEngine.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
IMPLEMENT_DYNCREATE(CTerrainHoleTool,CEditTool)
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CTerrainHoleTool::CTerrainHoleTool()
|
|
{
|
|
m_panelId = 0;
|
|
m_panel = 0;
|
|
|
|
m_pointerPos(0,0,0);
|
|
|
|
m_bMakeHole = true;
|
|
m_brushRadius = 1;
|
|
GetIEditor()->ClearSelection();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CTerrainHoleTool::~CTerrainHoleTool()
|
|
{
|
|
m_pointerPos(0,0,0);
|
|
if (GetIEditor()->IsUndoRecording())
|
|
GetIEditor()->CancelUndo();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CTerrainHoleTool::BeginEditParams( IEditor *ie,int flags )
|
|
{
|
|
m_ie = ie;
|
|
if (!m_panelId)
|
|
{
|
|
m_panel = new CTerrainHolePanel(this,AfxGetMainWnd());
|
|
m_panelId = m_ie->AddRollUpPage( ROLLUP_TERRAIN,"Modify Terrain",m_panel );
|
|
AfxGetMainWnd()->SetFocus();
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CTerrainHoleTool::EndEditParams()
|
|
{
|
|
if (m_panelId)
|
|
{
|
|
m_ie->RemoveRollUpPage(ROLLUP_TERRAIN,m_panelId);
|
|
m_panel = 0;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool CTerrainHoleTool::MouseCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags )
|
|
{
|
|
m_pointerPos = view->ViewToWorld( point,0,true );
|
|
if (event == eMouseLDown || (event == eMouseMove && (flags&MK_LBUTTON)))
|
|
{
|
|
/*
|
|
if (flags&MK_CONTROL)
|
|
{
|
|
bool bMakeHole = m_bMakeHole;
|
|
m_bMakeHole = false;
|
|
Modify();
|
|
m_bMakeHole = bMakeHole;
|
|
}
|
|
else
|
|
{
|
|
Modify();
|
|
}
|
|
*/
|
|
if (!GetIEditor()->IsUndoRecording())
|
|
GetIEditor()->BeginUndo();
|
|
Modify();
|
|
}
|
|
else
|
|
{
|
|
if (GetIEditor()->IsUndoRecording())
|
|
GetIEditor()->AcceptUndo( "Terrain Hole" );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CTerrainHoleTool::Display( DisplayContext &dc )
|
|
{
|
|
if (dc.flags & DISPLAY_2D)
|
|
return;
|
|
|
|
CHeightmap *heightmap = m_ie->GetHeightmap();
|
|
int unitSize = heightmap->GetUnitSize();
|
|
|
|
dc.renderer->SetMaterialColor( 0,1,0,1 );
|
|
dc.DrawTerrainCircle( m_pointerPos,m_brushRadius,0.2f );
|
|
|
|
float fx1 = (m_pointerPos.y - m_brushRadius)/unitSize;
|
|
float fy1 = (m_pointerPos.x - m_brushRadius)/unitSize;
|
|
float fx2 = (m_pointerPos.y + m_brushRadius)/unitSize;
|
|
float fy2 = (m_pointerPos.x + m_brushRadius)/unitSize;
|
|
|
|
|
|
int x1 = MAX(fx1,0);
|
|
int y1 = MAX(fy1,0);
|
|
int x2 = MIN(fx2,heightmap->GetWidth()-1);
|
|
int y2 = MIN(fy2,heightmap->GetHeight()-1);
|
|
|
|
if (m_bMakeHole)
|
|
dc.renderer->SetMaterialColor( 1,0,0,1 );
|
|
else
|
|
dc.renderer->SetMaterialColor( 0,0,1,1 );
|
|
Vec3 p1,p2,p3,p4;
|
|
// Make hole.
|
|
for (int x = x1; x <= x2; x++)
|
|
{
|
|
for (int y = y1; y <= y2; y++)
|
|
{
|
|
p1.x = y*unitSize;
|
|
p1.y = x*unitSize;
|
|
|
|
p2.x = y*unitSize+unitSize;
|
|
p2.y = x*unitSize;
|
|
|
|
p3.x = y*unitSize+unitSize;
|
|
p3.y = x*unitSize+unitSize;
|
|
|
|
p4.x = y*unitSize;
|
|
p4.y = x*unitSize+unitSize;
|
|
|
|
p1.z = dc.engine->GetTerrainElevation(p1.x,p1.y)+0.2f;
|
|
p2.z = dc.engine->GetTerrainElevation(p2.x,p2.y)+0.2f;
|
|
p3.z = dc.engine->GetTerrainElevation(p3.x,p3.y)+0.2f;
|
|
p4.z = dc.engine->GetTerrainElevation(p4.x,p4.y)+0.2f;
|
|
dc.DrawLine( p1,p2 );
|
|
dc.DrawLine( p2,p3 );
|
|
dc.DrawLine( p3,p4 );
|
|
dc.DrawLine( p1,p4 );
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool CTerrainHoleTool::OnKeyDown( CViewport *view,uint nChar,uint nRepCnt,uint nFlags )
|
|
{
|
|
bool bProcessed = false;
|
|
if (nChar == VK_ADD)
|
|
{
|
|
if (m_brushRadius < 100)
|
|
m_brushRadius += 0.5f;
|
|
bProcessed = true;
|
|
}
|
|
if (nChar == VK_SUBTRACT)
|
|
{
|
|
if (m_brushRadius > 0.5f)
|
|
m_brushRadius -= 0.5f;
|
|
bProcessed = true;
|
|
}
|
|
if (nChar == VK_CONTROL && !(nFlags&(1<<14))) // only once (no repeat).
|
|
{
|
|
m_bMakeHole = !m_bMakeHole;
|
|
m_panel->SetMakeHole(m_bMakeHole);
|
|
}
|
|
if (bProcessed && m_panel)
|
|
{
|
|
m_panel->m_radius.SetPos(m_brushRadius);
|
|
}
|
|
return bProcessed;
|
|
}
|
|
|
|
bool CTerrainHoleTool::OnKeyUp( CViewport *view,uint nChar,uint nRepCnt,uint nFlags )
|
|
{
|
|
if (nChar == VK_CONTROL)
|
|
{
|
|
m_bMakeHole = !m_bMakeHole;
|
|
m_panel->SetMakeHole(m_bMakeHole);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CTerrainHoleTool::Modify()
|
|
{
|
|
CHeightmap *heightmap = m_ie->GetHeightmap();
|
|
int unitSize = heightmap->GetUnitSize();
|
|
|
|
float fx1 = (m_pointerPos.y - m_brushRadius)/unitSize;
|
|
float fy1 = (m_pointerPos.x - m_brushRadius)/unitSize;
|
|
float fx2 = (m_pointerPos.y + m_brushRadius)/unitSize;
|
|
float fy2 = (m_pointerPos.x + m_brushRadius)/unitSize;
|
|
|
|
int x1 = MAX(fx1,0);
|
|
int y1 = MAX(fy1,0);
|
|
int x2 = MIN(fx2,heightmap->GetWidth()-1);
|
|
int y2 = MIN(fy2,heightmap->GetHeight()-1);
|
|
|
|
heightmap->MakeHole( x1,y1,x2-x1,y2-y1,m_bMakeHole );
|
|
}
|