Adding a basic rule-based terrain painting implementation.

http://www.garagegames.com/community/resources/view/17145
This commit is contained in:
thecelloman 2013-03-21 17:45:23 -04:00
parent 79fd610301
commit 25efdb4a06
10 changed files with 769 additions and 0 deletions

View file

@ -2933,3 +2933,74 @@ ConsoleMethod( TerrainEditor, setSlopeLimitMaxAngle, F32, 3, 3, 0)
object->mSlopeMaxAngle = angle;
return angle;
}
//------------------------------------------------------------------------------
void TerrainEditor::autoMaterialLayer( F32 mMinHeight, F32 mMaxHeight, F32 mMinSlope, F32 mMaxSlope )
{
if (!mActiveTerrain)
return;
S32 mat = getPaintMaterialIndex();
if (mat == -1)
return;
mUndoSel = new Selection;
U32 terrBlocks = mActiveTerrain->getBlockSize();
for (U32 y = 0; y < terrBlocks; y++)
{
for (U32 x = 0; x < terrBlocks; x++)
{
// get info
GridPoint gp;
gp.terrainBlock = mActiveTerrain;
gp.gridPos.set(x, y);
GridInfo gi;
getGridInfo(gp, gi);
if (gi.mMaterial == mat)
continue;
Point3F wp;
gridToWorld(gp, wp);
if (!(wp.z >= mMinHeight && wp.z <= mMaxHeight))
continue;
// transform wp to object space
Point3F op;
mActiveTerrain->getWorldTransform().mulP(wp, &op);
Point3F norm;
mActiveTerrain->getNormal(Point2F(op.x, op.y), &norm, true);
if (mMinSlope > 0)
if (norm.z > mSin(mDegToRad(90.0f - mMinSlope)))
continue;
if (mMaxSlope < 90)
if (norm.z < mSin(mDegToRad(90.0f - mMaxSlope)))
continue;
gi.mMaterialChanged = true;
mUndoSel->add(gi);
gi.mMaterial = mat;
setGridInfo(gi);
}
}
if(mUndoSel->size())
submitUndo( mUndoSel );
else
delete mUndoSel;
mUndoSel = 0;
scheduleMaterialUpdate();
}
ConsoleMethod( TerrainEditor, autoMaterialLayer, void, 6, 6, "(float minHeight, float maxHeight, float minSlope, float maxSlope)")
{
object->autoMaterialLayer( dAtof(argv[2]), dAtof(argv[3]), dAtof(argv[4]), dAtof(argv[5]) );
}

View file

@ -230,6 +230,8 @@ class TerrainEditor : public EditTSCtrl
void submitMaterialUndo( String actionName );
void onMaterialUndo( TerrainBlock *terr );
void autoMaterialLayer(F32, F32, F32, F32);
private:
typedef EditTSCtrl Parent;

View file

