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 6b0ae7e7c..bc8445ed8 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
@@ -119,12 +119,12 @@ CreateTerrainVisualPanel2.smoothIterationsLabel.text=Rough
CreateTerrainVisualPanel2.jLabel6.text=Smooth
CreateTerrainVisualPanel2.jLabel7.text=Height Scale:
CreateTerrainVisualPanel2.heightScale.text=1
-TerrainEditorTopComponent.toolHint.shirkit=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.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.jLabel7.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
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 7459ee179..2fd8b2097 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
@@ -188,12 +188,15 @@
-
+
-
+
+
+
+
@@ -548,7 +551,7 @@
-
+
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 2cc370eb1..d466dd42b 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
@@ -239,7 +239,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
scaleField = new javax.swing.JTextField();
slopeBrushPanel = new javax.swing.JPanel();
slopePrecisionCheckbox = new javax.swing.JCheckBox();
- jLabel7 = new javax.swing.JLabel();
+ slopeLockCheckbox = new javax.swing.JCheckBox();
jToolBar1 = new javax.swing.JToolBar();
createTerrainButton = new javax.swing.JButton();
jSeparator1 = new javax.swing.JToolBar.Separator();
@@ -381,8 +381,13 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
});
slopeBrushPanel.add(slopePrecisionCheckbox);
- org.openide.awt.Mnemonics.setLocalizedText(jLabel7, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.jLabel7.text")); // NOI18N
- slopeBrushPanel.add(jLabel7);
+ org.openide.awt.Mnemonics.setLocalizedText(slopeLockCheckbox, org.openide.util.NbBundle.getMessage(TerrainEditorTopComponent.class, "TerrainEditorTopComponent.slopeLockCheckbox.text")); // NOI18N
+ slopeLockCheckbox.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ slopeLockCheckboxActionPerformed(evt);
+ }
+ });
+ slopeBrushPanel.add(slopeLockCheckbox);
setBackground(java.awt.Color.gray);
@@ -572,7 +577,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
jPanel3.setLayout(jPanel3Layout);
jPanel3Layout.setHorizontalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 147, Short.MAX_VALUE)
+ .addGap(0, 148, Short.MAX_VALUE)
);
jPanel3Layout.setVerticalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -953,6 +958,10 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
updateSlopeToolParams();
}//GEN-LAST:event_slopePrecisionCheckboxActionPerformed
+ private void slopeLockCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_slopeLockCheckboxActionPerformed
+ updateSlopeToolParams();
+ }//GEN-LAST:event_slopeLockCheckboxActionPerformed
+
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton addTextureButton;
private javax.swing.JButton createTerrainButton;
@@ -966,7 +975,6 @@ 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;
@@ -996,6 +1004,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
private javax.swing.JLabel scaleLabel;
private javax.swing.JTextField shininessField;
private javax.swing.JPanel slopeBrushPanel;
+ private javax.swing.JCheckBox slopeLockCheckbox;
private javax.swing.JCheckBox slopePrecisionCheckbox;
private javax.swing.JToggleButton slopeTerrainButton;
private javax.swing.JToggleButton smoothTerrainButton;
@@ -1048,6 +1057,7 @@ public final class TerrainEditorTopComponent extends TopComponent implements Sce
private void updateSlopeToolParams() {
SlopeExtraToolParams params = new SlopeExtraToolParams();
params.precision = slopePrecisionCheckbox.isSelected();
+ params.lock = slopeLockCheckbox.isSelected();
toolController.setExtraToolParams(params);
}
diff --git a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SlopeExtraToolParams.java b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SlopeExtraToolParams.java
index 8309335e1..0de3060d6 100644
--- a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SlopeExtraToolParams.java
+++ b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SlopeExtraToolParams.java
@@ -40,5 +40,6 @@ import com.jme3.gde.terraineditor.ExtraToolParams;
public class SlopeExtraToolParams implements ExtraToolParams {
public boolean precision;
+ public boolean lock;
}
diff --git a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SlopeTerrainTool.java b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SlopeTerrainTool.java
index cc85371a2..6f85d486a 100644
--- a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SlopeTerrainTool.java
+++ b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SlopeTerrainTool.java
@@ -32,32 +32,39 @@
package com.jme3.gde.terraineditor.tools;
import com.jme3.asset.AssetManager;
+import com.jme3.font.BitmapText;
import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode;
import com.jme3.gde.terraineditor.ExtraToolParams;
import com.jme3.input.KeyInput;
import com.jme3.input.event.KeyInputEvent;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
+import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.control.BillboardControl;
+import com.jme3.scene.shape.Line;
import com.jme3.scene.shape.Sphere;
import org.openide.loaders.DataObject;
/**
- * Generates a slope between two control points.
+ *
* @author Shirkit
*/
public class SlopeTerrainTool extends TerrainTool {
private Vector3f point1, point2;
- private Geometry markerThird;
+ private Geometry markerThird, line;
private Node parent;
private SlopeExtraToolParams toolParams;
+ private BitmapText angleText;
+ private boolean leftCtrl = false;
public SlopeTerrainTool() {
- toolHintTextKey = "TerrainEditorTopComponent.toolHint.shirkit";
+ toolHintTextKey = "TerrainEditorTopComponent.toolHint.slope";
}
@Override
@@ -65,17 +72,20 @@ public class SlopeTerrainTool extends TerrainTool {
super.activate(manager, parent);
addMarkerSecondary(parent);
addMarkerThird(parent);
+ addLineAndText();
this.parent = parent;
}
@Override
public void hideMarkers() {
super.hideMarkers();
- if (markerThird != null) {
+ if (markerThird != null)
markerThird.removeFromParent();
- }
+
+ line.removeFromParent();
+ angleText.removeFromParent();
}
-
+
private void addMarkerThird(Node parent) {
if (markerThird == null) {
markerThird = new Geometry("edit marker secondary");
@@ -90,20 +100,29 @@ public class SlopeTerrainTool extends TerrainTool {
parent.attachChild(markerThird);
}
+ private void addLineAndText() {
+ line = new Geometry("line", new Line(Vector3f.ZERO, Vector3f.ZERO));
+ Material m = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md");
+ m.setColor("Color", ColorRGBA.White);
+ line.setMaterial(m);
+
+ angleText = new BitmapText(manager.loadFont("Interface/Fonts/Default.fnt"));
+ BillboardControl control = new BillboardControl();
+ angleText.addControl(control);
+ angleText.setSize(0.5f);
+ angleText.setCullHint(Spatial.CullHint.Never);
+ }
+
@Override
public void actionPrimary(Vector3f point, int textureIndex, AbstractSceneExplorerNode rootNode, DataObject dataObject) {
- if (point1 != null && point2 != null) {
- SlopeTerrainToolAction action = new SlopeTerrainToolAction(point, point1, point2, radius, weight, toolParams.precision);
+ 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);
action.actionPerformed(rootNode, dataObject);
}
}
- private boolean leftCtrl = false;
@Override
public void keyPressed(KeyInputEvent kie) {
- if (kie.getKeyCode() == KeyInput.KEY_LCONTROL) {
- leftCtrl = kie.isPressed();
- }
switch (kie.getKeyCode()) {
case KeyInput.KEY_LCONTROL:
leftCtrl = kie.isPressed();
@@ -113,25 +132,67 @@ public class SlopeTerrainTool extends TerrainTool {
point2 = null;
markerSecondary.removeFromParent();
markerThird.removeFromParent();
+ line.removeFromParent();
+ angleText.removeFromParent();
+ break;
+ case KeyInput.KEY_UP:
+ markerThird.move(0f, 0.1f, 0f);
+ point2.set(markerThird.getLocalTranslation());
+ updateAngle();
+ break;
+ case KeyInput.KEY_DOWN:
+ markerThird.move(0f, -0.1f, 0f);
+ point2.set(markerThird.getLocalTranslation());
+ updateAngle();
break;
}
}
+ private void updateAngle() {
+ Vector3f temp, higher, lower;
+ if (point2.y > point1.y) {
+ temp = point2;
+ higher = point2;
+ lower = point1;
+ } else {
+ temp = point1;
+ higher = point1;
+ lower = point2;
+ }
+ temp = temp.clone().setY(lower.y);
+
+ float angle = ((FastMath.asin(temp.distance(higher) / lower.distance(higher))) * FastMath.RAD_TO_DEG);
+
+ angleText.setText(angle + " degrees");
+ angleText.setLocalTranslation(new Vector3f().interpolate(point1, point2, 0.5f));
+
+ if (line.getParent() == null) {
+ parent.attachChild(line);
+ parent.attachChild(angleText);
+ }
+ ((Line) line.getMesh()).updatePoints(point1, point2);
+ }
+
@Override
public void actionSecondary(Vector3f point, int textureIndex, AbstractSceneExplorerNode rootNode, DataObject dataObject) {
if (leftCtrl) {
point2 = point;
- if (markerThird.getParent() == null) {
+ if (markerThird.getParent() == null)
parent.attachChild(markerThird);
- }
+
markerThird.setLocalTranslation(point);
} else {
point1 = point;
- if (markerSecondary.getParent() == null) {
+ if (markerSecondary.getParent() == null)
parent.attachChild(markerSecondary);
- }
+
markerSecondary.setLocalTranslation(point);
}
+ if (point1 != null && point2 != null)
+ updateAngle();
+ else
+ if (line != null)
+ line.removeFromParent();
}
@Override
@@ -139,6 +200,4 @@ public class SlopeTerrainTool extends TerrainTool {
if (params instanceof SlopeExtraToolParams)
this.toolParams = (SlopeExtraToolParams) params;
}
-
-
}
diff --git a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SlopeTerrainToolAction.java b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SlopeTerrainToolAction.java
index d55ab6e80..d3bcf079d 100644
--- a/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SlopeTerrainToolAction.java
+++ b/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/SlopeTerrainToolAction.java
@@ -32,7 +32,9 @@
package com.jme3.gde.terraineditor.tools;
import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode;
-import com.jme3.math.*;
+import com.jme3.math.Plane;
+import com.jme3.math.Vector2f;
+import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
import com.jme3.terrain.Terrain;
import java.util.ArrayList;
@@ -52,41 +54,43 @@ public class SlopeTerrainToolAction extends AbstractTerrainToolAction {
private List undoLocs;
private List undoHeights;
private final boolean precise;
+ private final boolean lock;
- public SlopeTerrainToolAction(Vector3f current, Vector3f point1, Vector3f point2, float radius, float weight, boolean precise) {
+ public SlopeTerrainToolAction(Vector3f current, Vector3f point1, Vector3f point2, float radius, float weight, boolean precise, boolean lock) {
this.current = current.clone();
this.point1 = point1;
this.point2 = point2;
this.radius = radius;
this.weight = weight;
this.precise = precise;
+ this.lock = lock;
name = "Slope terrain";
}
@Override
protected Object doApplyTool(AbstractSceneExplorerNode rootNode) {
Terrain terrain = getTerrain(rootNode.getLookup().lookup(Node.class));
- if (terrain == null) {
+ if (terrain == null)
return null;
- }
- modifyHeight(terrain, point1, point2, current, radius, weight, precise);
+ modifyHeight(terrain, point1, point2, current, radius, weight, precise, lock);
return terrain;
}
@Override
protected void doUndoTool(AbstractSceneExplorerNode rootNode, Object undoObject) {
- if (undoObject == null) {
+ if (undoObject == null)
return;
- }
- if (undoLocs == null || undoHeights == null) {
+
+ if (undoLocs == null || undoHeights == null)
return;
- }
+
resetHeight((Terrain) undoObject, undoLocs, undoHeights, precise);
}
- private void modifyHeight(Terrain terrain, Vector3f point1, Vector3f point2, Vector3f current, float radius, float weight, boolean precise) {
+ private void modifyHeight(Terrain terrain, Vector3f point1, Vector3f point2, Vector3f current, float radius, float weight, boolean precise, boolean lock) {
+ // 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;
point1 = point2;
@@ -104,55 +108,60 @@ public class SlopeTerrainToolAction extends AbstractTerrainToolAction {
List locs = new ArrayList();
List heights = new ArrayList();
undoHeights = new ArrayList();
-
- for (int z = -radiusStepsZ; z < radiusStepsZ; z++) {
+
+ Plane p1 = new Plane();
+ Plane p2 = new Plane();
+ p1.setOriginNormal(point1, point1.subtract(point2).normalize());
+ p2.setOriginNormal(point2, point1.subtract(point2).normalize());
+
+ for (int z = -radiusStepsZ; z < radiusStepsZ; z++)
for (int x = -radiusStepsZ; x < radiusStepsX; x++) {
float locX = current.x + (x * xStepAmount);
float locZ = current.z + (z * zStepAmount);
-
- // see if it is in the radius of the tool
- if (ToolUtils.isInRadius(locX - current.x, locZ - current.z, radius)) {
-
+
+ if (ToolUtils.isInRadius(locX - current.x, locZ - current.z, radius)) { // 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 radiusWeight = ToolUtils.calculateRadiusPercent(radius, locX - current.x, locZ - current.z);
-
float point1Distance = point1.distance(new Vector3f(locX, terrainHeightAtLoc, locZ));
float desiredHeight = point1.y + (point2.y - point1.y) * (point1Distance / totaldistance);
-
- if (!precise) {
- float epsilon = 0.1f * weight; // rounding error for snapping
-
- float adj = 0;
- if (terrainHeightAtLoc < desiredHeight) {
- adj = 1;
- } else if (terrainHeightAtLoc > desiredHeight) {
- adj = -1;
+ 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
+
+ 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;
+
+ // 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);
+ heights.add(adj);
+ }
+ } else {
+ locs.add(terrainLoc);
+ heights.add(desiredHeight);
+ undoHeights.add(terrainHeightAtLoc);
}
- adj *= radiusWeight * weight;
- // 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);
- heights.add(adj);
- }
- } else {
- locs.add(terrainLoc);
- heights.add(desiredHeight);
- undoHeights.add(terrainHeightAtLoc);
- }
}
}
- }
undoLocs = locs;
if (!precise)
undoHeights = heights;