Forest Editor - DropToGround Brush (Updated)
by Kevin Mitchell · 06/02/2013 (3:36 pm) · 5 comments
Just something I attempted to make that may help with readjustments to the forest elements after being placed. This will help all those who like me make terrain changes after placing everything and not wanting to manually drag all those objects out or erase and start again.
Code Changes:
Notes:
I wanted to add an adjustable sink like in the orginal add code. Currently it's hard coded to 0.5.
Edit:
Forgot about my video obsession:
T3D Forest Editor - Drop To Ground
//game/tools/forestEditor/main.cs //line: 50 %map = new ActionMap(); %map.bindCmd( keyboard, "1", "ForestEditorSelectModeBtn.performClick();", "" ); // Select %map.bindCmd( keyboard, "2", "ForestEditorMoveModeBtn.performClick();", "" ); // Move %map.bindCmd( keyboard, "3", "ForestEditorRotateModeBtn.performClick();", "" ); // Rotate %map.bindCmd( keyboard, "4", "ForestEditorScaleModeBtn.performClick();", "" ); // Scale %map.bindCmd( keyboard, "5", "ForestEditorPaintModeBtn.performClick();", "" ); // Paint %map.bindCmd( keyboard, "6", "ForestEditorEraseModeBtn.performClick();", "" ); // Erase %map.bindCmd( keyboard, "7", "ForestEditorEraseSelectedModeBtn.performClick();", "" ); // EraseSelected //RPG Edit %map.bindCmd( keyboard, "8", "ForestEditorDropToGroundModeBtn.performClick();", "" ); // DropTheBeat //END Editor
//game/tools/forestEditor/main.cs
//line: 172
%mode = ForestTools->BrushTool.mode;
switch$ (%mode)
{
case "Paint":
ForestEditorPaintModeBtn.performClick();
case "Erase":
ForestEditorEraseModeBtn.performClick();
case "EraseSelected":
ForestEditorEraseSelectedModeBtn.performClick();
//RPG Edit
case "DropToGround":
ForestEditorDropToGroundModeBtn.performClick();
//RPG END
}//tools/worldEditor/gui/ToolsPaletteGroups/ForestEditorPalette.ed.gui
//line: append new button
new GuiBitmapButtonCtrl(ForestEditorDropToGroundModeBtn) {
canSaveDynamicFields = "0";
internalName = "ForestEditorDropToGroundMode";
Enabled = "1";
isContainer = "0";
Profile = "GuiButtonProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "0 0";
Extent = "25 19";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "ForestEditorGui.setActiveTool( ForestTools->BrushTool ); ForestTools->BrushTool.mode = "DropToGround";";
tooltipprofile = "GuiToolTipProfile";
ToolTip = "Drop To Ground (8)";
hovertime = "1000";
bitmap = "tools/foresteditor/images/paint-forest-btn";
buttonType = "RadioButton";
useMouseEvents = "0";
};Code Changes:
//source/foresteditor/forestBrushTool.cpp
//line: 53
ImplementEnumType( ForestBrushMode,
"Active brush mode type.n"
"@internalnn")
{ ForestBrushTool::Paint, "Paint", "Creates Items based on the Elements you have selected.n" },
{ ForestBrushTool::Erase, "Erase", "Erases Items of any Mesh type.n" },
{ ForestBrushTool::EraseSelected, "EraseSelected", "Erases items of a specific type.n" },
//RPG Edit
{ ForestBrushTool::DropToGround, "DropToGround", "Drops items of a specific type to the ground.n" },
EndImplementEnumType;
//RPG End//source/foresteditor/forestBrushTool.cpp
//line: 229
if ( mMode == Paint )
brushColor = ColorI::BLUE;
else if ( mMode == Erase )
brushColor = ColorI::RED;
//RPG Edit
else if ( mMode == DropToGround )
brushColor = ColorI::WHITE;
//RPG End
else if ( mMode == EraseSelected )
brushColor.set( 150, 0, 0 );
if ( mMode == Paint || mMode == EraseSelected )
{
if ( mElements.empty() )
{
brushColor.set( 140, 140, 140 );
}
}//source/foresteditor/forestBrushTool.cpp
//line: 269
if ( mMode == Paint )
text = "Forest Editor ( Paint Tool ) - This brush creates Items based on the Elements you have selected.";
else if ( mMode == Erase )
text = "Forest Editor ( Erase Tool ) - This brush erases Items of any Mesh type.";
//RPG Edit
else if ( mMode == DropToGround )
text = "Forest Editor ( DropToGround Tool ) - This brush Drop To Ground Items of any Mesh type.";
//RPG End
else if ( mMode == EraseSelected )
text = "Forest Editor ( Erase Selected ) - This brush erases Items based on the Elements you have selected.";//source/foresteditor/forestBrushTool.cpp
//line: 318
void ForestBrushTool::_action( const Point3F &point )
{
if ( mMode == Paint )
_paint( point );
else if ( mMode == Erase || mMode == EraseSelected )
_erase( point );
else if ( mMode == DropToGround)
_DropToGround( point );
}//source/foresteditor/forestBrushTool.cpp
//line: 525
//RPG Edit
void ForestBrushTool::_DropToGround( const Point3F &point )
{
AssertFatal( mForest, "ForestBrushTool::_erase() - Can't erase without a Forest!" );
// First grab all the forest items around the point.
ForestItemVector trees;
if ( mForest->getData()->getItems( point.asPoint2F(), mSize, &trees ) == 0 )
return;
if ( trees.empty() )
return;
// Number of trees to erase depending on pressure.
S32 dropCount = getMax( (S32)mCeil( (F32)trees.size() * mPressure ), 0 );
// Initialize an MRandomDeck with trees under the brush.
MRandomDeck<ForestItem> deck(&mRandom);
deck.addToPile( trees );
deck.shuffle();
ForestItem currentTree;
// Draw eraseCount number of trees from MRandomDeck, adding them to our erase action.
for ( U32 i = 0; i < dropCount; i++ )
{
deck.draw(¤tTree);
//GetObject Data
// Get current object transform matrix
MatrixF SRC_xform = currentTree.getTransform();
// Get rotations from transform matrix
VectorF SRC_vec;
SRC_xform.getColumn(1,&SRC_vec);
// Get X-vector for roll calculation
Point3F SRC_xv;
SRC_xform.getColumn(0,&SRC_xv);
// Get Position
Point3F SRC_pos;
SRC_xform.getColumn(3,&SRC_pos);
Point3F mountpos;
F32 contactZ;
// Look for the ground at this position.
if ( !getGroundAt( Point3F( SRC_pos.x, SRC_pos.y , SRC_pos.z ),
&contactZ,
NULL ) )
{
break;
}
contactZ-=0.5;
SRC_pos.z=contactZ;
SRC_xform.setColumn(3,SRC_pos);
currentTree = mForest->getData()->updateItem( currentTree.getKey(), currentTree.getPosition(), currentTree.getData(), SRC_xform, currentTree.getScale() );
}
}
//RPG End//source/foresteditor/forestBrushTool.h
//line: 39
enum BrushMode
{
Paint = 0,
Erase,
EraseSelected,
//RPG Edit
DropToGround
//RPG End
};//source/foresteditor/forestBrushTool.h
//line: 75
virtual void _action( const Point3F &point );
virtual void _paint( const Point3F &point );
virtual void _erase( const Point3F &point );
//RPG Edit
virtual void _DropToGround( const Point3F &point );
//RPG EndNotes:
I wanted to add an adjustable sink like in the orginal add code. Currently it's hard coded to 0.5.
Edit:
Forgot about my video obsession:
T3D Forest Editor - Drop To Ground
About the author
Riding Solo since 2005. Current Project: Fated World 2005-Present RPG Engine Tool Kit - Now available.
#2
06/03/2013 (10:43 am)
Awe that's not suppose to happen under code flags... I'll correct this when i get home.
#4
07/08/2013 (12:27 am)
Very handy, thanks for sharing Kevin!
#5
10/06/2013 (9:59 am)
A wonderful concept Kevin, are you a mind reader? I've needed something like this forever. Thanks for thaking the time to do this and share it with us! 
Torque 3D Owner Kevin Rogers
(Can we get the code re-posted without the HTML character tags?)