Browse Source

terrain tool changes and improvements, thanks @Shirkit

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9681 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
bre..ns 13 years ago
parent
commit
b5c4b2ccd4

+ 13 - 4
jme3-terrain-editor/src/com/jme3/gde/terraineditor/Bundle.properties

@@ -121,10 +121,19 @@ CreateTerrainVisualPanel2.jLabel7.text=Height Scale:
 CreateTerrainVisualPanel2.heightScale.text=1
 TerrainEditorTopComponent.toolHint.slope=Right click to set the markers position. A simple right click set the first marker, holding ctrl sets the second marker. Hold the Left button to apply the slope in the area you are hovering.
 TerrainEditorTopComponent.jLabel6.text=
-TerrainEditorTopComponent.levelPrecisionCheckbox.text=Precision
-TerrainEditorTopComponent.levelAbsoluteCheckbox.text=Absolute
 TerrainEditorTopComponent.levelAbsoluteHeightField.text=0
-TerrainEditorTopComponent.slopePrecisionCheckbox.text=Precision
 TerrainEditorTopComponent.slopeTerrainButton.toolTipText=Slope terrain
 TerrainEditorTopComponent.slopeTerrainButton.text=
-TerrainEditorTopComponent.slopeLockCheckbox.text=Lock
+TerrainEditorTopComponent.slopeLockCheckbox.text=Contain
+TerrainEditorTopComponent.jLabel7.text=
+TerrainEditorTopComponent.borderDistanceField.text=0
+TerrainEditorTopComponent.borderHeightField.text=0
+TerrainEditorTopComponent.PrecisionCheckbox.text=Snap
+TerrainEditorTopComponent.PrecisionCheckbox.tooltip=Snap directly to the defined height, instead of smoothly adjusting
+TerrainEditorTopComponent.AbsoluteCheckbox.text=Absolute
+TerrainEditorTopComponent.AbsoluteCheckbox.tooltip=Define the height to adjust to, instead of using the marker
+TerrainEditorTopComponent.slopeLockCheckbox.tooltip=Contains the slope between the two slope nodes
+TerrainEditorTopComponent.borderDistanceLabel.text=Distance
+TerrainEditorTopComponent.borderHeightLAbel.text=Height
+TerrainEditorTopComponent.borderDistanceLabel.tooltip=Distance means how far from the terrain's edge the border will be raised (thickness of the border).
+TerrainEditorTopComponent.borderHeightLAbel.tooltip=Height means how high the border will go (also accept negative values).

+ 106 - 31
jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorTopComponent.form

@@ -39,7 +39,10 @@
         <Component class="javax.swing.JCheckBox" name="levelPrecisionCheckbox">
           <Properties>
             <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.levelPrecisionCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.PrecisionCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.PrecisionCheckbox.tooltip" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
             </Property>
           </Properties>
           <Events>
@@ -56,7 +59,10 @@
         <Component class="javax.swing.JCheckBox" name="levelAbsoluteCheckbox">
           <Properties>
             <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.levelAbsoluteCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.AbsoluteCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.AbsoluteCheckbox.tooltip" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
             </Property>
           </Properties>
           <Events>
@@ -181,7 +187,10 @@
         <Component class="javax.swing.JCheckBox" name="slopePrecisionCheckbox">
           <Properties>
             <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.slopePrecisionCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.PrecisionCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.PrecisionCheckbox.tooltip" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
             </Property>
           </Properties>
           <Events>
@@ -193,6 +202,9 @@
             <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
               <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.slopeLockCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
             </Property>
+            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.slopeLockCheckbox.tooltip" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
           </Properties>
           <Events>
             <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="slopeLockCheckboxActionPerformed"/>
@@ -200,6 +212,93 @@
         </Component>
       </SubComponents>
     </Container>
+    <Container class="javax.swing.JPanel" name="borderBrushPanel">
+      <Properties>
+        <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
+          <Color blue="cc" green="cc" red="cc" type="rgb"/>
+        </Property>
+        <Property name="opaque" type="boolean" value="false"/>
+      </Properties>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout">
+        <Property name="columns" type="int" value="2"/>
+        <Property name="rows" type="int" value="3"/>
+      </Layout>
+      <SubComponents>
+        <Component class="javax.swing.JCheckBox" name="borderPrecisionCheckbox">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.PrecisionCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.PrecisionCheckbox.tooltip" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="borderPrecisionCheckboxActionPerformed"/>
+          </Events>
+        </Component>
+        <Component class="javax.swing.JLabel" name="jLabel7">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.jLabel7.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="borderDistanceLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.borderDistanceLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.borderDistanceLabel.tooltip" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JFormattedTextField" name="borderDistanceField">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.borderDistanceField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.borderDistanceLabel.tooltip" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="keyTyped" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="borderDistanceFieldKeyTyped"/>
+          </Events>
+          <AuxValues>
+            <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JFormattedTextField(NumberFormat.getInstance())"/>
+          </AuxValues>
+        </Component>
+        <Component class="javax.swing.JLabel" name="borderHeightLAbel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.borderHeightLAbel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.borderHeightLAbel.tooltip" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JFormattedTextField" name="borderHeightField">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.borderHeightField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/terraineditor/Bundle.properties" key="TerrainEditorTopComponent.borderHeightLAbel.tooltip" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="keyTyped" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="borderHeightFieldKeyTyped"/>
+          </Events>
+          <AuxValues>
+            <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JFormattedTextField(NumberFormat.getInstance())"/>
+          </AuxValues>
+        </Component>
+      </SubComponents>
+    </Container>
   </NonVisualComponents>
   <Properties>
     <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
@@ -241,8 +340,8 @@
               <Group type="103" groupAlignment="1" attributes="0">
                   <Component id="hintPanel" max="32767" attributes="1"/>
                   <Component id="paintingPanel" alignment="0" max="32767" attributes="1"/>
-                  <Component id="toolSettingsPanel" alignment="0" pref="128" max="32767" attributes="1"/>
-                  <Component id="jPanel2" pref="128" max="32767" attributes="1"/>
+                  <Component id="toolSettingsPanel" alignment="0" pref="132" max="32767" attributes="1"/>
+                  <Component id="jPanel2" pref="132" max="32767" attributes="1"/>
               </Group>
           </Group>
       </Group>
