|
@@ -1,9 +1,38 @@
|
|
/*
|
|
/*
|
|
- * To change this template, choose Tools | Templates
|
|
|
|
- * and open the template in the editor.
|
|
|
|
|
|
+ * Copyright (c) 2009-2010 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.terrain.geomipmap;
|
|
package com.jme3.terrain.geomipmap;
|
|
|
|
|
|
|
|
+import com.jme3.scene.control.UpdateControl;
|
|
|
|
+import com.jme3.app.Application;
|
|
import com.jme3.bullet.PhysicsSpace;
|
|
import com.jme3.bullet.PhysicsSpace;
|
|
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
|
|
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
|
|
import com.jme3.bullet.control.RigidBodyControl;
|
|
import com.jme3.bullet.control.RigidBodyControl;
|
|
@@ -19,10 +48,11 @@ import com.jme3.material.Material;
|
|
import com.jme3.math.FastMath;
|
|
import com.jme3.math.FastMath;
|
|
import com.jme3.math.Vector2f;
|
|
import com.jme3.math.Vector2f;
|
|
import com.jme3.math.Vector3f;
|
|
import com.jme3.math.Vector3f;
|
|
|
|
+import com.jme3.renderer.Camera;
|
|
import com.jme3.terrain.geomipmap.lodcalc.LodCalculatorFactory;
|
|
import com.jme3.terrain.geomipmap.lodcalc.LodCalculatorFactory;
|
|
import com.jme3.terrain.geomipmap.lodcalc.LodDistanceCalculatorFactory;
|
|
import com.jme3.terrain.geomipmap.lodcalc.LodDistanceCalculatorFactory;
|
|
import com.jme3.terrain.heightmap.HeightMapGrid;
|
|
import com.jme3.terrain.heightmap.HeightMapGrid;
|
|
-import com.jme3.terrain.heightmap.RawHeightMap;
|
|
|
|
|
|
+import java.util.concurrent.Callable;
|
|
|
|
|
|
/**
|
|
/**
|
|
* @author Anthyon
|
|
* @author Anthyon
|
|
@@ -34,7 +64,7 @@ public class TerrainGrid extends TerrainQuad {
|
|
private int quarterSize;
|
|
private int quarterSize;
|
|
private int quadSize;
|
|
private int quadSize;
|
|
private HeightMapGrid heightMapGrid;
|
|
private HeightMapGrid heightMapGrid;
|
|
- private Vector3f[] quadOrigins;
|
|
|
|
|
|
+ //private Vector3f[] quadOrigins;
|
|
private Vector3f[] quadIndex;
|
|
private Vector3f[] quadIndex;
|
|
private Map<String, TerrainGridListener> listeners = new HashMap<String, TerrainGridListener>();
|
|
private Map<String, TerrainGridListener> listeners = new HashMap<String, TerrainGridListener>();
|
|
private Material material;
|
|
private Material material;
|
|
@@ -45,77 +75,107 @@ public class TerrainGrid extends TerrainQuad {
|
|
private class UpdateQuadCache implements Runnable {
|
|
private class UpdateQuadCache implements Runnable {
|
|
|
|
|
|
private final Vector3f location;
|
|
private final Vector3f location;
|
|
- private final boolean centerOnly;
|
|
|
|
|
|
|
|
public UpdateQuadCache(Vector3f location) {
|
|
public UpdateQuadCache(Vector3f location) {
|
|
this.location = location;
|
|
this.location = location;
|
|
- this.centerOnly = false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public UpdateQuadCache(Vector3f location, boolean centerOnly) {
|
|
|
|
- this.location = location;
|
|
|
|
- this.centerOnly = centerOnly;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
public void run() {
|
|
public void run() {
|
|
- for (int i = centerOnly ? 1 : 0; i < (centerOnly ? 3 : 4); i++) {
|
|
|
|
- for (int j = centerOnly ? 1 : 0; j < (centerOnly ? 3 : 4); j++) {
|
|
|
|
- Vector3f temp = location.add(quadIndex[i * 4 + j]);
|
|
|
|
- if (cache.get(temp) == null) {
|
|
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < 4; i++) {
|
|
|
|
+ for (int j = 0; j < 4; j++) {
|
|
|
|
+ int quadIdx = i * 4 + j;
|
|
|
|
+ final Vector3f temp = location.add(quadIndex[quadIdx]);
|
|
|
|
+ TerrainQuad q = cache.get(temp);
|
|
|
|
+ if (q == null) {
|
|
|
|
+ // create the new Quad since it doesn't exist
|
|
HeightMap heightMapAt = heightMapGrid.getHeightMapAt(temp);
|
|
HeightMap heightMapAt = heightMapGrid.getHeightMapAt(temp);
|
|
- TerrainQuad q = new TerrainQuad(getName() + "Quad" + temp, patchSize, quadSize, heightMapAt == null ? null : heightMapAt.getHeightMap(), lodCalculatorFactory);
|
|
|
|
|
|
+ q = new TerrainQuad(getName() + "Quad" + temp, patchSize, quadSize, totalSize, heightMapAt == null ? null : heightMapAt.getHeightMap(), lodCalculatorFactory);
|
|
Material mat = material.clone();
|
|
Material mat = material.clone();
|
|
for (TerrainGridListener l : listeners.values()) {
|
|
for (TerrainGridListener l : listeners.values()) {
|
|
mat = l.tileLoaded(mat, temp);
|
|
mat = l.tileLoaded(mat, temp);
|
|
}
|
|
}
|
|
q.setMaterial(mat);
|
|
q.setMaterial(mat);
|
|
- cache.put(temp, q);
|
|
|
|
|
|
+ log.log(Level.FINE, "Loaded TerrainQuad {0}", q.getName());
|
|
|
|
+ }
|
|
|
|
+ cache.put(temp, q);
|
|
|
|
+
|
|
|
|
+ if (isCenter(quadIdx)) {
|
|
|
|
+ // if it should be attached as a child right now, attach it
|
|
|
|
+ final int quadrant = getQuadrant(quadIdx);
|
|
|
|
+ final TerrainQuad newQuad = q;
|
|
|
|
+ // back on the OpenGL thread:
|
|
|
|
+ getControl(UpdateControl.class).enqueue(new Callable() {
|
|
|
|
+ public Object call() throws Exception {
|
|
|
|
+ attachQuadAt(newQuad, quadrant, temp);
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ private boolean isCenter(int quadIndex) {
|
|
|
|
+ return quadIndex == 9 || quadIndex == 5 || quadIndex == 10 || quadIndex == 6;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private int getQuadrant(int quadIndex) {
|
|
|
|
+ if (quadIndex == 9)
|
|
|
|
+ return 1;
|
|
|
|
+ else if (quadIndex == 5)
|
|
|
|
+ return 2;
|
|
|
|
+ else if (quadIndex == 10)
|
|
|
|
+ return 3;
|
|
|
|
+ else if (quadIndex == 6)
|
|
|
|
+ return 4;
|
|
|
|
+ return 0; // error
|
|
|
|
+ }
|
|
|
|
|
|
- public TerrainGrid(String name, int patchSize, int size, Vector3f stepScale, HeightMapGrid heightMapGrid, int totalSize,
|
|
|
|
|
|
+ public TerrainGrid(String name, int patchSize, int maxVisibleSize, Vector3f scale, HeightMapGrid heightMapGrid,
|
|
Vector2f offset, float offsetAmount, LodCalculatorFactory lodCalculatorFactory) {
|
|
Vector2f offset, float offsetAmount, LodCalculatorFactory lodCalculatorFactory) {
|
|
this.name = name;
|
|
this.name = name;
|
|
this.patchSize = patchSize;
|
|
this.patchSize = patchSize;
|
|
- this.size = size;
|
|
|
|
- this.quarterSize = size >> 2;
|
|
|
|
- this.quadSize = (size + 1) >> 1;
|
|
|
|
- this.stepScale = stepScale;
|
|
|
|
|
|
+ this.size = maxVisibleSize;
|
|
|
|
+ this.quarterSize = maxVisibleSize >> 2;
|
|
|
|
+ this.quadSize = (maxVisibleSize + 1) >> 1;
|
|
|
|
+ this.stepScale = scale;
|
|
this.heightMapGrid = heightMapGrid;
|
|
this.heightMapGrid = heightMapGrid;
|
|
heightMapGrid.setSize(this.quadSize);
|
|
heightMapGrid.setSize(this.quadSize);
|
|
- this.totalSize = totalSize;
|
|
|
|
|
|
+ this.totalSize = maxVisibleSize;
|
|
this.offset = offset;
|
|
this.offset = offset;
|
|
this.offsetAmount = offsetAmount;
|
|
this.offsetAmount = offsetAmount;
|
|
this.lodCalculatorFactory = lodCalculatorFactory;
|
|
this.lodCalculatorFactory = lodCalculatorFactory;
|
|
if (lodCalculatorFactory == null) {
|
|
if (lodCalculatorFactory == null) {
|
|
lodCalculatorFactory = new LodDistanceCalculatorFactory();
|
|
lodCalculatorFactory = new LodDistanceCalculatorFactory();
|
|
}
|
|
}
|
|
- this.quadOrigins = new Vector3f[]{new Vector3f(-this.quarterSize, 0, -this.quarterSize).mult(this.stepScale),
|
|
|
|
- new Vector3f(-this.quarterSize, 0, this.quarterSize).mult(this.stepScale),
|
|
|
|
- new Vector3f(this.quarterSize, 0, -this.quarterSize).mult(this.stepScale),
|
|
|
|
- new Vector3f(this.quarterSize, 0, this.quarterSize).mult(this.stepScale)};
|
|
|
|
|
|
+// this.quadOrigins = new Vector3f[]{
|
|
|
|
+// new Vector3f(-this.quarterSize, 0, -this.quarterSize).mult(this.stepScale),
|
|
|
|
+// new Vector3f(-this.quarterSize, 0, this.quarterSize).mult(this.stepScale),
|
|
|
|
+// new Vector3f(this.quarterSize, 0, -this.quarterSize).mult(this.stepScale),
|
|
|
|
+// new Vector3f(this.quarterSize, 0, this.quarterSize).mult(this.stepScale)};
|
|
this.quadIndex = new Vector3f[]{
|
|
this.quadIndex = new Vector3f[]{
|
|
- new Vector3f(-1, 0, -1), new Vector3f(-1, 0, 0), new Vector3f(-1, 0, 1), new Vector3f(-1, 0, 2),
|
|
|
|
- new Vector3f(0, 0, -1), new Vector3f(0, 0, 0), new Vector3f(0, 0, 1), new Vector3f(0, 0, 2),
|
|
|
|
- new Vector3f(1, 0, -1), new Vector3f(1, 0, 0), new Vector3f(1, 0, 1), new Vector3f(1, 0, 2),
|
|
|
|
- new Vector3f(2, 0, -1), new Vector3f(2, 0, 0), new Vector3f(2, 0, 1), new Vector3f(2, 0, 2)};
|
|
|
|
|
|
+ new Vector3f(-1, 0, 2), new Vector3f(0, 0, 2), new Vector3f(1, 0, 2), new Vector3f(2, 0, 2),
|
|
|
|
+ new Vector3f(-1, 0, 1), new Vector3f(0, 0, 1), new Vector3f(1, 0, 1), new Vector3f(2, 0, 1),
|
|
|
|
+ new Vector3f(-1, 0, 0), new Vector3f(0, 0, 0), new Vector3f(1, 0, 0), new Vector3f(2, 0, 0),
|
|
|
|
+ new Vector3f(-1, 0, -1), new Vector3f(0, 0, -1), new Vector3f(1, 0, -1), new Vector3f(-2, 0, -1)};
|
|
|
|
+
|
|
|
|
+ addControl(new UpdateControl());
|
|
}
|
|
}
|
|
|
|
|
|
- public TerrainGrid(String name, int patchSize, int size, Vector3f scale, HeightMapGrid heightMapGrid,
|
|
|
|
|
|
+ public TerrainGrid(String name, int patchSize, int maxVisibleSize, Vector3f scale, HeightMapGrid heightMapGrid,
|
|
LodCalculatorFactory lodCalculatorFactory) {
|
|
LodCalculatorFactory lodCalculatorFactory) {
|
|
- this(name, patchSize, size, scale, heightMapGrid, size, new Vector2f(), 0, lodCalculatorFactory);
|
|
|
|
|
|
+ this(name, patchSize, maxVisibleSize, scale, heightMapGrid, new Vector2f(), 0, lodCalculatorFactory);
|
|
}
|
|
}
|
|
|
|
|
|
- public TerrainGrid(String name, int patchSize, int totalSize, HeightMapGrid heightMapGrid, LodCalculatorFactory lodCalculatorFactory) {
|
|
|
|
- this(name, patchSize, totalSize, Vector3f.UNIT_XYZ, heightMapGrid, lodCalculatorFactory);
|
|
|
|
|
|
+ public TerrainGrid(String name, int patchSize, int maxVisibleSize, HeightMapGrid heightMapGrid, LodCalculatorFactory lodCalculatorFactory) {
|
|
|
|
+ this(name, patchSize, maxVisibleSize, Vector3f.UNIT_XYZ, heightMapGrid, lodCalculatorFactory);
|
|
}
|
|
}
|
|
|
|
|
|
- public TerrainGrid(String name, int patchSize, int totalSize, HeightMapGrid heightMapGrid) {
|
|
|
|
- this(name, patchSize, totalSize, heightMapGrid, null);
|
|
|
|
|
|
+ public TerrainGrid(String name, int patchSize, int maxVisibleSize, HeightMapGrid heightMapGrid) {
|
|
|
|
+ this(name, patchSize, maxVisibleSize, heightMapGrid, null);
|
|
}
|
|
}
|
|
|
|
|
|
public TerrainGrid() {
|
|
public TerrainGrid() {
|
|
@@ -164,13 +224,18 @@ public class TerrainGrid extends TerrainQuad {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Runs on the rendering thread
|
|
|
|
+ */
|
|
protected void attachQuadAt(TerrainQuad q, int quadrant, Vector3f cam) {
|
|
protected void attachQuadAt(TerrainQuad q, int quadrant, Vector3f cam) {
|
|
|
|
+ this.removeQuad(quadrant);
|
|
//q.setMaterial(this.material);
|
|
//q.setMaterial(this.material);
|
|
//q.setLocalTranslation(quadOrigins[quadrant - 1]);
|
|
//q.setLocalTranslation(quadOrigins[quadrant - 1]);
|
|
q.setQuadrant((short) quadrant);
|
|
q.setQuadrant((short) quadrant);
|
|
this.attachChild(q);
|
|
this.attachChild(q);
|
|
|
|
|
|
- q.setLocalTranslation(cam.mult(this.quadSize).add(quadOrigins[quadrant-1]));
|
|
|
|
|
|
+ Vector3f loc = cam.mult(this.quadSize-1).subtract(quarterSize, 0, quarterSize);// quadrant location handled TerrainQuad automatically now
|
|
|
|
+ q.setLocalTranslation(loc );
|
|
|
|
|
|
if (quadControls != null) {
|
|
if (quadControls != null) {
|
|
quadControls[quadrant - 1].setEnabled(false);
|
|
quadControls[quadrant - 1].setEnabled(false);
|
|
@@ -181,6 +246,8 @@ public class TerrainGrid extends TerrainQuad {
|
|
//quadControls[quadrant - 1].setPhysicsLocation(cam.add(this.quadOrigins[quadrant - 1]));
|
|
//quadControls[quadrant - 1].setPhysicsLocation(cam.add(this.quadOrigins[quadrant - 1]));
|
|
} else {
|
|
} else {
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ updateModelBound();
|
|
}
|
|
}
|
|
|
|
|
|
private void updateChildrens(Vector3f cam) {
|
|
private void updateChildrens(Vector3f cam) {
|
|
@@ -203,11 +270,14 @@ public class TerrainGrid extends TerrainQuad {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- TerrainQuad q1 = cache.get(cam.add(quadIndex[5]));
|
|
|
|
- TerrainQuad q2 = cache.get(cam.add(quadIndex[6]));
|
|
|
|
- TerrainQuad q3 = cache.get(cam.add(quadIndex[9]));
|
|
|
|
- TerrainQuad q4 = cache.get(cam.add(quadIndex[10]));
|
|
|
|
|
|
+ //TerrainQuad q1 = cache.get(cam.add(quadIndex[9]));
|
|
|
|
+ //TerrainQuad q2 = cache.get(cam.add(quadIndex[5]));
|
|
|
|
+ //TerrainQuad q3 = cache.get(cam.add(quadIndex[10]));
|
|
|
|
+ //TerrainQuad q4 = cache.get(cam.add(quadIndex[6]));
|
|
|
|
|
|
|
|
+ // ---------------------------------------------------
|
|
|
|
+ // what does this block do?
|
|
|
|
+ // ---------------------------------------------------
|
|
int dx = 0;
|
|
int dx = 0;
|
|
int dy = 0;
|
|
int dy = 0;
|
|
if (currentCell != null) {
|
|
if (currentCell != null) {
|
|
@@ -236,16 +306,21 @@ public class TerrainGrid extends TerrainQuad {
|
|
cache.get(cam.add(quadIndex[i * 4 + j]));
|
|
cache.get(cam.add(quadIndex[i * 4 + j]));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
- if (q1 == null || q2 == null || q3 == null || q4 == null) {
|
|
|
|
|
|
+ // ---------------------------------------------------
|
|
|
|
+ // ---------------------------------------------------
|
|
|
|
+
|
|
|
|
+ if (executor == null)
|
|
|
|
+ executor = createExecutorService();
|
|
|
|
+
|
|
|
|
+ executor.submit(new UpdateQuadCache(cam));
|
|
|
|
+
|
|
|
|
+/* if (q1 == null || q2 == null || q3 == null || q4 == null) {
|
|
try {
|
|
try {
|
|
- if (executor == null)
|
|
|
|
- executor = createExecutorService();
|
|
|
|
- executor.submit(new UpdateQuadCache(cam, true)).get();
|
|
|
|
- q1 = cache.get(cam.add(quadIndex[5]));
|
|
|
|
- q2 = cache.get(cam.add(quadIndex[6]));
|
|
|
|
- q3 = cache.get(cam.add(quadIndex[9]));
|
|
|
|
- q4 = cache.get(cam.add(quadIndex[10]));
|
|
|
|
|
|
+ executor.submit(new UpdateQuadCache(cam, true)).get(); // BLOCKING
|
|
|
|
+ q1 = cache.get(cam.add(quadIndex[9]));
|
|
|
|
+ q2 = cache.get(cam.add(quadIndex[5]));
|
|
|
|
+ q3 = cache.get(cam.add(quadIndex[10]));
|
|
|
|
+ q4 = cache.get(cam.add(quadIndex[6]));
|
|
} catch (InterruptedException ex) {
|
|
} catch (InterruptedException ex) {
|
|
Logger.getLogger(TerrainGrid.class.getName()).log(Level.SEVERE, null, ex);
|
|
Logger.getLogger(TerrainGrid.class.getName()).log(Level.SEVERE, null, ex);
|
|
return;
|
|
return;
|
|
@@ -263,15 +338,15 @@ public class TerrainGrid extends TerrainQuad {
|
|
this.removeQuad(3);
|
|
this.removeQuad(3);
|
|
this.removeQuad(4);
|
|
this.removeQuad(4);
|
|
|
|
|
|
- attachQuadAt(q1, 1, cam);
|
|
|
|
- attachQuadAt(q2, 2, cam);
|
|
|
|
- attachQuadAt(q3, 3, cam);
|
|
|
|
- attachQuadAt(q4, 4, cam);
|
|
|
|
-
|
|
|
|
|
|
+ attachQuadAt(q1, 1, cam); // quadIndex[9]
|
|
|
|
+ attachQuadAt(q2, 2, cam); // quadIndex[5]
|
|
|
|
+ attachQuadAt(q3, 3, cam); // quadIndex[10]
|
|
|
|
+ attachQuadAt(q4, 4, cam); // quadIndex[6]
|
|
|
|
+*/
|
|
this.currentCell = cam;
|
|
this.currentCell = cam;
|
|
- this.updateModelBound();
|
|
|
|
|
|
+// this.updateModelBound();
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
public void addListener(String id, TerrainGridListener listener) {
|
|
public void addListener(String id, TerrainGridListener listener) {
|
|
this.listeners.put(id, listener);
|
|
this.listeners.put(id, listener);
|
|
}
|
|
}
|
|
@@ -293,4 +368,15 @@ public class TerrainGrid extends TerrainQuad {
|
|
public void setQuadSize(int quadSize) {
|
|
public void setQuadSize(int quadSize) {
|
|
this.quadSize = quadSize;
|
|
this.quadSize = quadSize;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void adjustHeight(List<Vector2f> xz, List<Float> height) {
|
|
|
|
+ Vector3f currentGridLocation = getCurrentCell().mult( getLocalScale() ).multLocal( quadSize-1 );
|
|
|
|
+ for ( Vector2f vect : xz )
|
|
|
|
+ {
|
|
|
|
+ vect.x -= currentGridLocation.x;
|
|
|
|
+ vect.y -= currentGridLocation.z;
|
|
|
|
+ }
|
|
|
|
+ super.adjustHeight( xz, height );
|
|
|
|
+ }
|
|
}
|
|
}
|