added 'slope' tool to terrain editor, and some more options to the 'level terrain' tool. Thanks @shirkit
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9582 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
parent
4f848ab5b5
commit
d3b280c7e3
After Width: | Height: | Size: 2.9 KiB |
@ -0,0 +1,18 @@ |
||||
/* |
||||
* To change this template, choose Tools | Templates |
||||
* and open the template in the editor. |
||||
*/ |
||||
package com.jme3.gde.terraineditor.tools; |
||||
|
||||
import com.jme3.gde.terraineditor.ExtraToolParams; |
||||
|
||||
/** |
||||
* |
||||
* @author Shirkit |
||||
*/ |
||||
public class LevelExtraToolParams implements ExtraToolParams { |
||||
|
||||
public boolean precision; |
||||
public boolean absolute; |
||||
public float height; |
||||
} |
@ -0,0 +1,44 @@ |
||||
/* |
||||
* Copyright (c) 2009-2011 jMonkeyEngine |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* |
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||
* may be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package com.jme3.gde.terraineditor.tools; |
||||
|
||||
import com.jme3.gde.terraineditor.ExtraToolParams; |
||||
|
||||
/** |
||||
* |
||||
* @author Shirkit |
||||
*/ |
||||
public class SlopeExtraToolParams implements ExtraToolParams { |
||||
|
||||
public boolean precision; |
||||
|
||||
} |
@ -0,0 +1,144 @@ |
||||
/* |
||||
* Copyright (c) 2009-2011 jMonkeyEngine |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* |
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||
* may be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package com.jme3.gde.terraineditor.tools; |
||||
|
||||
import com.jme3.asset.AssetManager; |
||||
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.Vector3f; |
||||
import com.jme3.scene.Geometry; |
||||
import com.jme3.scene.Mesh; |
||||
import com.jme3.scene.Node; |
||||
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 Node parent; |
||||
private SlopeExtraToolParams toolParams; |
||||
|
||||
public SlopeTerrainTool() { |
||||
toolHintTextKey = "TerrainEditorTopComponent.toolHint.shirkit"; |
||||
} |
||||
|
||||
@Override |
||||
public void activate(AssetManager manager, Node parent) { |
||||
super.activate(manager, parent); |
||||
addMarkerSecondary(parent); |
||||
addMarkerThird(parent); |
||||
this.parent = parent; |
||||
} |
||||
|
||||
@Override |
||||
public void hideMarkers() { |
||||
super.hideMarkers(); |
||||
if (markerThird != null) { |
||||
markerThird.removeFromParent(); |
||||
} |
||||
} |
||||
|
||||
private void addMarkerThird(Node parent) { |
||||
if (markerThird == null) { |
||||
markerThird = new Geometry("edit marker secondary"); |
||||
Mesh m2 = new Sphere(8, 8, 0.5f); |
||||
markerThird.setMesh(m2); |
||||
Material mat2 = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md"); |
||||
mat2.getAdditionalRenderState().setWireframe(false); |
||||
markerThird.setMaterial(mat2); |
||||
markerThird.setLocalTranslation(0, 0, 0); |
||||
mat2.setColor("Color", ColorRGBA.Blue); |
||||
} |
||||
parent.attachChild(markerThird); |
||||
} |
||||
|
||||
@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); |
||||
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(); |
||||
break; |
||||
case KeyInput.KEY_C: |
||||
point1 = null; |
||||
point2 = null; |
||||
markerSecondary.removeFromParent(); |
||||
markerThird.removeFromParent(); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void actionSecondary(Vector3f point, int textureIndex, AbstractSceneExplorerNode rootNode, DataObject dataObject) { |
||||
if (leftCtrl) { |
||||
point2 = point; |
||||
if (markerThird.getParent() == null) { |
||||
parent.attachChild(markerThird); |
||||
} |
||||
markerThird.setLocalTranslation(point); |
||||
} else { |
||||
point1 = point; |
||||
if (markerSecondary.getParent() == null) { |
||||
parent.attachChild(markerSecondary); |
||||
} |
||||
markerSecondary.setLocalTranslation(point); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void setExtraParams(ExtraToolParams params) { |
||||
if (params instanceof SlopeExtraToolParams) |
||||
this.toolParams = (SlopeExtraToolParams) params; |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,181 @@ |
||||
/* |
||||
* Copyright (c) 2009-2011 jMonkeyEngine |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* |
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||
* may be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package com.jme3.gde.terraineditor.tools; |
||||
|
||||
import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode; |
||||
import com.jme3.math.*; |
||||
import com.jme3.scene.Node; |
||||
import com.jme3.terrain.Terrain; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* |
||||
* @author Shirkit |
||||
*/ |
||||
public class SlopeTerrainToolAction extends AbstractTerrainToolAction { |
||||
|
||||
private final Vector3f current; |
||||
private Vector3f point1; |
||||
private Vector3f point2; |
||||
private final float radius; |
||||
private final float weight; |
||||
private List<Vector2f> undoLocs; |
||||
private List<Float> undoHeights; |
||||
private final boolean precise; |
||||
|
||||
public SlopeTerrainToolAction(Vector3f current, Vector3f point1, Vector3f point2, float radius, float weight, boolean precise) { |
||||
this.current = current.clone(); |
||||
this.point1 = point1; |
||||
this.point2 = point2; |
||||
this.radius = radius; |
||||
this.weight = weight; |
||||
this.precise = precise; |
||||
name = "Slope terrain"; |
||||
} |
||||
|
||||
@Override |
||||
protected Object doApplyTool(AbstractSceneExplorerNode rootNode) { |
||||
Terrain terrain = getTerrain(rootNode.getLookup().lookup(Node.class)); |
||||
if (terrain == null) { |
||||
return null; |
||||
} |
||||
|
||||
modifyHeight(terrain, point1, point2, current, radius, weight, precise); |
||||
|
||||
return terrain; |
||||
} |
||||
|
||||
@Override |
||||
protected void doUndoTool(AbstractSceneExplorerNode rootNode, Object undoObject) { |
||||
if (undoObject == null) { |
||||
return; |
||||
} |
||||
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) { |
||||
if (point1.y > point2.y) { |
||||
Vector3f temp = point1; |
||||
point1 = point2; |
||||
point2 = temp; |
||||
} |
||||
|
||||
float totaldistance = point1.distance(point2); |
||||
|
||||
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<Vector2f> locs = new ArrayList<Vector2f>(); |
||||
List<Float> heights = new ArrayList<Float>(); |
||||
undoHeights = new ArrayList<Float>(); |
||||
|
||||
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)) { |
||||
|
||||
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; |
||||
} |
||||
|
||||
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; |
||||
|
||||
// do the actual height adjustment
|
||||
if (precise) |
||||
terrain.setHeight(locs, heights); |
||||
else |
||||
terrain.adjustHeight(locs, heights); |
||||
|
||||
((Node) terrain).updateModelBound(); // or else we won't collide with it where we just edited
|
||||
} |
||||
|
||||
private void resetHeight(Terrain terrain, List<Vector2f> undoLocs, List<Float> undoHeights, boolean precise) { |
||||
if (precise) |
||||
terrain.setHeight(undoLocs, undoHeights); |
||||
else { |
||||
List<Float> neg = new ArrayList<Float>(); |
||||
for (Float f : undoHeights) { |
||||
neg.add(f * -1f); |
||||
} |
||||
terrain.adjustHeight(undoLocs, neg); |
||||
} |
||||
((Node) terrain).updateModelBound(); |
||||
} |
||||
} |
Loading…
Reference in new issue