@@ -537,30 +636,6 @@
             <EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="heightSliderStateChanged"/>
           </Events>
         </Component>
-        <Container class="javax.swing.JPanel" name="jPanel3">
-          <Properties>
-            <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
-              <Color blue="cc" green="cc" red="cc" type="rgb"/>
-            </Property>
-            <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
-              <Color blue="f0" green="f0" red="f0" type="rgb"/>
-            </Property>
-            <Property name="opaque" type="boolean" value="false"/>
-          </Properties>
-
-          <Layout>
-            <DimensionLayout dim="0">
-              <Group type="103" groupAlignment="0" attributes="0">
-                  <EmptySpace min="0" pref="148" max="32767" attributes="0"/>
-              </Group>
-            </DimensionLayout>
-            <DimensionLayout dim="1">
-              <Group type="103" groupAlignment="0" attributes="0">
-                  <EmptySpace min="0" pref="25" max="32767" attributes="0"/>
-              </Group>
-            </DimensionLayout>
-          </Layout>
-        </Container>
       </SubComponents>
     </Container>
     <Container class="javax.swing.JPanel" name="toolSettingsPanel">
@@ -613,7 +688,7 @@
         <DimensionLayout dim="1">
           <Group type="103" groupAlignment="0" attributes="0">
               <Group type="102" alignment="1" attributes="0">
-                  <Component id="jScrollPane2" pref="81" max="32767" attributes="0"/>
+                  <Component id="jScrollPane2" pref="85" max="32767" attributes="0"/>
                   <EmptySpace max="-2" attributes="0"/>
                   <Group type="103" groupAlignment="3" attributes="0">
                       <Component id="remainingTexTitleLabel" alignment="3" min="-2" max="-2" attributes="0"/>
@@ -786,7 +861,7 @@
         </DimensionLayout>
         <DimensionLayout dim="1">
           <Group type="103" groupAlignment="0" attributes="0">
-              <Component id="jScrollPane1" alignment="0" pref="101" max="32767" attributes="0"/>
+              <Component id="jScrollPane1" alignment="0" pref="105" max="32767" attributes="0"/>
           </Group>
         </DimensionLayout>
       </Layout>

+ 104 - 35
jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorTopComponent.java

@@ -240,6 +240,13 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         slopeBrushPanel = new javax.swing.JPanel();
         slopePrecisionCheckbox = new javax.swing.JCheckBox();
         slopeLockCheckbox = new javax.swing.JCheckBox();
+        borderBrushPanel = new javax.swing.JPanel();
+        borderPrecisionCheckbox = new javax.swing.JCheckBox();
+        jLabel7 = new javax.swing.JLabel();
+        borderDistanceLabel = new javax.swing.JLabel();
+        borderDistanceField = new javax.swing.JFormattedTextField(NumberFormat.getInstance());
+        borderHeightLAbel = new javax.swing.JLabel();
+        borderHeightField = new javax.swing.JFormattedTextField(NumberFormat.getInstance());
         jToolBar1 = new javax.swing.JToolBar();
         createTerrainButton = new javax.swing.JButton();
         jSeparator1 = new javax.swing.JToolBar.Separator();
@@ -259,7 +266,6 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         radiusSlider = new javax.swing.JSlider();
         heightLabel = new javax.swing.JLabel();
         heightSlider = new javax.swing.JSlider();
-        jPanel3 = new javax.swing.JPanel();
         toolSettingsPanel = new javax.swing.JPanel();
         paintingPanel = new javax.swing.JPanel();
         jScrollPane2 = new javax.swing.JScrollPane();
@@ -284,7 +290,8 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         levelBrushPanel.setOpaque(false);
         levelBrushPanel.setLayout(new java.awt.GridLayout(3, 2));
 