@ -0,0 +1,326 @@
//--- OBJECT WRITE BEGIN ---
%guiContent = new GuiControl(ProceduralTerrainPainterGui) {
canSaveDynamicFields = "0";
isContainer = "1";
Profile = "ToolsGuiDefaultProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "0 0";
Extent = "1024 768";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
new GuiWindowCtrl(ProceduralTerrainPainterDescription) {
canSaveDynamicFields = "0";
isContainer = "1";
Profile = "ToolsGuiWindowProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "285 83";
Extent = "175 209";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
resizeWidth = "0";
resizeHeight = "0";
canMove = "1";
canClose = "1";
canMinimize = "0";
canMaximize = "0";
minSize = "50 50";
EdgeSnap = "1";
canCollapse = "0";
CollapseGroup = "-1";
CollapseGroupNum = "-1";
closeCommand = "Canvas.popDialog(ProceduralTerrainPainterGui);";
text = "Generate layer mask";
new GuiButtonCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "ToolsGuiButtonProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "19 164";
Extent = "140 30";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "generateProceduralTerrainMask();";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
text = "Generate";
groupNum = "-1";
buttonType = "PushButton";
useMouseEvents = "0";
};
new GuiTextCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiTextProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "15 37";
Extent = "33 13";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "HEIGHT";
maxLength = "1024";
};
new GuiTextCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiTextProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "59 37";
Extent = "23 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Min.";
maxLength = "1024";
};
new GuiTextCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiTextProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "59 62";
Extent = "23 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Max.";
maxLength = "1024";
};
new GuiTextEditCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiTextEditProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "97 35";
Extent = "66 18";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Variable = "$TPPHeightMin";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
maxLength = "1024";
historySize = "0";
password = "0";
tabComplete = "0";
sinkAllKeyEvents = "0";
passwordMask = "*";
};
new GuiTextEditCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiTextEditProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "97 60";
Extent = "66 18";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Variable = "$TPPHeightMax";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
maxLength = "1024";
historySize = "0";
password = "0";
tabComplete = "0";
sinkAllKeyEvents = "0";
passwordMask = "*";
};
new GuiTextCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiTextProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "15 101";
Extent = "33 13";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "SLOPE";
maxLength = "1024";
};
new GuiTextCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiTextProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "59 101";
Extent = "23 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Min.";
maxLength = "1024";
};
new GuiTextCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "ToolsGuiTextProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "59 126";
Extent = "23 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Max.";
maxLength = "1024";
};
new GuiTextEditCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "ToolsGuiTextEditProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "97 99";
Extent = "66 18";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Variable = "$TPPSlopeMin";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
maxLength = "1024";
historySize = "0";
password = "0";
tabComplete = "0";
sinkAllKeyEvents = "0";
passwordMask = "*";
};
new GuiTextEditCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "ToolsGuiTextEditProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "97 124";
Extent = "66 18";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Variable = "$TPPSlopeMax";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
maxLength = "1024";
historySize = "0";
password = "0";
tabComplete = "0";
sinkAllKeyEvents = "0";
passwordMask = "*";
};
};
};
//--- OBJECT WRITE END ---
$TPPHeightMin = -10000;
$TPPHeightMax = 10000;
$TPPSlopeMin = 0;
$TPPSlopeMax = 90;
function autoLayers()
{
Canvas.pushDialog(ProceduralTerrainPainterGui);
}
function generateProceduralTerrainMask()
{
Canvas.popDialog(ProceduralTerrainPainterGui);
ETerrainEditor.autoMaterialLayer($TPPHeightMin, $TPPHeightMax, $TPPSlopeMin, $TPPSlopeMax);
}

View file

@ -224,6 +224,26 @@
text = "None";
maxLength = "1024";
};
new GuiButtonCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiButtonProfile";
HorizSizing = "left";
VertSizing = "bottom";
Position = "100 229";
Extent = "50 18";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "autoLayers();";
tooltipprofile = "ToolsGuiToolTipProfile";
tooltip = "Generate a layer mask for this material.";
hovertime = "1000";
text = "AutoPaint";
groupNum = "-1";
buttonType = "PushButton";
useMouseEvents = "0";
};
};
};
//--- OBJECT WRITE END ---

View file

@ -43,6 +43,7 @@ function initializeWorldEditor()
exec("./gui/TimeAdjustGui.ed.gui");
exec("./gui/AddFMODProjectDlg.ed.gui");
exec("./gui/SelectObjectsWindow.ed.gui");
exec("./gui/ProceduralTerrainPainterGui.gui" );
// Load Scripts.
exec("./scripts/menus.ed.cs");

View file

@ -64,6 +64,7 @@ function TerrainEditor::setPaintMaterial( %this, %matIndex, %terrainMat )
ETerrainMaterialSelected.bitmap = %terrainMat.diffuseMap;
ETerrainMaterialSelectedEdit.Visible = isObject(%terrainMat);
TerrainTextureText.text = %terrainMat.getInternalName();
ProceduralTerrainPainterDescription.text = "Generate "@ %terrainMat.getInternalName() @" layer";
}
function TerrainEditor::setup( %this )

View file

