diff --git a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/Bundle.properties b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/Bundle.properties index 2c9f3ac9e..95dc6d25b 100644 --- a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/Bundle.properties +++ b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/Bundle.properties @@ -98,3 +98,9 @@ TerrainEditorTopComponent.paintingPanel.border.title=Painting TerrainEditorTopComponent.triPlanarCheckBox.toolTipText=Enable if you have a lot of vertical surfaces. It will look nice but lower performance TerrainEditorTopComponent.triPlanarCheckBox.text=Tri-planar mapping TerrainEditorTopComponent.jButton1.text=Create Skybox +TerrainEditorTopComponent.levelTerrainButton.text= + +TerrainEditorTopComponent.toolHint.none= +TerrainEditorTopComponent.toolHint.default=Switch between camera and tool controls by holding down SHIFT +TerrainEditorTopComponent.toolHint.smooth= +TerrainEditorTopComponent.toolHint.level=Right click to set desired height value, left click to adjust height to that desired value. diff --git a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainCameraController.java b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainCameraController.java index 350cf9cff..1f596d1bf 100644 --- a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainCameraController.java +++ b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainCameraController.java @@ -107,7 +107,7 @@ public class TerrainCameraController extends AbstractCameraController { movedR = true; if (isTerrainEditButtonEnabled() && !forceCameraControls) { if (leftMouse) - terrainEditToolActivated = true;//toolController.doTerrainEditToolActivated(); + terrainEditToolActivated = true; } else { if (leftMouse) { @@ -122,7 +122,7 @@ public class TerrainCameraController extends AbstractCameraController { movedR = true; if (isTerrainEditButtonEnabled() && !forceCameraControls) { if (leftMouse) - terrainEditToolActivated = true;//toolController.doTerrainEditToolActivated(); + terrainEditToolActivated = true; } else { if (leftMouse) { @@ -137,7 +137,7 @@ public class TerrainCameraController extends AbstractCameraController { movedR = true; if (isTerrainEditButtonEnabled() && !forceCameraControls) { if (leftMouse) - terrainEditToolActivated = true;//toolController.doTerrainEditToolActivated(); + terrainEditToolActivated = true; } else { if (leftMouse) { @@ -152,7 +152,7 @@ public class TerrainCameraController extends AbstractCameraController { movedR = true; if (isTerrainEditButtonEnabled() && !forceCameraControls) { if (leftMouse) - terrainEditToolActivated = true;//toolController.doTerrainEditToolActivated(); + terrainEditToolActivated = true; } else { if (leftMouse) { @@ -181,7 +181,12 @@ public class TerrainCameraController extends AbstractCameraController { if (button == 0) { if (isTerrainEditButtonEnabled() && !forceCameraControls) { if (leftMouse) - terrainEditToolActivated = true;//toolController.doTerrainEditToolActivated(); + terrainEditToolActivated = true; + } + } + if (button == 1) { + if (isTerrainEditButtonEnabled() && !forceCameraControls) { + toolController.doTerrainEditToolAlternateActivated(); } } } @@ -199,7 +204,8 @@ public class TerrainCameraController extends AbstractCameraController { if (lastModifyTime >= toolModifyRate) { lastModifyTime = 0; - toolController.doTerrainEditToolActivated(); + if (terrainEditToolActivated) + toolController.doTerrainEditToolActivated(); terrainEditToolActivated = false; lastModifyTime = app.getContext().getTimer().getTime(); } @@ -222,7 +228,7 @@ public class TerrainCameraController extends AbstractCameraController { /** * Find where on the terrain the mouse intersects. */ - private Vector3f getTerrainCollisionPoint() { + protected Vector3f getTerrainCollisionPoint() { if (editorController.getTerrain(null) == null) return null; diff --git a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorController.java b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorController.java index 3e5b47787..048a816f5 100644 --- a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorController.java +++ b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorController.java @@ -88,8 +88,11 @@ public class TerrainEditorController { private final int BASE_TEXTURE_COUNT = NUM_ALPHA_TEXTURES; // add any others here, like a global specular map protected final int MAX_TEXTURE_LAYERS = 7-BASE_TEXTURE_COUNT; // 16 max, minus the ones we are reserving + // level terrain settings + private Vector3f levelTerrainDesiredHeight; + private float levelTerrainSnapThreshold = 0.01f; - //private DataObjectSaveNode alphaDataObject; + protected SaveCookie terrainSaveCookie = new SaveCookie() { public void save() throws IOException { @@ -177,38 +180,38 @@ public class TerrainEditorController { float zStepAmount = ((Node)terrain).getLocalScale().z; for (int z=-radiusStepsZ; z() { - public Object call() throws Exception { - doSaveAlphaImages(terrain); - return null; - } - }); - } + /** * Save the terrain's alpha maps to disk, in the Textures/terrain-alpha/ directory @@ -1195,6 +1181,110 @@ public class TerrainEditorController { setNeedsSave(true); } + /** + * Level the terrain to the desired height. + * It will pull down or raise terrain towards the desired height, still + * using the radius of the tool and the weight. There are some slight rounding + * errors that are coorected with float epsilon testing. + * @param markerLocation + * @param heightToolRadius + * @param heightAmount + */ + protected void doLevelTerrain(Vector3f worldLoc, float radius, float heightWeight) { + if (levelTerrainDesiredHeight == null) + return; + + float desiredHeight = levelTerrainDesiredHeight.y; + + Terrain terrain = (Terrain) getTerrain(null); + if (terrain == null) + return; + + setNeedsSave(true); + + int radiusStepsX = (int)(radius / ((Node)terrain).getLocalScale().x); + int radiusStepsZ = (int)(radius / ((Node)terrain).getLocalScale().z); + + float xStepAmount = ((Node)terrain).getLocalScale().x; + float zStepAmount = ((Node)terrain).getLocalScale().z; + + List locs = new ArrayList(); + List heights = new ArrayList(); + + for (int z=-radiusStepsZ; z desiredHeight) + adj = -1; + + adj *= radiusWeight * heightWeight; + + // test if adjusting too far and then cap it + if (adj > 0 && floatGreaterThan((terrainHeightAtLoc + adj), desiredHeight, epsilon)) + adj = desiredHeight - terrainHeightAtLoc; + else if (adj < 0 && floatLessThan((terrainHeightAtLoc + adj), desiredHeight, epsilon)) + adj = terrainHeightAtLoc - desiredHeight; + + if (!floatEquals(adj, 0, 0.001f)) { + locs.add(terrainLoc); + heights.add(adj); + } + + } + } + } + // do the actual height adjustment + terrain.adjustHeight(locs, heights); + + ((Node)terrain).updateModelBound(); // or else we won't collide with it where we just edited + + } + + private int compareFloat(float a, float b, float epsilon) { + if (floatEquals(a, b, epsilon)) + return 0; + else if (floatLessThan(a, b, epsilon)) + return -1; + else + return 1; + } + + private boolean floatEquals(float a, float b, float epsilon) { + return a == b ? true : Math.abs(a - b) < epsilon; + } + + private boolean floatLessThan(float a, float b, float epsilon) { + return b - a > epsilon; + } + + private boolean floatGreaterThan(float a, float b, float epsilon) { + return a - b > epsilon; + } + + protected void doSetLevelTerrainDesiredHeight(Vector3f point) { + this.levelTerrainDesiredHeight = point; + } + + public Vector3f doGetLevelTerrainDesiredHeight() { + return levelTerrainDesiredHeight; + } + diff --git a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorTopComponent.form b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorTopComponent.form index 59c555ca7..da18ec695 100644 --- a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorTopComponent.form +++ b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorTopComponent.form @@ -536,6 +536,22 @@ + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorTopComponent.java b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorTopComponent.java index 6a30eb3d0..744f1d505 100644 --- a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorTopComponent.java +++ b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainEditorTopComponent.java @@ -179,9 +179,13 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce private void setHintText(TerrainEditButton terrainEditButton) { if (TerrainEditButton.none.equals(terrainEditButton) ) - hintTextArea.setText(""); + hintTextArea.setText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.toolHint.none")); + else if (TerrainEditButton.levelTerrain.equals(terrainEditButton) ) + hintTextArea.setText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.toolHint.level")); + else if (TerrainEditButton.smoothTerrain.equals(terrainEditButton) ) + hintTextArea.setText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.toolHint.smooth")); else - hintTextArea.setText("Switch between camera and tool controls by holding down SHIFT"); + hintTextArea.setText(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.toolHint.default")); } @@ -222,6 +226,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce lowerTerrainButton = new javax.swing.JToggleButton(); smoothTerrainButton = new javax.swing.JToggleButton(); roughTerrainButton = new javax.swing.JToggleButton(); + levelTerrainButton = new javax.swing.JToggleButton(); jSeparator2 = new javax.swing.JToolBar.Separator(); paintButton = new javax.swing.JToggleButton(); eraseButton = new javax.swing.JToggleButton(); @@ -247,11 +252,11 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce hintPanel.setLayout(hintPanelLayout); hintPanelLayout.setHorizontalGroup( hintPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 189, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 283, Short.MAX_VALUE) ); hintPanelLayout.setVerticalGroup( hintPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 131, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 151, Short.MAX_VALUE) ); toolSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.toolSettingsPanel.border.title"))); // NOI18N @@ -306,7 +311,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce .addGroup(toolSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(heightLabel) .addComponent(heightSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap(56, Short.MAX_VALUE)) + .addContainerGap(76, Short.MAX_VALUE)) ); paintingPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.paintingPanel.border.title"))); // NOI18N @@ -357,7 +362,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce .addGroup(paintingPanelLayout.createSequentialGroup() .addGroup(paintingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, paintingPanelLayout.createSequentialGroup() - .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 277, Short.MAX_VALUE) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 425, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(paintingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addComponent(removeTextureButton, 0, 0, Short.MAX_VALUE) @@ -366,7 +371,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce .addComponent(remainingTexTitleLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(remainingTexturesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 78, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 228, Short.MAX_VALUE) .addComponent(triPlanarCheckBox))) .addContainerGap()) ); @@ -378,7 +383,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce .addComponent(addTextureButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(removeTextureButton)) - .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 106, Short.MAX_VALUE)) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 126, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(paintingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(remainingTexTitleLabel) @@ -419,7 +424,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce .addComponent(genEntropiesButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton1) - .addContainerGap(79, Short.MAX_VALUE)) + .addContainerGap(99, Short.MAX_VALUE)) ); jToolBar1.setFloatable(false); @@ -475,6 +480,18 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce roughTerrainButton.setActionCommand(org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.roughTerrainButton.actionCommand")); // NOI18N roughTerrainButton.setEnabled(false); jToolBar1.add(roughTerrainButton); + + levelTerrainButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/terraineditor/icon_terrain-level.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(levelTerrainButton, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.levelTerrainButton.text")); // NOI18N + levelTerrainButton.setFocusable(false); + levelTerrainButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + levelTerrainButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + levelTerrainButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + levelTerrainButtonActionPerformed(evt); + } + }); + jToolBar1.add(levelTerrainButton); jToolBar1.add(jSeparator2); terrainModButtonGroup.add(paintButton); @@ -517,7 +534,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce .addComponent(terrainOpsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(hintPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 1019, Short.MAX_VALUE) + .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 1261, Short.MAX_VALUE) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -645,6 +662,16 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce addSpatial("Skybox"); }//GEN-LAST:event_jButton1ActionPerformed + private void levelTerrainButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_levelTerrainButtonActionPerformed + if (levelTerrainButton.isSelected()) { + toolController.setTerrainEditButtonState(TerrainEditButton.levelTerrain); + setHintText(TerrainEditButton.levelTerrain); + } else { + toolController.setTerrainEditButtonState(TerrainEditButton.none); + setHintText(TerrainEditButton.none); + } + }//GEN-LAST:event_levelTerrainButtonActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton addTextureButton; private javax.swing.JButton createTerrainButton; @@ -661,6 +688,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce private javax.swing.JToolBar.Separator jSeparator1; private javax.swing.JToolBar.Separator jSeparator2; private javax.swing.JToolBar jToolBar1; + private javax.swing.JToggleButton levelTerrainButton; private javax.swing.JToggleButton lowerTerrainButton; private javax.swing.JToggleButton paintButton; private javax.swing.JPanel paintingPanel; @@ -997,6 +1025,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce camController.setToolController(toolController); camController.setEditorController(editorController); toolController.setEditorController(editorController); + toolController.setCameraController(camController); editorController.setToolController(toolController); toolController.setHeightToolRadius(radiusSlider.getValue()); diff --git a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainToolController.java b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainToolController.java index 2c45bbeb6..fc5a66228 100644 --- a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainToolController.java +++ b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/TerrainToolController.java @@ -63,13 +63,22 @@ public class TerrainToolController extends SceneToolController { private JmeSpatial jmeRootNode; private TerrainEditButton currentEditButtonState = TerrainEditButton.none; private Geometry marker; + private Geometry markerSmall; private TerrainEditorController editorController; + private TerrainCameraController cameraController; private float heightToolRadius; - private float heightToolHeight; private float heightAmount; + private float levelAmount; private float paintAmount; private int selectedTextureIndex = -1; + private final ColorRGBA terrainHeightColor = ColorRGBA.Green; + private final ColorRGBA terrainPaintColor = ColorRGBA.Yellow; + private final ColorRGBA terrainEraseColor = ColorRGBA.Cyan; + private final ColorRGBA terrainSmoothColor = ColorRGBA.Brown; + private final ColorRGBA terrainLevelColor = ColorRGBA.Orange; + private final ColorRGBA terrainLevelMarkColor = ColorRGBA.Red; + public TerrainToolController(Node toolsNode, AssetManager manager, JmeNode rootNode) { super(toolsNode, manager); this.jmeRootNode = rootNode; @@ -79,12 +88,16 @@ public class TerrainToolController extends SceneToolController { this.editorController = editorController; } + public void setCameraController(TerrainCameraController cameraController) { + this.cameraController = cameraController; + } + /** * assumes [0,200] */ public void setHeightToolHeight(float heightToolHeight) { - this.heightToolHeight = heightToolHeight; this.heightAmount = heightToolHeight/100f; + this.levelAmount = heightToolHeight/200f; this.paintAmount = heightToolHeight/200f; } @@ -107,9 +120,18 @@ public class TerrainToolController extends SceneToolController { marker.setMesh(m); Material mat = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md"); mat.getAdditionalRenderState().setWireframe(true); - mat.setColor("Color", ColorRGBA.Green); + mat.setColor("Color", ColorRGBA.LightGray); marker.setMaterial(mat); marker.setLocalTranslation(0,0,0); + + markerSmall = new Geometry("edit marker"); + Mesh m2 = new Sphere(8, 8, 0.5f); + markerSmall.setMesh(m2); + Material mat2 = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat2.getAdditionalRenderState().setWireframe(false); + mat2.setColor("Color", ColorRGBA.Red); + markerSmall.setMaterial(mat2); + markerSmall.setLocalTranslation(0,0,0); } protected void setMarkerRadius(float radius) { @@ -121,16 +143,18 @@ public class TerrainToolController extends SceneToolController { } public void setTerrainEditButtonState(final TerrainEditButton state) { - + Logger.getLogger(this.getClass().getName()).info("Edit button state set: "+state); currentEditButtonState = state; if (state == TerrainEditButton.none) { hideEditTool(); } else if (state == TerrainEditButton.raiseTerrain || state == TerrainEditButton.lowerTerrain) { showEditTool(state); - Logger.getLogger(TerrainEditorTopComponent.class.getName()).info("TERRAIN HEIGHT state"); + } else if (state == TerrainEditButton.levelTerrain) { + showEditTool(state); + } else if (state == TerrainEditButton.smoothTerrain) { + showEditTool(state); } else if (state == TerrainEditButton.paintTerrain || state == TerrainEditButton.eraseTerrain) { showEditTool(state); - Logger.getLogger(TerrainEditorTopComponent.class.getName()).info("PAINT TERRAIN state"); } } @@ -147,6 +171,8 @@ public class TerrainToolController extends SceneToolController { private void doHideEditTool() { marker.removeFromParent(); + markerSmall.removeFromParent(); + editorController.doSetLevelTerrainDesiredHeight(null); } public void showEditTool(final TerrainEditButton terrainEditButton) { @@ -160,12 +186,28 @@ public class TerrainToolController extends SceneToolController { } - private void doShowEditTool(TerrainEditButton terrainEditButton) { - //TODO show different tool marker depending on terrainEditButton type + /** + * show different tool marker depending on terrainEditButton type + * @param state + */ + private void doShowEditTool(TerrainEditButton state) { toolsNode.attachChild(marker); + markerSmall.removeFromParent(); // reset, turn it off + editorController.doSetLevelTerrainDesiredHeight(null); // disable the level marker height - + if (state == TerrainEditButton.raiseTerrain || state == TerrainEditButton.lowerTerrain) { + marker.getMaterial().setColor("Color", terrainHeightColor); + } else if (state == TerrainEditButton.paintTerrain) { + marker.getMaterial().setColor("Color", terrainPaintColor); + } else if (state == TerrainEditButton.eraseTerrain) { + marker.getMaterial().setColor("Color", terrainEraseColor); + } else if (state == TerrainEditButton.levelTerrain) { + toolsNode.attachChild(markerSmall); + marker.getMaterial().setColor("Color", terrainLevelColor); + } else if (state == TerrainEditButton.smoothTerrain) { + marker.getMaterial().setColor("Color", terrainSmoothColor); + } } public void setEditToolSize(final float size) { @@ -203,25 +245,48 @@ public class TerrainToolController extends SceneToolController { } /** + * Primary mouse button hit. * raise/lower/paint the terrain */ public void doTerrainEditToolActivated() { if (TerrainEditButton.raiseTerrain == getCurrentEditButtonState() ) { editorController.doModifyTerrainHeight(getMarkerLocation(), heightToolRadius, heightAmount); - Logger.getLogger(TerrainEditorTopComponent.class.getName()).info("terrain raise height"); } else if (TerrainEditButton.lowerTerrain == getCurrentEditButtonState() ) { editorController.doModifyTerrainHeight(getMarkerLocation(), heightToolRadius, -heightAmount); - Logger.getLogger(TerrainEditorTopComponent.class.getName()).info("terrain lower height"); + } + else if (TerrainEditButton.smoothTerrain == getCurrentEditButtonState() ) { + + } + else if (TerrainEditButton.levelTerrain == getCurrentEditButtonState() ) { + if (editorController.doGetLevelTerrainDesiredHeight() == null) { + Vector3f point = cameraController.getTerrainCollisionPoint(); + if (point != null) + editorController.doSetLevelTerrainDesiredHeight(point); + } + editorController.doLevelTerrain(getMarkerLocation(), heightToolRadius, levelAmount); } else if(TerrainEditButton.paintTerrain == getCurrentEditButtonState()) { editorController.doPaintTexture(selectedTextureIndex, getMarkerLocation(), heightToolRadius, paintAmount); - Logger.getLogger(TerrainEditorTopComponent.class.getName()).info("terrain paint"); } else if (TerrainEditButton.eraseTerrain == getCurrentEditButtonState() ) { editorController.doPaintTexture(selectedTextureIndex, getMarkerLocation(), heightToolRadius, -paintAmount); - Logger.getLogger(TerrainEditorTopComponent.class.getName()).info("terrain erase"); + } + } + + /** + * Alternate mouse button hit. + */ + public void doTerrainEditToolAlternateActivated() { + Logger.getLogger(this.getClass().getName()).info("Alternate tool activated "); + if (TerrainEditButton.levelTerrain == getCurrentEditButtonState() ) { + + Vector3f point = cameraController.getTerrainCollisionPoint(); + if (point != null) { + editorController.doSetLevelTerrainDesiredHeight(point); + markerSmall.setLocalTranslation(point); + } } } } diff --git a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/icon_terrain-level.png b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/icon_terrain-level.png new file mode 100644 index 000000000..b106e08f3 Binary files /dev/null and b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/icon_terrain-level.png differ