-        org.openide.awt.Mnemonics.setLocalizedText(levelPrecisionCheckbox, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.levelPrecisionCheckbox.text")); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(levelPrecisionCheckbox, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.PrecisionCheckbox.text")); // NOI18N
+        levelPrecisionCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.PrecisionCheckbox.tooltip")); // NOI18N
         levelPrecisionCheckbox.addActionListener(new java.awt.event.ActionListener() {
             public void actionPerformed(java.awt.event.ActionEvent evt) {
                 levelPrecisionCheckboxActionPerformed(evt);
@@ -295,7 +302,8 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         org.openide.awt.Mnemonics.setLocalizedText(jLabel6, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.jLabel6.text")); // NOI18N
         levelBrushPanel.add(jLabel6);
 
-        org.openide.awt.Mnemonics.setLocalizedText(levelAbsoluteCheckbox, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.levelAbsoluteCheckbox.text")); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(levelAbsoluteCheckbox, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.AbsoluteCheckbox.text")); // NOI18N
+        levelAbsoluteCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.AbsoluteCheckbox.tooltip")); // NOI18N
         levelAbsoluteCheckbox.addActionListener(new java.awt.event.ActionListener() {
             public void actionPerformed(java.awt.event.ActionEvent evt) {
                 levelAbsoluteCheckboxActionPerformed(evt);
@@ -373,7 +381,8 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         slopeBrushPanel.setOpaque(false);
         slopeBrushPanel.setLayout(new java.awt.GridLayout(3, 2));
 
-        org.openide.awt.Mnemonics.setLocalizedText(slopePrecisionCheckbox, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.slopePrecisionCheckbox.text")); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(slopePrecisionCheckbox, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.PrecisionCheckbox.text")); // NOI18N
+        slopePrecisionCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.PrecisionCheckbox.tooltip")); // NOI18N
         slopePrecisionCheckbox.addActionListener(new java.awt.event.ActionListener() {
             public void actionPerformed(java.awt.event.ActionEvent evt) {
                 slopePrecisionCheckboxActionPerformed(evt);
@@ -382,6 +391,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         slopeBrushPanel.add(slopePrecisionCheckbox);
 
         org.openide.awt.Mnemonics.setLocalizedText(slopeLockCheckbox, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.slopeLockCheckbox.text")); // NOI18N
+        slopeLockCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.slopeLockCheckbox.tooltip")); // NOI18N
         slopeLockCheckbox.addActionListener(new java.awt.event.ActionListener() {
             public void actionPerformed(java.awt.event.ActionEvent evt) {
                 slopeLockCheckboxActionPerformed(evt);
@@ -389,6 +399,48 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         });
         slopeBrushPanel.add(slopeLockCheckbox);
 
+        borderBrushPanel.setBackground(new java.awt.Color(204, 204, 204));
+        borderBrushPanel.setOpaque(false);
+        borderBrushPanel.setLayout(new java.awt.GridLayout(3, 2));
+
+        org.openide.awt.Mnemonics.setLocalizedText(borderPrecisionCheckbox, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.PrecisionCheckbox.text")); // NOI18N
+        borderPrecisionCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.PrecisionCheckbox.tooltip")); // NOI18N
+        borderPrecisionCheckbox.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                borderPrecisionCheckboxActionPerformed(evt);
+            }
+        });
+        borderBrushPanel.add(borderPrecisionCheckbox);
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel7, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.jLabel7.text")); // NOI18N
+        borderBrushPanel.add(jLabel7);
+
+        org.openide.awt.Mnemonics.setLocalizedText(borderDistanceLabel, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.borderDistanceLabel.text")); // NOI18N
+        borderDistanceLabel.setToolTipText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.borderDistanceLabel.tooltip")); // NOI18N
+        borderBrushPanel.add(borderDistanceLabel);
+
+        borderDistanceField.setText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.borderDistanceField.text")); // NOI18N
+        borderDistanceField.setToolTipText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.borderDistanceLabel.tooltip")); // NOI18N
+        borderDistanceField.addKeyListener(new java.awt.event.KeyAdapter() {
+            public void keyTyped(java.awt.event.KeyEvent evt) {
+                borderDistanceFieldKeyTyped(evt);
+            }
+        });
+        borderBrushPanel.add(borderDistanceField);
+
+        org.openide.awt.Mnemonics.setLocalizedText(borderHeightLAbel, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.borderHeightLAbel.text")); // NOI18N
+        borderHeightLAbel.setToolTipText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.borderHeightLAbel.tooltip")); // NOI18N
+        borderBrushPanel.add(borderHeightLAbel);
+
+        borderHeightField.setText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.borderHeightField.text")); // NOI18N
+        borderHeightField.setToolTipText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.borderHeightLAbel.tooltip")); // NOI18N
+        borderHeightField.addKeyListener(new java.awt.event.KeyAdapter() {
+            public void keyTyped(java.awt.event.KeyEvent evt) {
+                borderHeightFieldKeyTyped(evt);
+            }
+        });
+        borderBrushPanel.add(borderHeightField);
+
         setBackground(java.awt.Color.gray);
 
         jToolBar1.setBackground(new java.awt.Color(204, 204, 204));
@@ -569,23 +621,6 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         });
         jToolBar1.add(heightSlider);
 
-        jPanel3.setBackground(new java.awt.Color(204, 204, 204));
-        jPanel3.setForeground(new java.awt.Color(240, 240, 240));
-        jPanel3.setOpaque(false);
-
-        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
-        jPanel3.setLayout(jPanel3Layout);
-        jPanel3Layout.setHorizontalGroup(
-            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGap(0, 148, Short.MAX_VALUE)
-        );
-        jPanel3Layout.setVerticalGroup(
-            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGap(0, 25, Short.MAX_VALUE)
-        );
-
-        jToolBar1.add(jPanel3);
-
         toolSettingsPanel.setBackground(new java.awt.Color(204, 204, 204));
         toolSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.toolSettingsPanel.border.title"))); // NOI18N
         toolSettingsPanel.setOpaque(false);
@@ -622,7 +657,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         paintingPanelLayout.setVerticalGroup(
             paintingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
             .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, paintingPanelLayout.createSequentialGroup()
-                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 81, Short.MAX_VALUE)
+                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE)
                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                 .addGroup(paintingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                     .addComponent(remainingTexTitleLabel)
@@ -710,7 +745,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         );
         hintPanelLayout.setVerticalGroup(
             hintPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)
+            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE)
         );
 
         javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
@@ -735,8 +770,8 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                     .addComponent(hintPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                     .addComponent(paintingPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                    .addComponent(toolSettingsPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 128, Short.MAX_VALUE)
-                    .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, 128, Short.MAX_VALUE)))
+                    .addComponent(toolSettingsPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 132, Short.MAX_VALUE)
+                    .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, 132, Short.MAX_VALUE)))
         );
     }// </editor-fold>//GEN-END:initComponents
 
@@ -950,10 +985,6 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         updateLevelToolParams();
     }//GEN-LAST:event_levelAbsoluteHeightFieldKeyTyped
 
-    private void levelAbsoluteCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_levelAbsoluteCheckboxActionPerformed
-        updateLevelToolParams();
-    }//GEN-LAST:event_levelAbsoluteCheckboxActionPerformed
-
     private void slopePrecisionCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_slopePrecisionCheckboxActionPerformed
         updateSlopeToolParams();
     }//GEN-LAST:event_slopePrecisionCheckboxActionPerformed
@@ -962,8 +993,31 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
         updateSlopeToolParams();
     }//GEN-LAST:event_slopeLockCheckboxActionPerformed
 
+    private void levelAbsoluteCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_levelAbsoluteCheckboxActionPerformed
+        updateLevelToolParams();
+        levelAbsoluteHeightField.setEnabled(levelAbsoluteCheckbox.isEnabled());
+    }//GEN-LAST:event_levelAbsoluteCheckboxActionPerformed
+
+    private void borderPrecisionCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_borderPrecisionCheckboxActionPerformed
+        updateBorderToolParams();
+    }//GEN-LAST:event_borderPrecisionCheckboxActionPerformed
+
+    private void borderDistanceFieldKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_borderDistanceFieldKeyTyped
+        updateBorderToolParams();
+    }//GEN-LAST:event_borderDistanceFieldKeyTyped
+
+    private void borderHeightFieldKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_borderHeightFieldKeyTyped
+        updateBorderToolParams();
+    }//GEN-LAST:event_borderHeightFieldKeyTyped
+
     // Variables declaration - do not modify//GEN-BEGIN:variables
     private javax.swing.JButton addTextureButton;
