Files
FC1/Editor/VegetationTool.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

833 lines
22 KiB
C++

////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
// File name: VegetationTool.cpp
// Version: v1.00
// Created: 11/1/2002 by Timur.
// Compilers: Visual C++ 6.0
// Description: Places vegetation on terrain.
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "VegetationTool.h"
#include "Viewport.h"
#include "VegetationPanel.h"
#include "Heightmap.h"
#include "VegetationMap.h"
#include "Objects\DisplayContext.h"
#include "NumberDlg.h"
#include "PanelPreview.h"
#include "Settings.h"
#include "I3dEngine.h"
#include "IPhysics.h"
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CVegetationTool,CEditTool)
float CVegetationTool::m_brushRadius = 1;
//bool CVegetationTool::m_bPlaceMode = true;
//////////////////////////////////////////////////////////////////////////
CVegetationTool::CVegetationTool()
{
m_panelId = 0;
m_panel = 0;
m_panelPreview = 0;
m_panelPreviewId = 0;
m_pointerPos(0,0,0);
m_vegetationMap = GetIEditor()->GetHeightmap()->GetVegetationMap();
GetIEditor()->ClearSelection();
m_bPaintingMode = false;
m_bPlaceMode = true;
m_opMode = OPMODE_NONE;
SetStatusText( "Click to Place or Remove Vegetation" );
}
//////////////////////////////////////////////////////////////////////////
CVegetationTool::~CVegetationTool()
{
m_pointerPos(0,0,0);
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::BeginEditParams( IEditor *ie,int flags )
{
m_ie = ie;
if (!m_panelId)
{
CWaitCursor wait;
m_panel = new CVegetationPanel(this,AfxGetMainWnd());
m_panelId = m_ie->AddRollUpPage( ROLLUP_TERRAIN,"Vegetation",m_panel );
if (gSettings.bPreviewGeometryWindow)
{
m_panelPreview = new CPanelPreview(AfxGetMainWnd());
m_panelPreviewId = m_ie->AddRollUpPage( ROLLUP_TERRAIN,"Object Preview",m_panelPreview );
m_panel->SetPreviewPanel(m_panelPreview);
}
AfxGetMainWnd()->SetFocus();
GetIEditor()->UpdateViews( eUpdateStatObj );
}
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::EndEditParams()
{
if (m_panelPreviewId)
{
m_ie->RemoveRollUpPage(ROLLUP_TERRAIN,m_panelPreviewId);
m_panelPreviewId = 0;
m_panelPreview = 0;
}
if (m_panelId)
{
m_ie->RemoveRollUpPage(ROLLUP_TERRAIN,m_panelId);
m_panel = 0;
m_panelId = 0;
}
GetIEditor()->SetStatusText( "Ready" );
}
//////////////////////////////////////////////////////////////////////////
// Specific mouse events handlers.
bool CVegetationTool::OnLButtonDown( CViewport *view,UINT nFlags,CPoint point )
{
m_mouseDownPos = point;
bool bShift = nFlags & MK_SHIFT;
bool bCtrl = nFlags & MK_CONTROL;
bool bAlt = (GetAsyncKeyState(VK_MENU) & (1<<15)) != 0;
m_opMode = OPMODE_NONE;
if (m_bPaintingMode)
{
m_opMode = OPMODE_PAINT;
if (nFlags&MK_CONTROL)
m_bPlaceMode = false;
else
m_bPlaceMode = true;
GetIEditor()->BeginUndo();
view->CaptureMouse();
PaintBrush();
}
else
{
Matrix44 tm;
tm.SetIdentity();
tm.SetTranslationOLD( view->ViewToWorld(point) );
view->SetConstrPlane( point,tm );
m_opMode = OPMODE_SELECT;
if (bShift)
{
PlaceThing();
m_opMode = OPMODE_MOVE;
GetIEditor()->BeginUndo();
}
else
{
if (!bCtrl && !bAlt)
{
ClearThingSelection();
}
// Select thing.
if (SelectThingAtPoint(view,point))
{
if (bAlt)
m_opMode = OPMODE_SCALE;
else
m_opMode = OPMODE_MOVE;
GetIEditor()->BeginUndo();
}
}
view->CaptureMouse();
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CVegetationTool::OnLButtonUp( CViewport *view,UINT nFlags,CPoint point )
{
if (GetIEditor()->IsUndoRecording())
{
if (m_opMode == OPMODE_MOVE)
GetIEditor()->AcceptUndo( "Vegetation Move" );
else if (m_opMode == OPMODE_SCALE)
GetIEditor()->AcceptUndo( "Vegetation Scale" );
else if (m_opMode == OPMODE_PAINT)
GetIEditor()->AcceptUndo( "Vegetation Paint" );
else
GetIEditor()->CancelUndo();
}
if (m_opMode == OPMODE_SELECT)
{
CRect rect = view->GetSelectionRectangle();
if (!(nFlags & MK_CONTROL))
{
ClearThingSelection();
}
if (!rect.IsRectEmpty())
SelectThingsInRect( view,rect );
/*
BBox box;
GetIEditor()->GetSelectedRegion( box );
if (!box.IsEmpty())
{
ClearThingSelection();
std::vector<CVegetationInstance*> selectedThings;
m_vegetationMap->GetObjectInstances( box.min.x,box.min.y,box.max.x,box.max.y,selectedThings );
for (int i = 0; i < selectedThings.size(); i++)
{
if (!selectedThings[i]->object->IsHidden())
{
SelectThing( selectedThings[i],false );
}
}
}
*/
}
m_opMode = OPMODE_NONE;
view->ReleaseMouse();
// Reset selected region.
view->ResetSelectionRegion();
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CVegetationTool::OnMouseMove( CViewport *view,UINT nFlags,CPoint point )
{
if (nFlags&MK_CONTROL)
m_bPlaceMode = false;
else
m_bPlaceMode = true;
if (m_opMode == OPMODE_PAINT)
{
if (nFlags&MK_LBUTTON)
PaintBrush();
}
else if (m_opMode == OPMODE_SELECT)
{
// Define selection.
view->SetSelectionRectangle( m_mouseDownPos,point );
//CRect rc( m_cMouseDownPos,point );
}
else if (m_opMode == OPMODE_MOVE)
{
GetIEditor()->RestoreUndo();
// Define selection.
int axis = GetIEditor()->GetAxisConstrains();
Vec3 p1 = view->MapViewToCP( m_mouseDownPos );
Vec3 p2 = view->MapViewToCP( point );
Vec3 v = view->GetCPVector(p1,p2);
MoveSelected( v,(axis == AXIS_TERRAIN) );
//m_mouseDownPos = point;
}
else if (m_opMode == OPMODE_SCALE)
{
GetIEditor()->RestoreUndo();
// Define selection.
int y = m_mouseDownPos.y - point.y;
if (y != 0)
{
float fScale = 1.0f + (float)y/100.0f;
ScaleSelected( fScale );
}
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CVegetationTool::MouseCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags )
{
m_pointerPos = view->ViewToWorld( point,0,true );
m_mousePos = point;
m_bPlaceMode = true;
bool bProcessed = false;
if (event == eMouseLDown)
{
bProcessed = OnLButtonDown( view,flags,point );
}
else if (event == eMouseLUp)
{
bProcessed = OnLButtonUp( view,flags,point );
}
else if (event == eMouseMove)
{
bProcessed = OnMouseMove( view,flags,point );
}
GetIEditor()->SetMarkerPosition( m_pointerPos );
int unitSize = GetIEditor()->GetHeightmap()->GetUnitSize();
if (flags & MK_CONTROL)
{
//swap x/y
float slope = GetIEditor()->GetHeightmap()->GetSlope( m_pointerPos.y/unitSize,m_pointerPos.x/unitSize );
char szNewStatusText[512];
sprintf(szNewStatusText, "Slope: %g",slope );
GetIEditor()->SetStatusText(szNewStatusText);
}
else
{
GetIEditor()->SetStatusText( "Shift: Place New Ctrl: Add To Selection Alt: Scale Selected DEL: Delete Selected" );
}
m_prevMousePos = point;
// Not processed.
return bProcessed;
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::Display( DisplayContext &dc )
{
if (!m_bPaintingMode)
{
if (dc.flags & DISPLAY_2D)
return;
dc.SetColor( 0,1,0,1 );
// Single object 3D display mode.
for (int i = 0; i < m_selectedThings.size(); i++)
{
float radius = m_selectedThings[i]->object->GetObjectSize() * m_selectedThings[i]->scale;
dc.DrawTerrainCircle( m_selectedThings[i]->pos,radius/2.0f,0.1f );
}
}
else
{
// Brush paint mode.
if (dc.flags & DISPLAY_2D)
{
CPoint p1 = dc.view->WorldToView(m_pointerPos);
CPoint p2 = dc.view->WorldToView(m_pointerPos+Vec3(m_brushRadius,0,0));
float radius = sqrtf( (p2.x-p1.x)*(p2.x-p1.x) + (p2.y-p1.y)*(p2.y-p1.y) );
dc.SetColor( 0,1,0,1 );
dc.DrawWireCircle2d( p1,radius,0 );
return;
}
dc.SetColor( 0,1,0,1 );
dc.DrawTerrainCircle( m_pointerPos,m_brushRadius,0.2f );
float col[4] = { 1,1,1,0.8f };
if (m_bPlaceMode)
dc.renderer->DrawLabelEx( m_pointerPos+Vec3(0,0,1),1.0f,col,true,true,"Place" );
else
dc.renderer->DrawLabelEx( m_pointerPos+Vec3(0,0,1),1.0f,col,true,true,"Remove" );
}
}
//////////////////////////////////////////////////////////////////////////
bool CVegetationTool::OnKeyDown( CViewport *view,uint nChar,uint nRepCnt,uint nFlags )
{
bool bProcessed = false;
if (nChar == VK_ADD)
{
if (m_brushRadius < 300)
m_brushRadius += 1;
bProcessed = true;
}
if (nChar == VK_SUBTRACT)
{
if (m_brushRadius > 1)
m_brushRadius -= 1;
bProcessed = true;
}
if (nChar == VK_DELETE)
{
CUndo undo( "Vegetation Delete" );
if (!m_selectedThings.empty())
{
if (AfxMessageBox( "Delete Selected Instances?",MB_YESNO) == IDYES)
{
for (int i = 0; i < m_selectedThings.size(); i++)
{
m_vegetationMap->DeleteObjInstance( m_selectedThings[i] );
}
ClearThingSelection();
if (m_panel)
m_panel->UpdateAllObjectsInTree();
}
}
bProcessed = true;
}
if (nChar == VK_CONTROL && !(nFlags&(1<<14))) // only once (no repeat).
{
m_bPlaceMode = true;
m_opMode = OPMODE_NONE;
}
if (bProcessed && m_panel)
{
m_panel->m_radius.SetPos(m_brushRadius);
}
return bProcessed;
}
//////////////////////////////////////////////////////////////////////////
bool CVegetationTool::OnKeyUp( CViewport *view,uint nChar,uint nRepCnt,uint nFlags )
{
if (nChar == VK_CONTROL)
{
m_bPlaceMode = true;
m_opMode = OPMODE_NONE;
}
return false;
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::GetSelectedObjects( std::vector<CVegetationObject*> &objects )
{
objects.clear();
for (int i = 0; i < m_vegetationMap->GetObjectCount(); i++)
{
if (m_vegetationMap->GetObject(i)->IsSelected())
objects.push_back( m_vegetationMap->GetObject(i) );
}
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::PaintBrush()
{
GetSelectedObjects( m_selectedObjects );
CRect rc( m_pointerPos.x-m_brushRadius,m_pointerPos.y-m_brushRadius,
m_pointerPos.x+m_brushRadius,m_pointerPos.y+m_brushRadius );
if (m_bPlaceMode)
{
for (int i = 0; i < m_selectedObjects.size(); i++)
{
int numInstances = m_selectedObjects[i]->GetNumInstances();
m_vegetationMap->PaintBrush( rc,true,m_selectedObjects[i] );
// If number of instances changed.
if (numInstances != m_selectedObjects[i]->GetNumInstances())
m_panel->UpdateObjectInTree( m_selectedObjects[i] );
}
}
else
{
for (int i = 0; i < m_selectedObjects.size(); i++)
{
int numInstances = m_selectedObjects[i]->GetNumInstances();
m_vegetationMap->ClearBrush( rc,true,m_selectedObjects[i] );
// If number of instances changed.
if (numInstances != m_selectedObjects[i]->GetNumInstances())
m_panel->UpdateObjectInTree( m_selectedObjects[i] );
}
}
BBox updateRegion;
updateRegion.min = m_pointerPos - Vec3(m_brushRadius,m_brushRadius,m_brushRadius);
updateRegion.max = m_pointerPos + Vec3(m_brushRadius,m_brushRadius,m_brushRadius);
GetIEditor()->UpdateViews( eUpdateStatObj,&updateRegion );
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::PlaceThing()
{
GetSelectedObjects( m_selectedObjects );
CUndo undo( "Vegetation Place" );
if (!m_selectedObjects.empty())
{
CVegetationInstance *thing = m_vegetationMap->PlaceObjectInstance( m_pointerPos,m_selectedObjects[0] );
// If number of instances changed.
if (thing)
{
ClearThingSelection();
SelectThing(thing);
m_panel->UpdateObjectInTree( m_selectedObjects[0] );
BBox updateRegion;
updateRegion.min = m_pointerPos - Vec3(1,1,1);
updateRegion.max = m_pointerPos + Vec3(1,1,1);
GetIEditor()->UpdateViews( eUpdateStatObj,&updateRegion );
}
}
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::Distribute()
{
GetSelectedObjects( m_selectedObjects );
for (int i = 0; i < m_selectedObjects.size(); i++)
{
int numInstances = m_selectedObjects[i]->GetNumInstances();
CRect rc( 0,0,m_vegetationMap->GetSize(),m_vegetationMap->GetSize() );
m_vegetationMap->PaintBrush( rc,false,m_selectedObjects[i] );
if (numInstances != m_selectedObjects[i]->GetNumInstances())
m_panel->UpdateObjectInTree( m_selectedObjects[i] );
}
if (!m_selectedObjects.empty())
GetIEditor()->UpdateViews( eUpdateStatObj );
ClearThingSelection();
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::DistributeMask( const char *maskFile )
{
GetSelectedObjects( m_selectedObjects );
for (int i = 0; i < m_selectedObjects.size(); i++)
{
int numInstances = m_selectedObjects[i]->GetNumInstances();
//map->PaintMask( maskFile,m_selectedObjects[i] );
if (numInstances != m_selectedObjects[i]->GetNumInstances())
m_panel->UpdateObjectInTree( m_selectedObjects[i] );
}
if (!m_selectedObjects.empty())
GetIEditor()->UpdateViews( eUpdateStatObj );
ClearThingSelection();
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::Clear()
{
GetSelectedObjects( m_selectedObjects );
for (int i = 0; i < m_selectedObjects.size(); i++)
{
int numInstances = m_selectedObjects[i]->GetNumInstances();
CRect rc( 0,0,m_vegetationMap->GetSize(),m_vegetationMap->GetSize());
m_vegetationMap->ClearBrush( rc,false,m_selectedObjects[i] );
if (numInstances != m_selectedObjects[i]->GetNumInstances())
m_panel->UpdateObjectInTree( m_selectedObjects[i] );
}
if (!m_selectedObjects.empty())
GetIEditor()->UpdateViews( eUpdateStatObj );
ClearThingSelection();
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::ClearMask( const char *maskFile )
{
//GetSelectedObjects( m_selectedObjects );
/*
for (int i = 0; i < m_selectedObjects.size(); i++)
{
int numInstances = m_selectedObjects[i]->GetNumInstances();
//m_vegetationMap->ClearMask( maskFile,m_selectedObjects[i] );
if (numInstances != m_selectedObjects[i]->GetNumInstances())
m_panel->UpdateObjectInTree( m_selectedObjects[i] );
}
*/
m_vegetationMap->ClearMask( maskFile );
//if (!m_selectedObjects.empty())
GetIEditor()->UpdateViews( eUpdateStatObj );
ClearThingSelection();
}
void CVegetationTool::HideSelectedObjects( bool bHide )
{
GetSelectedObjects( m_selectedObjects );
for (int i = 0; i < m_selectedObjects.size(); i++)
{
m_vegetationMap->HideObject( m_selectedObjects[i],bHide );
}
if (!m_selectedObjects.empty())
{
/*
GetIEditor()->UpdateViews( eUpdateStatObj );
CStatObjMap *vegetationMap = GetIEditor()->GetStatObjMap();
vegetationMap->RemoveObjectsFromTerrain();
vegetationMap->PlaceObjectsOnTerrain();
*/
}
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::RemoveSelectedObjects()
{
GetSelectedObjects( m_selectedObjects );
GetIEditor()->BeginUndo();
for (int i = 0; i < m_selectedObjects.size(); i++)
{
int numInstances = m_selectedObjects[i]->GetNumInstances();
m_vegetationMap->RemoveObject( m_selectedObjects[i] );
if (numInstances != m_selectedObjects[i]->GetNumInstances())
m_panel->UpdateObjectInTree( m_selectedObjects[i] );
}
GetIEditor()->AcceptUndo( "Remove Brush" );
ClearThingSelection();
if (!m_selectedObjects.empty())
{
GetIEditor()->UpdateViews( eUpdateStatObj );
}
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::SetMode( bool paintMode )
{
if (paintMode)
{
SetStatusText( "Hold Ctrl to Remove Vegetation" );
}
else
{
SetStatusText( "Push Paint button to start painting" );
}
ClearThingSelection();
m_bPaintingMode = paintMode;
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::ClearThingSelection()
{
m_selectedThings.clear();
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::SelectThing( CVegetationInstance *thing,bool bSelObject )
{
// If already selected.
if (std::find(m_selectedThings.begin(),m_selectedThings.end(),thing) != m_selectedThings.end())
return;
if (thing->object->IsHidden())
return;
m_selectedThings.push_back(thing);
if (m_panel && bSelObject)
{
m_panel->SelectObject( thing->object );
}
}
//////////////////////////////////////////////////////////////////////////
bool CVegetationTool::SelectThingAtPoint( CViewport *view,CPoint point,bool bNotSelect )
{
Vec3 raySrc,rayDir;
view->ViewToWorldRay( point,raySrc,rayDir );
bool bCollideTerrain=false;
Vec3 pos = view->ViewToWorld( point,&bCollideTerrain,true );
IPhysicalWorld *pPhysics = GetIEditor()->GetSystem()->GetIPhysicalWorld();
if (pPhysics)
{
int objTypes = ent_static;
int flags = rwi_stop_at_pierceable|rwi_ignore_terrain_holes;
//flags = 31;
ray_hit hit;
int col = pPhysics->RayWorldIntersection( raySrc,rayDir*1000.0f,objTypes,flags,&hit,1 );
if (hit.dist > 0 && !hit.bTerrain)
{
pe_status_pos statusPos;
hit.pCollider->GetStatus( &statusPos );
pos = statusPos.pos;
}
}
// Find closest thing to this point.
CVegetationInstance *obj = m_vegetationMap->GetNearestInstance( pos,1.0f );
if (obj)
{
if (!bNotSelect)
SelectThing(obj);
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::MoveSelected( const Vec3 &offset,bool bFollowTerrain )
{
BBox box;
box.Reset();
Vec3 newPos,oldPos;
for (int i = 0; i < m_selectedThings.size(); i++)
{
oldPos = m_selectedThings[i]->pos;
newPos = oldPos + offset;
//if (bFollowTerrain)
{
// Make sure object keeps it height.
//float height = oldPos.z - GetIEditor()->GetTerrainElevation( oldPos.x,oldPos.y );
//newPos.z = GetIEditor()->GetTerrainElevation( newPos.x,newPos.y ) + height;
}
// Always stick to terrain.
newPos.z = GetIEditor()->GetTerrainElevation( newPos.x,newPos.y );
m_vegetationMap->MoveInstance( m_selectedThings[i],newPos );
box.Add( newPos );
}
box.min = box.min - Vec3(1,1,1);
box.max = box.max + Vec3(1,1,1);
GetIEditor()->UpdateViews( eUpdateStatObj,&box );
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::ScaleSelected( float fScale )
{
if (fScale <= 0.01f)
return;
if (!m_selectedThings.empty())
{
int numThings = m_selectedThings.size();
for (int i = 0; i < numThings; i++)
{
m_vegetationMap->RecordUndo( m_selectedThings[i] );
m_selectedThings[i]->scale *= fScale;
// Force this object to be placed on terrain again.
m_vegetationMap->MoveInstance(m_selectedThings[i],m_selectedThings[i]->pos);
}
}
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::ScaleObjects()
{
float fScale = 1;
if (m_selectedThings.size() == 1)
{
fScale = m_selectedThings[0]->scale;
}
CNumberDlg dlg( AfxGetMainWnd(),fScale,"Scale Selected Object(s)" );
if (dlg.DoModal() != IDOK)
return;
fScale = dlg.GetValue();
if (fScale <= 0)
return;
if (!m_selectedThings.empty())
{
int numThings = m_selectedThings.size();
for (int i = 0; i < numThings; i++)
{
m_vegetationMap->RecordUndo( m_selectedThings[i] );
if (numThings > 1)
m_selectedThings[i]->scale *= fScale;
else
m_selectedThings[i]->scale = fScale;
// Force this object to be placed on terrain again.
m_vegetationMap->MoveInstance(m_selectedThings[i],m_selectedThings[i]->pos);
}
}
else
{
GetSelectedObjects( m_selectedObjects );
for (int i = 0; i < m_selectedObjects.size(); i++)
{
m_vegetationMap->ScaleObjectInstances( m_selectedObjects[i],fScale );
}
}
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::SelectThingsInRect( CViewport *view,CRect rect )
{
BBox box;
std::vector<CVegetationInstance*> things;
m_vegetationMap->GetAllInstances( things );
for (int i = 0; i < things.size(); i++)
{
Vec3 pos = things[i]->pos;
box.min.Set( pos.x-0.1f,pos.y-0.1f,pos.z-0.1f );
box.max.Set( pos.x+0.1f,pos.y+0.1f,pos.z+0.1f );
if (!view->IsBoundsVisible(box))
continue;
CPoint pnt = view->WorldToView( things[i]->pos );
if (rect.PtInRect(pnt))
{
SelectThing( things[i],false );
}
}
}
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::Command_Activate()
{
CEditTool *pTool = GetIEditor()->GetEditTool();
if (pTool && pTool->IsKindOf(RUNTIME_CLASS(CVegetationTool)))
{
// Already active.
return;
}
pTool = new CVegetationTool;
GetIEditor()->SetEditTool( pTool );
GetIEditor()->SelectRollUpBar( ROLLUP_TERRAIN );
AfxGetMainWnd()->RedrawWindow(NULL,NULL,RDW_INVALIDATE|RDW_ALLCHILDREN);
}
//////////////////////////////////////////////////////////////////////////
// Class description.
//////////////////////////////////////////////////////////////////////////
class CVegetationTool_ClassDesc : public CRefCountClassDesc
{
//! This method returns an Editor defined GUID describing the class this plugin class is associated with.
virtual ESystemClassID SystemClassID() { return ESYSTEM_CLASS_EDITTOOL; }
//! Return the GUID of the class created by plugin.
virtual REFGUID ClassID()
{
// {854ECA09-C572-444a-BC1F-2F7A71E1277D}
static const GUID guid = { 0x854eca09, 0xc572, 0x444a, { 0xbc, 0x1f, 0x2f, 0x7a, 0x71, 0xe1, 0x27, 0x7d } };
return guid;
}
//! This method returns the human readable name of the class.
virtual const char* ClassName() { return "VegetationTool"; };
//! This method returns Category of this class, Category is specifing where this plugin class fits best in
//! create panel.
virtual const char* Category() { return "Terrain"; };
//////////////////////////////////////////////////////////////////////////
};
//////////////////////////////////////////////////////////////////////////
void CVegetationTool::RegisterTool( CRegistrationContext &rc )
{
rc.pClassFactory->RegisterClass( new CVegetationTool_ClassDesc );
rc.pCommandManager->RegisterCommand( "EditTool.VegetationTool.Activate",functor(CVegetationTool::Command_Activate) );
}