@ -0,0 +1,326 @@
//--- OBJECT WRITE BEGIN ---
%guiContent = new GuiControl(ProceduralTerrainPainterGui) {
canSaveDynamicFields = "0";
isContainer = "1";
Profile = "ToolsGuiDefaultProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "0 0";
Extent = "1024 768";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
new GuiWindowCtrl(ProceduralTerrainPainterDescription) {
canSaveDynamicFields = "0";
isContainer = "1";
Profile = "ToolsGuiWindowProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "285 83";
Extent = "175 209";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
resizeWidth = "0";
resizeHeight = "0";
canMove = "1";
canClose = "1";
canMinimize = "0";
canMaximize = "0";
minSize = "50 50";
EdgeSnap = "1";
canCollapse = "0";
CollapseGroup = "-1";
CollapseGroupNum = "-1";
closeCommand = "Canvas.popDialog(ProceduralTerrainPainterGui);";
text = "Generate layer mask";
new GuiButtonCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "ToolsGuiButtonProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "19 164";
Extent = "140 30";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "generateProceduralTerrainMask();";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
text = "Generate";
groupNum = "-1";
buttonType = "PushButton";
useMouseEvents = "0";
};
new GuiTextCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiTextProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "15 37";
Extent = "33 13";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "HEIGHT";
maxLength = "1024";
};
new GuiTextCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiTextProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "59 37";
Extent = "23 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Min.";
maxLength = "1024";
};
new GuiTextCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiTextProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "59 62";
Extent = "23 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Max.";
maxLength = "1024";
};
new GuiTextEditCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiTextEditProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "97 35";
Extent = "66 18";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Variable = "$TPPHeightMin";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
maxLength = "1024";
historySize = "0";
password = "0";
tabComplete = "0";
sinkAllKeyEvents = "0";
passwordMask = "*";
};
new GuiTextEditCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiTextEditProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "97 60";
Extent = "66 18";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Variable = "$TPPHeightMax";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
maxLength = "1024";
historySize = "0";
password = "0";
tabComplete = "0";
sinkAllKeyEvents = "0";
passwordMask = "*";
};
new GuiTextCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiTextProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "15 101";
Extent = "33 13";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "SLOPE";
maxLength = "1024";
};
new GuiTextCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiTextProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "59 101";
Extent = "23 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Min.";
maxLength = "1024";
};
new GuiTextCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "ToolsGuiTextProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "59 126";
Extent = "23 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Max.";
maxLength = "1024";
};
new GuiTextEditCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "ToolsGuiTextEditProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "97 99";
Extent = "66 18";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Variable = "$TPPSlopeMin";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
maxLength = "1024";
historySize = "0";
password = "0";
tabComplete = "0";
sinkAllKeyEvents = "0";
passwordMask = "*";
};
new GuiTextEditCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "ToolsGuiTextEditProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "97 124";
Extent = "66 18";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Variable = "$TPPSlopeMax";
tooltipprofile = "ToolsGuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
maxLength = "1024";
historySize = "0";
password = "0";
tabComplete = "0";
sinkAllKeyEvents = "0";
passwordMask = "*";
};
};
};
//--- OBJECT WRITE END ---
$TPPHeightMin = -10000;
$TPPHeightMax = 10000;
$TPPSlopeMin = 0;
$TPPSlopeMax = 90;
function autoLayers()
{
Canvas.pushDialog(ProceduralTerrainPainterGui);
}
function generateProceduralTerrainMask()
{
Canvas.popDialog(ProceduralTerrainPainterGui);
ETerrainEditor.autoMaterialLayer($TPPHeightMin, $TPPHeightMax, $TPPSlopeMin, $TPPSlopeMax);
}

View file

@ -224,6 +224,26 @@
text = "None";
maxLength = "1024";
};
new GuiButtonCtrl() {
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiButtonProfile";
HorizSizing = "left";
VertSizing = "bottom";
Position = "100 229";
Extent = "50 18";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "autoLayers();";
tooltipprofile = "ToolsGuiToolTipProfile";
tooltip = "Generate a layer mask for this material.";
hovertime = "1000";
text = "AutoPaint";
groupNum = "-1";
buttonType = "PushButton";
useMouseEvents = "0";
};
};
};
//--- OBJECT WRITE END ---

View file

@ -43,6 +43,7 @@ function initializeWorldEditor()
exec("./gui/TimeAdjustGui.ed.gui");
exec("./gui/AddFMODProjectDlg.ed.gui");
exec("./gui/SelectObjectsWindow.ed.gui");
exec("./gui/ProceduralTerrainPainterGui.gui" );
// Load Scripts.
exec("./scripts/menus.ed.cs");

View file

@ -64,6 +64,7 @@ function TerrainEditor::setPaintMaterial( %this, %matIndex, %terrainMat )
ETerrainMaterialSelected.bitmap = %terrainMat.diffuseMap;
ETerrainMaterialSelectedEdit.Visible = isObject(%terrainMat);
TerrainTextureText.text = %terrainMat.getInternalName();
ProceduralTerrainPainterDescription.text = "Generate "@ %terrainMat.getInternalName() @" layer";
}
function TerrainEditor::setup( %this )