+    private javax.swing.JPanel borderBrushPanel;
+    private javax.swing.JFormattedTextField borderDistanceField;
+    private javax.swing.JLabel borderDistanceLabel;
+    private javax.swing.JFormattedTextField borderHeightField;
+    private javax.swing.JLabel borderHeightLAbel;
+    private javax.swing.JCheckBox borderPrecisionCheckbox;
     private javax.swing.JButton createTerrainButton;
     private javax.swing.JToggleButton eraseButton;
     private javax.swing.JPanel fractalBrushPanel;
@@ -975,8 +1029,8 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
     private javax.swing.JLabel jLabel3;
     private javax.swing.JLabel jLabel4;
     private javax.swing.JLabel jLabel6;
+    private javax.swing.JLabel jLabel7;
     private javax.swing.JPanel jPanel2;
-    private javax.swing.JPanel jPanel3;
     private javax.swing.JScrollPane jScrollPane1;
     private javax.swing.JScrollPane jScrollPane2;
     private javax.swing.JToolBar.Separator jSeparator1;
@@ -1062,11 +1116,23 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
     }
     
     private void updateLevelToolParams() {
-        LevelExtraToolParams params = new LevelExtraToolParams();
-        params.absolute = levelAbsoluteCheckbox.isSelected();
-        params.precision = levelPrecisionCheckbox.isSelected();
-        params.height = new Float(levelAbsoluteHeightField.getText());
-        toolController.setExtraToolParams(params);
+        try {
+            LevelExtraToolParams params = new LevelExtraToolParams();
+            params.absolute = levelAbsoluteCheckbox.isSelected();
+            params.precision = levelPrecisionCheckbox.isSelected();
+            params.height = new Float(levelAbsoluteHeightField.getText());
+            toolController.setExtraToolParams(params);
+        } catch (NumberFormatException e) {}
+    }
+    
+    private void updateBorderToolParams() {
+        try {
+            BorderExtraToolParams params = new BorderExtraToolParams();
+            params.precision = borderPrecisionCheckbox.isSelected();
+            params.height = new Float(borderHeightField.getText());
+            params.distance = new Float(borderDistanceField.getText());
+            toolController.setExtraToolParams(params);
+        } catch (NumberFormatException e) {}
     }
     
     private void updateRoughenFractalToolParams() {
@@ -1091,6 +1157,8 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
                 updateLevelToolParams();
             else if (toolController.getCurrentTerrainTool().getClass() == SlopeTerrainTool.class)
                 updateSlopeToolParams();
+            else if (toolController.getCurrentTerrainTool().getClass() == BorderTerrainTool.class)
+                updateBorderToolParams();
         }
     }
     
@@ -1424,6 +1492,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
 
             toolController.setHeightToolRadius((float) radiusSlider.getValue() / (float) radiusSlider.getMaximum());
             toolController.setHeightToolHeight((float) heightSlider.getValue() / (float) heightSlider.getMaximum());
+            //toolController.setToolMesh(meshForm.isSelected()); // future for adding brush shape
 
             editorController.setTerrainLodCamera();
 

+ 26 - 0
jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainToolController.java

@@ -62,6 +62,7 @@ public class TerrainToolController extends SceneToolController {
     private float toolRadius;
     private float toolWeight;
     private int selectedTextureIndex = -1;
+    private boolean mesh = false;
     
 
     public TerrainToolController(Node toolsNode, AssetManager manager, JmeNode rootNode) {
@@ -97,6 +98,11 @@ public class TerrainToolController extends SceneToolController {
         this.toolRadius = radius;
         setEditToolSize(radius);
     }
+    
+    public void setToolMesh(boolean mesh) {
+        this.mesh = mesh;
+        setEditToolMesh(this.mesh);
+    }
 
     public void setSelectedTextureIndex(int index) {
         this.selectedTextureIndex = index;
@@ -145,6 +151,26 @@ public class TerrainToolController extends SceneToolController {
             }
         });
     }
+    
+    public void setEditToolMesh(final boolean mesh) {
+        SceneApplication.getApplication().enqueue(new Callable<Object>() {
+
+            public Object call() throws Exception {
+                doSetEditToolMesh(mesh);
+                return null;
+            }
+        });
+        
+    }
+    
+    public void doSetEditToolMesh(boolean mesh) {
+        if (terrainTool != null) {
+            if(mesh)
+                terrainTool.setMesh(TerrainTool.Meshes.Box);
+            else
+                terrainTool.setMesh(TerrainTool.Meshes.Sphere);
+        }
+    }
 
     private void doSetEditToolSize(float size) {
         if (terrainTool != null)

+ 1 - 1
jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/LevelTerrainTool.java

@@ -69,7 +69,7 @@ public class LevelTerrainTool extends TerrainTool {
             desiredHeight = point.clone();
         if (toolParams.absolute)
             desiredHeight.y = toolParams.height;
-        LevelTerrainToolAction action = new LevelTerrainToolAction(point, radius, weight, desiredHeight, toolParams.precision);
+        LevelTerrainToolAction action = new LevelTerrainToolAction(point, radius, weight, desiredHeight, toolParams.precision, getMesh());
         action.doActionPerformed(rootNode, dataObject);
     }
 

+ 44 - 38
jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/LevelTerrainToolAction.java

@@ -32,6 +32,7 @@
 package com.jme3.gde.terraineditor.tools;
 
 import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode;
+import com.jme3.gde.terraineditor.tools.TerrainTool.Meshes;
 import com.jme3.math.Vector2f;
 import com.jme3.math.Vector3f;
 import com.jme3.scene.Node;
@@ -49,21 +50,23 @@ import java.util.List;
  */
 public class LevelTerrainToolAction extends AbstractTerrainToolAction {
     
-    private Vector3f worldLoc;
-    private float radius;
-    private float height;
-    private Vector3f levelTerrainLocation;
-    private boolean precision;
+    private final Vector3f worldLoc;
+    private final float radius;
+    private final float height;
+    private final Vector3f levelTerrainLocation;
+    private final boolean precision;
+    private final Meshes mesh;
     
-    List<Vector2f> undoLocs;
-    List<Float> undoHeights;
+    private List<Vector2f> undoLocs;
+    private List<Float> undoHeights;
 
-    public LevelTerrainToolAction(Vector3f markerLocation, float radius, float height, Vector3f levelTerrainLocation, boolean precision) {
+    public LevelTerrainToolAction(Vector3f markerLocation, float radius, float height, Vector3f levelTerrainLocation, boolean precision, Meshes mesh) {
         this.worldLoc = markerLocation.clone();
         this.radius = radius;
         this.height = height;
         this.levelTerrainLocation = levelTerrainLocation;
         this.precision = precision;
+        this.mesh = mesh;
         name = "Level terrain";
     }
 
@@ -72,7 +75,7 @@ public class LevelTerrainToolAction extends AbstractTerrainToolAction {
         Terrain terrain = getTerrain(rootNode.getLookup().lookup(Node.class));
         if (terrain == null)
             return null;
-        modifyHeight(terrain, radius, height, precision);
+        modifyHeight(terrain, levelTerrainLocation, worldLoc, radius, height, precision, mesh);
         return terrain;
     }
     
@@ -85,11 +88,11 @@ public class LevelTerrainToolAction extends AbstractTerrainToolAction {
         resetHeight((Terrain)undoObject, undoLocs, undoHeights, precision);
     }
 
-    private void modifyHeight(Terrain terrain, float radius, float height, boolean precision) {
-        if (levelTerrainLocation == null)
+    private void modifyHeight(Terrain terrain, Vector3f level, Vector3f worldLoc, float radius, float height, boolean precision, Meshes mesh) {
+        if (level == null)
             return;
 
-        float desiredHeight = levelTerrainLocation.y;
+        float desiredHeight = level.y;
 
         int radiusStepsX = (int)(radius / ((Node)terrain).getLocalScale().x);
         int radiusStepsZ = (int)(radius / ((Node)terrain).getLocalScale().z);
@@ -102,44 +105,47 @@ public class LevelTerrainToolAction extends AbstractTerrainToolAction {
         undoHeights = new ArrayList<Float>();
 
         for (int z=-radiusStepsZ; z<radiusStepsZ; z++) {
-            for (int x=-radiusStepsZ; x<radiusStepsX; x++) {
+            for (int x=-radiusStepsX; x<radiusStepsX; x++) {
 
                 float locX = worldLoc.x + (x*xStepAmount);
                 float locZ = worldLoc.z + (z*zStepAmount);
                 
                 // see if it is in the radius of the tool
-                if (ToolUtils.isInRadius(locX-worldLoc.x,locZ-worldLoc.z,radius)) {
+                if (ToolUtils.isInMesh(locX-worldLoc.x,locZ-worldLoc.z,radius, mesh)) {
 
                     Vector2f terrainLoc = new Vector2f(locX, locZ);
                     // adjust height based on radius of the tool
                     float terrainHeightAtLoc = terrain.getHeightmapHeight(terrainLoc)*((Node)terrain).getWorldScale().y;
-                    float radiusWeight = ToolUtils.calculateRadiusPercent(radius, locX-worldLoc.x, locZ-worldLoc.z);
-
-                    float epsilon = 0.1f*height; // rounding error for snapping
+                    if (precision) {
+                        locs.add(terrainLoc);
+                        heights.add(desiredHeight / ((Node) terrain).getLocalScale().y);
+                        undoHeights.add(terrainHeightAtLoc / ((Node) terrain).getLocalScale().y);
+                    } else {
+                        float epsilon = 0.1f*height; // rounding error for snapping
                     
-                    float adj = 0;
-                    if (terrainHeightAtLoc < desiredHeight)
-                        adj = 1;
-                    else if (terrainHeightAtLoc > desiredHeight)
-                        adj = -1;
-                            
-                    adj *= radiusWeight * height;
-
-                    // test if adjusting too far and then cap it
-                    if (adj > 0 && ToolUtils.floatGreaterThan((terrainHeightAtLoc + adj), desiredHeight, epsilon))
-                        adj = desiredHeight - terrainHeightAtLoc;
-                    else if (adj < 0 && ToolUtils.floatLessThan((terrainHeightAtLoc + adj), desiredHeight, epsilon))
-                        adj = terrainHeightAtLoc - desiredHeight;
+                        float adj = 0;
+                        if (terrainHeightAtLoc < desiredHeight)
+                            adj = 1;
+                        else if (terrainHeightAtLoc > desiredHeight)
+                            adj = -1;
+                        
+                        adj *= height;
+                        
+                        if (mesh.equals(Meshes.Sphere))
+                            adj *= ToolUtils.calculateRadiusPercent(radius, locX-worldLoc.x, locZ-worldLoc.z);
+
+                        // test if adjusting too far and then cap it
+                        if (adj > 0 && ToolUtils.floatGreaterThan((terrainHeightAtLoc + adj), desiredHeight, epsilon))
+                            adj = desiredHeight - terrainHeightAtLoc;
+                        else if (adj < 0 && ToolUtils.floatLessThan((terrainHeightAtLoc + adj), desiredHeight, epsilon))
+                            adj = terrainHeightAtLoc - desiredHeight;
   
-                    if (!ToolUtils.floatEquals(adj, 0, 0.001f)) {
-                        locs.add(terrainLoc);
-                        if (precision) {
-                            heights.add(desiredHeight);
-                            undoHeights.add(terrainHeightAtLoc);
-                        } else
-                            heights.add(adj);
-                    }
+                        if (!ToolUtils.floatEquals(adj, 0, 0.001f)) {
+                                locs.add(terrainLoc);
+                                heights.add(adj);
+                        }
                     
+                    }
                 }
             }
         }

+ 1 - 1
jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/LowerTerrainTool.java

@@ -48,7 +48,7 @@ public class LowerTerrainTool extends TerrainTool {
     public void actionPrimary(Vector3f point, int textureIndex, AbstractSceneExplorerNode rootNode, DataObject dataObject) {
         if (radius == 0 || weight == 0)
             return;
-        RaiseTerrainToolAction action = new RaiseTerrainToolAction(point, radius, -weight); // negative weight
+        RaiseTerrainToolAction action = new RaiseTerrainToolAction(point, radius, -weight, getMesh()); // negative weight
         action.doActionPerformed(rootNode, dataObject);
     }
 

+ 0 - 1
jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/PaintTerrainToolAction.java

@@ -38,7 +38,6 @@ import com.jme3.math.Vector2f;
 import com.jme3.math.Vector3f;
 import com.jme3.scene.Node;
 import com.jme3.terrain.Terrain;
-import com.jme3.terrain.geomipmap.TerrainQuad;
 import com.jme3.texture.Image;
 import com.jme3.texture.Texture;
 import java.nio.ByteBuffer;

+ 1 - 1
jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/RaiseTerrainTool.java

@@ -50,7 +50,7 @@ public class RaiseTerrainTool extends TerrainTool {
     public void actionPrimary(Vector3f point, int textureIndex, AbstractSceneExplorerNode rootNode, DataObject dataObject) {
         if (radius == 0 || weight == 0)
             return;
-        RaiseTerrainToolAction action = new RaiseTerrainToolAction(point, radius, weight);
+        RaiseTerrainToolAction action = new RaiseTerrainToolAction(point, radius, weight, getMesh());
         action.doActionPerformed(rootNode, dataObject);
     }
 

+ 9 - 6
jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/RaiseTerrainToolAction.java

@@ -33,6 +33,7 @@
 package com.jme3.gde.terraineditor.tools;
 
 import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode;
+import com.jme3.gde.terraineditor.tools.TerrainTool.Meshes;
 import com.jme3.math.Vector2f;
 import com.jme3.math.Vector3f;
 import com.jme3.scene.Node;
@@ -50,11 +51,13 @@ public class RaiseTerrainToolAction extends AbstractTerrainToolAction {
     private Vector3f worldLoc;
     private float radius;
     private float height;
+    private Meshes mesh;
 
-    public RaiseTerrainToolAction(Vector3f markerLocation, float radius, float height) {
+    public RaiseTerrainToolAction(Vector3f markerLocation, float radius, float height, Meshes mesh) {
         this.worldLoc = markerLocation.clone();
         this.radius = radius;
         this.height = height;
+        this.mesh = mesh;
         name = "Raise terrain";
     }
 
@@ -63,7 +66,7 @@ public class RaiseTerrainToolAction extends AbstractTerrainToolAction {
         Terrain terrain = getTerrain(rootNode.getLookup().lookup(Node.class));
         if (terrain == null)
             return null;
-        modifyHeight(terrain, radius, height);
+        modifyHeight(terrain, worldLoc, radius, height, mesh);
         return terrain;
     }
     
@@ -71,10 +74,10 @@ public class RaiseTerrainToolAction extends AbstractTerrainToolAction {
     protected void doUndoTool(AbstractSceneExplorerNode rootNode, Object undoObject) {
         if (undoObject == null)
             return;
-        modifyHeight((Terrain)undoObject, radius, -height);
+        modifyHeight((Terrain)undoObject, worldLoc, radius, -height, mesh);
     }
 
-    private void modifyHeight(Terrain terrain, float radius, float heightDir) {
+    private void modifyHeight(Terrain terrain, Vector3f worldLoc, float radius, float heightDir, Meshes mesh) {
 
         int radiusStepsX = (int) (radius / ((Node)terrain).getWorldScale().x);
         int radiusStepsZ = (int) (radius / ((Node)terrain).getWorldScale().z);
@@ -86,13 +89,13 @@ public class RaiseTerrainToolAction extends AbstractTerrainToolAction {
         List<Float> heights = new ArrayList<Float>();
         
         for (int z=-radiusStepsZ; z<radiusStepsZ; z++) {
-            for (int x=-radiusStepsZ; x<radiusStepsX; x++) {
+            for (int x=-radiusStepsX; x<radiusStepsX; x++) {
 
                 float locX = worldLoc.x + (x*xStepAmount);
                 float locZ = worldLoc.z + (z*zStepAmount);
 
                 // see if it is in the radius of the tool
-                if (ToolUtils.isInRadius(locX-worldLoc.x,locZ-worldLoc.z,radius)) {
+                if (ToolUtils.isInMesh(locX-worldLoc.x,locZ-worldLoc.z,radius,mesh)) {
                     // adjust height based on radius of the tool
                     float h = ToolUtils.calculateHeight(radius, heightDir, locX-worldLoc.x, locZ-worldLoc.z);
                     // increase the height

+ 1 - 1
jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SlopeTerrainTool.java

@@ -116,7 +116,7 @@ public class SlopeTerrainTool extends TerrainTool {
     @Override
     public void actionPrimary(Vector3f point, int textureIndex, AbstractSceneExplorerNode rootNode, DataObject dataObject) {
         if (point1 != null && point2 != null && point1.distance(point2) > 0.01f) { // Preventing unexpected behavior, like destroying the terrain
-            SlopeTerrainToolAction action = new SlopeTerrainToolAction(point, point1, point2, radius, weight, toolParams.precision, toolParams.lock);
+            SlopeTerrainToolAction action = new SlopeTerrainToolAction(point, point1, point2, radius, weight, toolParams.precision, toolParams.lock, getMesh());
             action.actionPerformed(rootNode, dataObject);
         }
     }

+ 21 - 18
jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SlopeTerrainToolAction.java

@@ -32,6 +32,7 @@
 package com.jme3.gde.terraineditor.tools;
 
 import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode;
+import com.jme3.gde.terraineditor.tools.TerrainTool.Meshes;
 import com.jme3.math.Plane;
 import com.jme3.math.Vector2f;
 import com.jme3.math.Vector3f;
@@ -55,8 +56,9 @@ public class SlopeTerrainToolAction extends AbstractTerrainToolAction {
     private List<Float> undoHeights;
     private final boolean precise;
     private final boolean lock;
+    private final Meshes mesh;
 
-    public SlopeTerrainToolAction(Vector3f current, Vector3f point1, Vector3f point2, float radius, float weight, boolean precise, boolean lock) {
+    public SlopeTerrainToolAction(Vector3f current, Vector3f point1, Vector3f point2, float radius, float weight, boolean precise, boolean lock, Meshes mesh) {
         this.current = current.clone();
         this.point1 = point1;
         this.point2 = point2;
@@ -64,6 +66,7 @@ public class SlopeTerrainToolAction extends AbstractTerrainToolAction {
         this.weight = weight;
         this.precise = precise;
         this.lock = lock;
+        this.mesh = mesh;
         name = "Slope terrain";
     }
 
@@ -73,7 +76,7 @@ public class SlopeTerrainToolAction extends AbstractTerrainToolAction {
         if (terrain == null)
             return null;
 
-        modifyHeight(terrain, point1, point2, current, radius, weight, precise, lock);
+        modifyHeight(terrain, point1, point2, current, radius, weight, precise, lock, mesh);
 
         return terrain;
     }
@@ -89,7 +92,7 @@ public class SlopeTerrainToolAction extends AbstractTerrainToolAction {
         resetHeight((Terrain) undoObject, undoLocs, undoHeights, precise);
     }
 
-    private void modifyHeight(Terrain terrain, Vector3f point1, Vector3f point2, Vector3f current, float radius, float weight, boolean precise, boolean lock) {
+    private void modifyHeight(Terrain terrain, Vector3f point1, Vector3f point2, Vector3f current, float radius, float weight, boolean precise, boolean lock, Meshes mesh) {
         // Make sure we go for the right direction, or we could be creating a slope to the oposite side
         if (point1.y > point2.y) {
             Vector3f temp = point1;
@@ -97,7 +100,7 @@ public class SlopeTerrainToolAction extends AbstractTerrainToolAction {
             point2 = temp;
         }
 
-        float totaldistance = point1.distance(point2);
+        Vector3f subtract = point2.subtract(point1);
 
         int radiusStepsX = (int) (radius / ((Node) terrain).getLocalScale().x);
         int radiusStepsZ = (int) (radius / ((Node) terrain).getLocalScale().z);
@@ -115,18 +118,18 @@ public class SlopeTerrainToolAction extends AbstractTerrainToolAction {
         p2.setOriginNormal(point2, point1.subtract(point2).normalize());
 
         for (int z = -radiusStepsZ; z < radiusStepsZ; z++)
-            for (int x = -radiusStepsZ; x < radiusStepsX; x++) {
+            for (int x = -radiusStepsX; x < radiusStepsX; x++) {
 
                 float locX = current.x + (x * xStepAmount);
                 float locZ = current.z + (z * zStepAmount);
 
-                if (ToolUtils.isInRadius(locX - current.x, locZ - current.z, radius)) { // see if it is in the radius of the tool
+                if (ToolUtils.isInMesh(locX - current.x, locZ - current.z, radius, mesh)) { // see if it is in the radius of the tool
                     Vector2f terrainLoc = new Vector2f(locX, locZ);
 
                     // adjust height based on radius of the tool
                     float terrainHeightAtLoc = terrain.getHeightmapHeight(terrainLoc) * ((Node) terrain).getWorldScale().y;
-                    float point1Distance = point1.distance(new Vector3f(locX, terrainHeightAtLoc, locZ));
-                    float desiredHeight = point1.y + (point2.y - point1.y) * (point1Distance / totaldistance);
+                    float distance = point1.distance(new Vector3f(locX, terrainHeightAtLoc, locZ).subtractLocal(point1).project(subtract).addLocal(point1));
+                    float desiredHeight = point1.y + (point2.y - point1.y) * distance;
                     if (!lock || (lock && p1.whichSide(new Vector3f(locX, 0f, locZ)) != p2.whichSide(new Vector3f(locX, 0f, locZ))))
                         if (!precise) {
                             float epsilon = 0.1f * weight; // rounding error for snapping
@@ -134,14 +137,14 @@ public class SlopeTerrainToolAction extends AbstractTerrainToolAction {
                             float adj = 0;
                             if (terrainHeightAtLoc < desiredHeight)
                                 adj = 1;
-                            else
-                                if (terrainHeightAtLoc > desiredHeight)
-                                    adj = -1;
-
-                            float radiusWeight = ToolUtils.calculateRadiusPercent(radius, locX - current.x, locZ - current.z);
-
-                            adj *= radiusWeight * weight;
-
+                            else if (terrainHeightAtLoc > desiredHeight)
+                                adj = -1;
+
+                            adj *= weight;
+                            
+                            if (mesh.equals(Meshes.Sphere))
+                                adj *= ToolUtils.calculateRadiusPercent(radius, locX - current.x, locZ - current.z);
+                            
                             // test if adjusting too far and then cap it
                             if (adj > 0 && ToolUtils.floatGreaterThan((terrainHeightAtLoc + adj), desiredHeight, epsilon))
                                 adj = desiredHeight - terrainHeightAtLoc;
@@ -155,8 +158,8 @@ public class SlopeTerrainToolAction extends AbstractTerrainToolAction {
                             }
                         } else {
                             locs.add(terrainLoc);
-                            heights.add(desiredHeight);
-                            undoHeights.add(terrainHeightAtLoc);
+                            heights.add(desiredHeight / ((Node) terrain).getLocalScale().y);
+                            undoHeights.add(terrainHeightAtLoc / ((Node) terrain).getLocalScale().y);
                         }
 
 

+ 1 - 1
jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SmoothTerrainTool.java

@@ -48,7 +48,7 @@ public class SmoothTerrainTool extends TerrainTool {
     public void actionPrimary(Vector3f point, int textureIndex, AbstractSceneExplorerNode rootNode, DataObject dataObject) {
         if (radius == 0 || weight == 0)
             return;
-        SmoothTerrainToolAction action = new SmoothTerrainToolAction(point, radius, weight);
+        SmoothTerrainToolAction action = new SmoothTerrainToolAction(point, radius, weight, getMesh());
         action.doActionPerformed(rootNode, dataObject);
     }
 

+ 8 - 5
jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SmoothTerrainToolAction.java

@@ -32,6 +32,7 @@
 package com.jme3.gde.terraineditor.tools;
 
 import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode;
+import com.jme3.gde.terraineditor.tools.TerrainTool.Meshes;
 import com.jme3.math.Vector2f;
 import com.jme3.math.Vector3f;
 import com.jme3.scene.Node;
@@ -55,11 +56,13 @@ public class SmoothTerrainToolAction extends AbstractTerrainToolAction {
     
     List<Vector2f> undoLocs;
     List<Float> undoHeights;
+    private final Meshes mesh;
 
-    public SmoothTerrainToolAction(Vector3f markerLocation, float radius, float height) {
+    public SmoothTerrainToolAction(Vector3f markerLocation, float radius, float height, Meshes mesh) {
         this.worldLoc = markerLocation.clone();
         this.radius = radius;
         this.height = height;
+        this.mesh = mesh;
         name = "Smooth terrain";
     }
 
@@ -68,7 +71,7 @@ public class SmoothTerrainToolAction extends AbstractTerrainToolAction {
         Terrain terrain = getTerrain(rootNode.getLookup().lookup(Node.class));
         if (terrain == null)
             return null;
-        modifyHeight(terrain, radius, height);
+        modifyHeight(terrain, worldLoc, radius, height, mesh);
         return terrain;
     }
     
@@ -81,7 +84,7 @@ public class SmoothTerrainToolAction extends AbstractTerrainToolAction {
         resetHeight((Terrain)undoObject, undoLocs, undoHeights);
     }
     
-    private void modifyHeight(Terrain terrain, float radius, float height) {
+    private void modifyHeight(Terrain terrain, Vector3f worldLoc, float radius, float height, Meshes mesh) {
         
         int radiusStepsX = (int)(radius / ((Node)terrain).getLocalScale().x);
         int radiusStepsZ = (int)(radius / ((Node)terrain).getLocalScale().z);
@@ -93,13 +96,13 @@ public class SmoothTerrainToolAction extends AbstractTerrainToolAction {
         List<Float> heights = new ArrayList<Float>();
 
         for (int z=-radiusStepsZ; z<radiusStepsZ; z++) {
-            for (int x=-radiusStepsZ; x<radiusStepsX; x++) {
+            for (int x=-radiusStepsX; x<radiusStepsX; x++) {
 
                 float locX = worldLoc.x + (x*xStepAmount);
                 float locZ = worldLoc.z + (z*zStepAmount);
 
                 // see if it is in the radius of the tool
-                if (ToolUtils.isInRadius(locX-worldLoc.x,locZ-worldLoc.z,radius)) {
+                if (ToolUtils.isInMesh(locX-worldLoc.x,locZ-worldLoc.z,radius,mesh)) {
 
                     Vector2f terrainLoc = new Vector2f(locX, locZ);
                     // adjust height based on radius of the tool

+ 31 - 3
jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/TerrainTool.java

@@ -42,6 +42,7 @@ import com.jme3.scene.Geometry;
 import com.jme3.scene.Mesh;
 import com.jme3.scene.Node;
 import com.jme3.scene.VertexBuffer;
+import com.jme3.scene.shape.Box;
 import com.jme3.scene.shape.Sphere;
 import com.jme3.util.IntMap.Entry;
 import org.openide.loaders.DataObject;
@@ -61,6 +62,11 @@ public abstract class TerrainTool {
     protected float radius;
     protected float weight;
     protected float maxToolSize = 20; // override in sub classes
+    private Meshes mesh;
+    
+    public static enum Meshes {
+        Box, Sphere
+    }
     
     // the key to load the tool hint text from the resource bundle
     protected String toolHintTextKey = "TerrainEditorTopComponent.toolHint.default";
@@ -119,10 +125,33 @@ public abstract class TerrainTool {
         if (markerPrimary != null) {
             for (Entry e: markerPrimary.getMesh().getBuffers())
                 ((VertexBuffer)e.getValue()).resetObject();
-            ((Sphere)markerPrimary.getMesh()).updateGeometry(8, 8, this.radius);
+            if (markerPrimary.getMesh() instanceof Sphere)
+                ((Sphere)markerPrimary.getMesh()).updateGeometry(8, 8, this.radius);
+            else if (markerPrimary.getMesh() instanceof Box)
+                ((Box)markerPrimary.getMesh()).updateGeometry(Vector3f.ZERO, this.radius, this.radius, this.radius);
         }
     }
     
+    /**
+     * Changes the appearence of the markers according to the {@code mesh} param.
+     * @param mesh possible values are: {@code sphere, box}.
+     */
+    public void setMesh(Meshes mesh) {
+        switch (mesh) {
+            case Box:
+                markerPrimary.setMesh(new Box(radius, radius, radius));
+                break;
+            case Sphere:
+                markerPrimary.setMesh(new Sphere(8, 8, radius));
+                break;
+        }
+        this.mesh = mesh;
+    }
+
+    public Meshes getMesh() {
+        return mesh;
+    }
+
     /**
      * The weight of the tool has changed. Optionally change
      * the marker look.
@@ -139,8 +168,7 @@ public abstract class TerrainTool {
     public void addMarkerPrimary(Node parent) {
         if (markerPrimary == null) {
             markerPrimary = new Geometry("edit marker primary");
-            Mesh m = new Sphere(8, 8, radius);
-            markerPrimary.setMesh(m);
+            setMesh(Meshes.Sphere);
             Material mat = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md");
             mat.getAdditionalRenderState().setWireframe(true);
             markerPrimary.setMaterial(mat);

+ 33 - 0
jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/ToolUtils.java

@@ -54,6 +54,39 @@ public class ToolUtils {
         return Math.abs(point.length()) <= radius;
     }
 
+    /**
+     * See if the X,Y coordinate is inside the box. It is assumed
+     * that the "grid" being tested is located at 0,0 and its dimensions are 2*radius.
+     * @param x
+     * @param z
+     * @param radius
+     * @return
+     */
+    public static boolean isInBox(final float x, final float y, final float radius) {
+        return Math.abs(x) <= Math.abs(radius) && Math.abs(y) <= Math.abs(radius);
+    }
+    
+    /**
+     * Based on the mesh type, chooses the proper way to see if the point is
+     * inside the marker mesh.It is assumed that the "grid" being tested is 
+     * located at 0,0 and its dimensions are 2*radius.
+     * @param x
+     * @param y
+     * @param radius
+     * @param mesh
+     * @return 
+     */
+    public static boolean isInMesh(float x, float y, float radius, TerrainTool.Meshes mesh) {
+        switch (mesh) {
+            case Box:
+                return isInBox(x, y, radius);
+            case Sphere:
+                return isInRadius(x, y, radius);
+            default:
+                throw new IllegalArgumentException("Unkown mesh type " + mesh);
+        }
+    }
+
     /**
      * Interpolate the height value based on its distance from the center (how far along
      * the radius it is).