From 58ede837c6afb8876e9919b9db5859fafdeceff5 Mon Sep 17 00:00:00 2001 From: "ant..om" Date: Sat, 28 May 2011 18:48:27 +0000 Subject: [PATCH] Added my own noise library as jar (noise-0.0.1-SNAPSHOT.jar), hope I didn't break any build stuff TerrainGridTest is running smooth now using 257x257 sized TerrainQuads with fractal based heightmaps calculated on the fly. git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7529 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- engine/lib/nblibraries.properties | 2 + engine/lib/noise/noise-0.0.1-SNAPSHOT.jar | Bin 0 -> 28291 bytes engine/nbproject/project.properties | 225 +++++++++--------- .../terrain/com/jme3/terrain/MapUtils.java | 62 +++++ .../com/jme3/terrain/geomipmap/LRUCache.java | 124 ++++++++++ .../jme3/terrain/geomipmap/TerrainGrid.java | 168 ++++++++----- .../terrain/geomipmap/TerrainLodControl.java | 54 +++-- .../jme3/terrain/geomipmap/TerrainQuad.java | 138 +++++------ .../heightmap/FractalHeightMapGrid.java | 75 ++++++ .../heightmap/ImageBasedHeightMapGrid.java | 8 +- .../jme3test/terrain/TerrainGridTest.java | 55 ++++- 11 files changed, 638 insertions(+), 273 deletions(-) create mode 100644 engine/lib/noise/noise-0.0.1-SNAPSHOT.jar create mode 100644 engine/src/terrain/com/jme3/terrain/MapUtils.java create mode 100644 engine/src/terrain/com/jme3/terrain/geomipmap/LRUCache.java create mode 100644 engine/src/terrain/com/jme3/terrain/heightmap/FractalHeightMapGrid.java diff --git a/engine/lib/nblibraries.properties b/engine/lib/nblibraries.properties index f490864b7..d64748a85 100644 --- a/engine/lib/nblibraries.properties +++ b/engine/lib/nblibraries.properties @@ -54,4 +54,6 @@ libs.swing-layout.javadoc=\ ${base}/swing-layout/swing-layout-1.0.4-doc.zip libs.swing-layout.src=\ ${base}/swing-layout/swing-layout-1.0.4-src.zip +libs.noise.classpath=\ + ${base}/noise/noise-0.0.1-SNAPSHOT.jar diff --git a/engine/lib/noise/noise-0.0.1-SNAPSHOT.jar b/engine/lib/noise/noise-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..62dc1f17d331b641a26764d6f9f8a72f976dbe2c GIT binary patch literal 28291 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 literal 0 HcmV?d00001 diff --git a/engine/nbproject/project.properties b/engine/nbproject/project.properties index fbee1d131..876511762 100644 --- a/engine/nbproject/project.properties +++ b/engine/nbproject/project.properties @@ -1,112 +1,113 @@ -annotation.processing.enabled=false -annotation.processing.enabled.in.editor=false -annotation.processing.run.all.processors=true -ant.customtasks.libs=JWSAntTasks -application.homepage=http://www.jmonkeyengine.com/ -application.title=jMonkeyEngine 3.0 -application.vendor=jMonkeyEngine -build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java,**/*.form -# This directory is removed when the project is cleaned: -build.dir=build -build.generated.dir=${build.dir}/generated -build.generated.sources.dir=${build.dir}/generated-sources -# Only compile against the classpath explicitly listed here: -build.sysclasspath=ignore -build.test.classes.dir=${build.dir}/test/classes -build.test.results.dir=${build.dir}/test/results -# Uncomment to specify the preferred debugger connection transport: -#debug.transport=dt_socket -debug.classpath=\ - ${run.classpath} -debug.test.classpath=\ - ${run.test.classpath} -# This directory is removed when the project is cleaned: -dist.dir=dist -dist.jar=${dist.dir}/jMonkeyEngine3.jar -dist.javadoc.dir=${dist.dir}/javadoc -endorsed.classpath= -excludes= -file.reference.src-test-data=src/test-data -includes=** -jar.archive.disabled=${jnlp.enabled} -jar.compress=true -jar.index=${jnlp.enabled} -javac.classpath=\ - ${libs.jogg.classpath}:\ - ${libs.jbullet.classpath}:\ - ${libs.bullet.classpath}:\ - ${libs.lwjgl.classpath}:\ - ${libs.jheora.classpath}:\ - ${libs.niftygui1.3.classpath}:\ - ${libs.jme3-test-data.classpath} -# Space-separated list of extra javac options -javac.compilerargs= -javac.deprecation=false -javac.processorpath=\ - ${javac.classpath} -javac.source=1.5 -javac.target=1.5 -javac.test.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir}:\ - ${libs.junit_4.classpath} -javadoc.additionalparam= -javadoc.author=false -javadoc.encoding=${source.encoding} -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false -javadoc.private=false -javadoc.splitindex=true -javadoc.use=true -javadoc.version=false -javadoc.windowtitle=jMonkeyEngine3 -jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api" -jnlp.applet.class=jme3test.awt.AppHarness -jnlp.applet.height=300 -jnlp.applet.width=300 -jnlp.codebase.type=user -jnlp.codebase.user=http://jmonkeyengine.com/javawebstart/ -jnlp.descriptor=application -jnlp.enabled=false -jnlp.icon=/Users/normenhansen/Pictures/jme/icons/jme-logo48.png -jnlp.mixed.code=default -jnlp.offline-allowed=true -jnlp.signed=true -jnlp.signing=generated -jnlp.signing.alias= -jnlp.signing.keystore= -main.class=jme3test.TestChooser -manifest.file=MANIFEST.MF -meta.inf.dir=${src.dir}/META-INF -mkdist.disabled=false -platform.active=default_platform -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -run.jvmargs=-Xms40m -Xmx40m -XX:MaxDirectMemorySize=256M -run.test.classpath=\ - ${javac.test.classpath}:\ - ${build.test.classes.dir} -source.encoding=UTF-8 -src.core-data.dir=src/core-data -src.core-plugins.dir=src/core-plugins -src.core.dir=src/core -src.desktop-fx.dir=src/desktop-fx -src.desktop.dir=src/desktop -src.games.dir=src/games -src.jbullet.dir=src/jbullet -src.jheora.dir=src/jheora -src.jogg.dir=src/jogg -src.lwjgl-oal.dir=src/lwjgl-oal -src.lwjgl-ogl.dir=src/lwjgl-ogl -src.networking.dir=src\\networking -src.niftygui.dir=src/niftygui -src.ogre.dir=src/ogre -src.pack.dir=src/pack -src.terrain.dir=src/terrain -src.test.dir=src/test -src.tools.dir=src/tools -src.xml.dir=src/xml -test.test.dir=test +annotation.processing.enabled=false +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +ant.customtasks.libs=JWSAntTasks +application.homepage=http://www.jmonkeyengine.com/ +application.title=jMonkeyEngine 3.0 +application.vendor=jMonkeyEngine +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/jMonkeyEngine3.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.src-test-data=src/test-data +includes=** +jar.archive.disabled=${jnlp.enabled} +jar.compress=true +jar.index=${jnlp.enabled} +javac.classpath=\ + ${libs.jogg.classpath}:\ + ${libs.jbullet.classpath}:\ + ${libs.bullet.classpath}:\ + ${libs.lwjgl.classpath}:\ + ${libs.jheora.classpath}:\ + ${libs.niftygui1.3.classpath}:\ + ${libs.jme3-test-data.classpath}:\ + ${libs.noise.classpath} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit_4.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle=jMonkeyEngine3 +jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api" +jnlp.applet.class=jme3test.awt.AppHarness +jnlp.applet.height=300 +jnlp.applet.width=300 +jnlp.codebase.type=user +jnlp.codebase.user=http://jmonkeyengine.com/javawebstart/ +jnlp.descriptor=application +jnlp.enabled=false +jnlp.icon=/Users/normenhansen/Pictures/jme/icons/jme-logo48.png +jnlp.mixed.code=default +jnlp.offline-allowed=true +jnlp.signed=true +jnlp.signing=generated +jnlp.signing.alias= +jnlp.signing.keystore= +main.class=jme3test.TestChooser +manifest.file=MANIFEST.MF +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +run.jvmargs=-Xms40m -Xmx40m -XX:MaxDirectMemorySize=256M +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.core-data.dir=src/core-data +src.core-plugins.dir=src/core-plugins +src.core.dir=src/core +src.desktop-fx.dir=src/desktop-fx +src.desktop.dir=src/desktop +src.games.dir=src/games +src.jbullet.dir=src/jbullet +src.jheora.dir=src/jheora +src.jogg.dir=src/jogg +src.lwjgl-oal.dir=src/lwjgl-oal +src.lwjgl-ogl.dir=src/lwjgl-ogl +src.networking.dir=src\\networking +src.niftygui.dir=src/niftygui +src.ogre.dir=src/ogre +src.pack.dir=src/pack +src.terrain.dir=src/terrain +src.test.dir=src/test +src.tools.dir=src/tools +src.xml.dir=src/xml +test.test.dir=test diff --git a/engine/src/terrain/com/jme3/terrain/MapUtils.java b/engine/src/terrain/com/jme3/terrain/MapUtils.java new file mode 100644 index 000000000..192ebf979 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/MapUtils.java @@ -0,0 +1,62 @@ +package com.jme3.terrain; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.FloatBuffer; +import java.util.logging.Logger; + +import javax.imageio.ImageIO; + +import org.novyon.noise.ShaderUtils; + +public class MapUtils { + + public static FloatBuffer clip(FloatBuffer src, int origSize, int newSize, int offset) { + FloatBuffer result = FloatBuffer.allocate(newSize * newSize); + + float[] orig = src.array(); + for (int i = offset; i < offset + newSize; i++) { + result.put(orig, i * origSize + offset, newSize); + } + + return result; + } + + public static BufferedImage toGrayscale16Image(FloatBuffer buff, int size) { + BufferedImage retval = new BufferedImage(size, size, BufferedImage.TYPE_USHORT_GRAY); + buff.rewind(); + for (int y = 0; y < size; y++) { + for (int x = 0; x < size; x++) { + short c = (short) (ShaderUtils.clamp(buff.get(), 0, 1) * 65532); + retval.getRaster().setDataElements(x, y, new short[] { c }); + } + } + return retval; + } + + public static BufferedImage toGrayscaleRGBImage(FloatBuffer buff, int size) { + BufferedImage retval = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB); + buff.rewind(); + for (int y = 0; y < size; y++) { + for (int x = 0; x < size; x++) { + int c = (int) (ShaderUtils.clamp(buff.get(), 0, 1) * 255); + retval.setRGB(x, y, 0xFF000000 | c << 16 | c << 8 | c); + } + } + return retval; + } + + public static void saveImage(BufferedImage im, String file) { + MapUtils.saveImage(im, new File(file)); + } + + public static void saveImage(BufferedImage im, File file) { + try { + ImageIO.write(im, "PNG", file); + Logger.getLogger(MapUtils.class.getCanonicalName()).info("Saved image as : " + file.getAbsolutePath()); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/LRUCache.java b/engine/src/terrain/com/jme3/terrain/geomipmap/LRUCache.java new file mode 100644 index 000000000..81f2c5641 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/LRUCache.java @@ -0,0 +1,124 @@ +package com.jme3.terrain.geomipmap; + +// Copyright 2007 Christian d'Heureuse, Inventec Informatik AG, Zurich, +// Switzerland +// www.source-code.biz, www.inventec.ch/chdh +// +// This module is multi-licensed and may be used under the terms +// of any of the following licenses: +// +// EPL, Eclipse Public License, V1.0 or later, http://www.eclipse.org/legal +// LGPL, GNU Lesser General Public License, V2 or later, +// http://www.gnu.org/licenses/lgpl.html +// GPL, GNU General Public License, V2 or later, +// http://www.gnu.org/licenses/gpl.html +// AL, Apache License, V2.0 or later, http://www.apache.org/licenses +// BSD, BSD License, http://www.opensource.org/licenses/bsd-license.php +// +// Please contact the author if you need another license. +// This module is provided "as is", without warranties of any kind. + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * An LRU cache, based on LinkedHashMap. + * + *

+ * This cache has a fixed maximum number of elements (cacheSize). + * If the cache is full and another entry is added, the LRU (least recently + * used) entry is dropped. + * + *

+ * This class is thread-safe. All methods of this class are synchronized. + * + *

+ * Author: Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland
+ * Multi-licensed: EPL / LGPL / GPL / AL / BSD. + */ +public class LRUCache { + + private static final float hashTableLoadFactor = 0.75f; + + private LinkedHashMap map; + private int cacheSize; + + /** + * Creates a new LRU cache. + * + * @param cacheSize + * the maximum number of entries that will be kept in this cache. + */ + public LRUCache(int cacheSize) { + this.cacheSize = cacheSize; + int hashTableCapacity = (int) Math.ceil(cacheSize / LRUCache.hashTableLoadFactor) + 1; + this.map = new LinkedHashMap(hashTableCapacity, LRUCache.hashTableLoadFactor, true) { + // (an anonymous inner class) + private static final long serialVersionUID = 1; + + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return this.size() > LRUCache.this.cacheSize; + } + }; + } + + /** + * Retrieves an entry from the cache.
+ * The retrieved entry becomes the MRU (most recently used) entry. + * + * @param key + * the key whose associated value is to be returned. + * @return the value associated to this key, or null if no value with this + * key exists in the cache. + */ + public synchronized V get(K key) { + return this.map.get(key); + } + + /** + * Adds an entry to this cache. + * The new entry becomes the MRU (most recently used) entry. + * If an entry with the specified key already exists in the cache, it is + * replaced by the new entry. + * If the cache is full, the LRU (least recently used) entry is removed from + * the cache. + * + * @param key + * the key with which the specified value is to be associated. + * @param value + * a value to be associated with the specified key. + */ + public synchronized void put(K key, V value) { + this.map.put(key, value); + } + + /** + * Clears the cache. + */ + public synchronized void clear() { + this.map.clear(); + } + + /** + * Returns the number of used entries in the cache. + * + * @return the number of entries currently in the cache. + */ + public synchronized int usedEntries() { + return this.map.size(); + } + + /** + * Returns a Collection that contains a copy of all cache + * entries. + * + * @return a Collection with a copy of the cache content. + */ + public synchronized Collection> getAll() { + return new ArrayList>(this.map.entrySet()); + } + +} // end class LRUCache diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java index bb3f3d69c..52d7db166 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java @@ -11,6 +11,8 @@ import com.jme3.terrain.heightmap.HeightMap; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.logging.Level; import java.util.logging.Logger; import com.jme3.material.Material; @@ -35,6 +37,37 @@ public class TerrainGrid extends TerrainQuad { private Vector3f[] quadIndex; private Map listeners = new HashMap(); private Material material; + private LRUCache cache = new LRUCache(16); + + private class UpdateQuadCache implements Runnable { + + private final Vector3f location; + private final boolean centerOnly; + + public UpdateQuadCache(Vector3f location) { + this.location = location; + this.centerOnly = false; + } + + public UpdateQuadCache(Vector3f location, boolean centerOnly) { + this.location = location; + this.centerOnly = centerOnly; + } + + 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) { + HeightMap heightMapAt = heightMapGrid.getHeightMapAt(temp); + TerrainQuad q = new TerrainQuad(getName() + "Quad" + temp, patchSize, quadSize, heightMapAt == null ? null : heightMapAt.getHeightMap(), lodCalculatorFactory); + cache.put(temp, q); + } + } + } + + } + } public TerrainGrid(String name, int patchSize, int size, Vector3f stepScale, HeightMapGrid heightMapGrid, int totalSize, Vector2f offset, float offsetAmount, LodCalculatorFactory lodCalculatorFactory) { @@ -57,7 +90,11 @@ public class TerrainGrid extends TerrainQuad { 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[]{new Vector3f(0, 0, 0), new Vector3f(0, 0, 1), new Vector3f(1, 0, 0), new Vector3f(1, 0, 1)}; + 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)}; updateChildrens(Vector3f.ZERO); } @@ -93,7 +130,7 @@ public class TerrainGrid extends TerrainQuad { } } - //super.update(locations); + super.update(locations); } public Vector3f getCell(Vector3f location) { @@ -102,7 +139,9 @@ public class TerrainGrid extends TerrainQuad { } protected void removeQuad(int idx) { - this.detachChild(this.getQuad(idx)); + if (this.getQuad(idx) != null) { + this.detachChild(this.getQuad(idx)); + } } protected void moveQuad(int from, int to) { @@ -112,16 +151,66 @@ public class TerrainGrid extends TerrainQuad { fq.setLocalTranslation(this.quadOrigins[to - 1]); } - protected TerrainQuad createQuadAt(Vector3f location, int quadrant) { - final HeightMap heightMapAt = this.heightMapGrid.getHeightMapAt(location); - TerrainQuad q = new TerrainQuad(this.getName() + "Quad" + location, this.patchSize, this.quadSize, heightMapAt == null ? null : heightMapAt.getHeightMap(), this.lodCalculatorFactory); - q.setLocalTranslation(this.quadOrigins[quadrant - 1]); + protected void attachQuadAt(TerrainQuad q, int quadrant) { q.setMaterial(this.material); + q.setLocalTranslation(quadOrigins[quadrant - 1]); q.setQuadrant((short) quadrant); - return q; + this.attachChild(q); } private void updateChildrens(Vector3f cam) { + 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])); + + int dx = 0; + int dy = 0; + if (currentCell != null) { + dx = (int) (cam.x - currentCell.x); + dy = (int) (cam.z - currentCell.z); + } + + int kxm = 0; + int kxM = 4; + int kym = 0; + int kyM = 4; + if (dx == -1) { + kxM = 3; + } else if (dx == 1) { + kxm = 1; + } + + if (dy == -1) { + kyM = 3; + } else if (dy == 1) { + kym = 1; + } + + for (int i=kym; i 1 || FastMath.abs(dz) > 1 || (dx != 0 && dz != 0)) { - if (this.currentCell != null) { - // in case of teleport, otherwise the FastMath.abs(delta) should - // never be greater than 1 - this.removeQuad(1); - this.removeQuad(2); - this.removeQuad(3); - this.removeQuad(4); - } - this.attachChild(this.createQuadAt(cam.add(this.quadIndex[0]).mult(this.quadSize - 1), 1)); - this.attachChild(this.createQuadAt(cam.add(this.quadIndex[1]).mult(this.quadSize - 1), 2)); - this.attachChild(this.createQuadAt(cam.add(this.quadIndex[2]).mult(this.quadSize - 1), 3)); - this.attachChild(this.createQuadAt(cam.add(this.quadIndex[3]).mult(this.quadSize - 1), 4)); - } else if (dx == 0) { - if (dz < 0) { - // move north - this.moveQuad(1, 2); - this.moveQuad(3, 4); - this.attachChild(this.createQuadAt(cam.add(this.quadIndex[0]).mult(this.quadSize - 1), 1)); - this.attachChild(this.createQuadAt(cam.add(this.quadIndex[2]).mult(this.quadSize - 1), 3)); - } else { - // move south - this.moveQuad(2, 1); - this.moveQuad(4, 3); - this.attachChild(this.createQuadAt(cam.add(this.quadIndex[1]).mult(this.quadSize - 1), 2)); - this.attachChild(this.createQuadAt(cam.add(this.quadIndex[3]).mult(this.quadSize - 1), 4)); - } - } else if (dz == 0) { - if (dx < 0) { - // move west - this.moveQuad(1, 3); - this.moveQuad(2, 4); - this.attachChild(this.createQuadAt(cam.add(this.quadIndex[0]).mult(this.quadSize - 1), 1)); - this.attachChild(this.createQuadAt(cam.add(this.quadIndex[1]).mult(this.quadSize - 1), 2)); - } else { - // move east - this.moveQuad(3, 1); - this.moveQuad(4, 2); - this.attachChild(this.createQuadAt(cam.add(this.quadIndex[2]).mult(this.quadSize - 1), 3)); - this.attachChild(this.createQuadAt(cam.add(this.quadIndex[3]).mult(this.quadSize - 1), 4)); - } - } else { - // rare situation to enter into a diagonally placed cell - // could not get into this part while testing, as it is handled by moving first - // in either horizontally or vertically than the other way - // I handle it in the first IF - } + + this.removeQuad(1); + this.removeQuad(2); + this.removeQuad(3); + this.removeQuad(4); + attachQuadAt(q1, 1); + attachQuadAt(q2, 2); + attachQuadAt(q3, 3); + attachQuadAt(q4, 4); + this.currentCell = cam; this.setLocalTranslation(cam.mult(2 * this.quadSize)); diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainLodControl.java b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainLodControl.java index 17139414b..9cd2c82c2 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainLodControl.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainLodControl.java @@ -29,7 +29,6 @@ * 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; import com.jme3.export.InputCapsule; @@ -57,7 +56,7 @@ import java.util.ArrayList; * NOTE: right now it just uses the first camera passed in, * in the future it will use all of them to determine what * LOD to set. - * + * * @author Brent Owens */ public class TerrainLodControl extends AbstractControl { @@ -68,8 +67,8 @@ public class TerrainLodControl extends AbstractControl { public TerrainLodControl() { } - - /** + + /** * Only uses the first camera right now. * @param terrain to act upon (must be a Spatial) * @param cameras one or more cameras to reference for LOD calc @@ -80,52 +79,55 @@ public class TerrainLodControl extends AbstractControl { } this.cameras = cameras; } - - @Override - protected void controlRender(RenderManager rm, ViewPort vp) { - - } - @Override - protected void controlUpdate(float tpf) { - //list of cameras for when terrain supports multiple cameras (ie split screen) - + @Override + protected void controlRender(RenderManager rm, ViewPort vp) { + } + + @Override + protected void controlUpdate(float tpf) { + //list of cameras for when terrain supports multiple cameras (ie split screen) + if (cameras != null) { if (cameraLocations.isEmpty() && !cameras.isEmpty()) { for (Camera c : cameras) // populate them + { cameraLocations.add(c.getLocation()); + } } terrain.update(cameraLocations); } - } + } - public Control cloneForSpatial(Spatial spatial) { - if (spatial instanceof Terrain) { + public Control cloneForSpatial(Spatial spatial) { + if (spatial instanceof Terrain) { List cameraClone = new ArrayList(); if (cameras != null) { - for (Camera c : cameras) - cameraClone.add(c); + for (Camera c : cameras) { + cameraClone.add(c); + } } - return new TerrainLodControl((TerrainQuad)spatial, cameraClone); + return new TerrainLodControl((TerrainQuad) spatial, cameraClone); } - return null; - } - + return null; + } public void setCameras(List cameras) { this.cameras = cameras; cameraLocations.clear(); - for (Camera c : cameras) + for (Camera c : cameras) { cameraLocations.add(c.getLocation()); + } } @Override public void setSpatial(Spatial spatial) { super.setSpatial(spatial); - if (spatial instanceof TerrainQuad) - this.terrain = (TerrainQuad)spatial; + if (spatial instanceof TerrainQuad) { + this.terrain = (TerrainQuad) spatial; + } } - + public void setTerrain(TerrainQuad terrain) { this.terrain = terrain; } diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java index 998b70351..30af02967 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -73,9 +73,9 @@ import java.util.logging.Logger; * A terrain quad is a node in the quad tree of the terrain system. * The root terrain quad will be the only one that receives the update() call every frame * and it will determine if there has been any LOD change. - * + * * The leaves of the terrain quad tree are Terrain Patches. These have the real geometry mesh. - * + * * @author Brent Owens */ public class TerrainQuad extends Node implements Terrain { @@ -93,7 +93,7 @@ public class TerrainQuad extends Node implements Terrain { protected float offsetAmount; protected int quadrant = 1; // 1=upper left, 2=lower left, 3=upper right, 4=lower right - + protected LodCalculatorFactory lodCalculatorFactory; @@ -107,20 +107,20 @@ public class TerrainQuad extends Node implements Terrain { private TerrainPicker picker; - - private ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactory() { + + protected ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactory() { public Thread newThread(Runnable r) { Thread th = new Thread(r); th.setDaemon(true); return th; } }); - - + + public TerrainQuad() { super("Terrain"); } - + public TerrainQuad(String name, int patchSize, int totalSize, float[] heightMap) { this(name, patchSize, totalSize, heightMap, null); } @@ -135,7 +135,7 @@ public class TerrainQuad extends Node implements Terrain { fixNormalEdges(affectedAreaBBox); addControl(new NormalRecalcControl(this)); } - + protected TerrainQuad(String name, int patchSize, int size, Vector3f stepScale, float[] heightMap, int totalSize, Vector2f offset, float offsetAmount, @@ -145,7 +145,7 @@ public class TerrainQuad extends Node implements Terrain { if (!FastMath.isPowerOfTwo(size - 1)) { throw new RuntimeException("size given: " + size + " Terrain quad sizes may only be (2^N + 1)"); } - + if (heightMap == null) heightMap = generateDefaultHeightMap(size); @@ -158,7 +158,7 @@ public class TerrainQuad extends Node implements Terrain { this.lodCalculatorFactory = lodCalculatorFactory; split(patchSize, heightMap); } - + public void setLodCalculatorFactory(LodCalculatorFactory lodCalculatorFactory) { if (children != null) { for (int i = children.size(); --i >= 0;) { @@ -171,8 +171,8 @@ public class TerrainQuad extends Node implements Terrain { } } } - - + + /** * Create just a flat heightmap */ @@ -184,11 +184,11 @@ public class TerrainQuad extends Node implements Terrain { /** * Call from the update() method of a terrain controller to update * the LOD values of each patch. - * This will perform the geometry calculation in a background thread and + * This will perform the geometry calculation in a background thread and * do the actual update on the opengl thread. */ public void update(List locations) { - + updateLOD(locations); } @@ -197,12 +197,12 @@ public class TerrainQuad extends Node implements Terrain { * Should only be called on the root quad */ protected void updateNormals() { - + if (needToRecalculateNormals()) { //TODO background-thread this if it ends up being expensive fixNormals(affectedAreaBBox); // the affected patches fixNormalEdges(affectedAreaBBox); // the edges between the patches - + setNormalRecalcNeeded(null); // set to false } } @@ -234,11 +234,11 @@ public class TerrainQuad extends Node implements Terrain { UpdateLOD updateLodThread = new UpdateLOD(locations); executor.execute(updateLodThread); } - + private synchronized boolean isLodCalcRunning() { return lodCalcRunning; } - + private synchronized void setLodCalcRunning(boolean running) { lodCalcRunning = running; } @@ -327,17 +327,17 @@ public class TerrainQuad extends Node implements Terrain { public float getTextureCoordinateScale() { return 1f/(float)totalSize; } - + /** * Calculates the LOD of all child terrain patches. */ private class UpdateLOD implements Runnable { private List camLocations; - + UpdateLOD(List location) { camLocations = location; } - + public void run() { long start = System.currentTimeMillis(); if (isLodCalcRunning()) { @@ -346,11 +346,11 @@ public class TerrainQuad extends Node implements Terrain { } //System.out.println("spawned thread "+toString()); setLodCalcRunning(true); - + // go through each patch and calculate its LOD based on camera distance HashMap updated = new HashMap(); boolean lodChanged = calculateLod(camLocations, updated); // 'updated' gets populated here - + if (!lodChanged) { // not worth updating anything else since no one's LOD changed setLodCalcRunning(false); @@ -358,28 +358,28 @@ public class TerrainQuad extends Node implements Terrain { } // then calculate its neighbour LOD values for seaming in the shader findNeighboursLod(updated); - + fixEdges(updated); // 'updated' can get added to here - + reIndexPages(updated); - + setUpdateQuadLODs(updated); // set back to main ogl thread - + setLodCalcRunning(false); //double duration = (System.currentTimeMillis()-start); //System.out.println("terminated in "+duration); } - - + + } - + private void setUpdateQuadLODs(HashMap updated) { synchronized (updatePatchesLock) { updatedPatches = updated; } } - + /** * Back on the ogl thread: update the terrain patch geometries * @param updatedPatches to be updated @@ -390,20 +390,20 @@ public class TerrainQuad extends Node implements Terrain { // return; if (updatedPatches == null || updatedPatches.isEmpty()) return; - + //TODO do the actual geometry update here for (UpdatedTerrainPatch utp : updatedPatches.values()) { utp.updateAll(); } - + updatedPatches.clear(); } } - + protected boolean calculateLod(List location, HashMap updates) { - + boolean lodChanged = false; - + if (children != null) { for (int i = children.size(); --i >= 0;) { Spatial child = children.get(i); @@ -418,10 +418,10 @@ public class TerrainQuad extends Node implements Terrain { } } } - + return lodChanged; } - + protected synchronized void findNeighboursLod(HashMap updated) { if (children != null) { for (int x = children.size(); --x >= 0;) { @@ -441,20 +441,20 @@ public class TerrainQuad extends Node implements Terrain { } TerrainPatch right = patch.rightNeighbour; TerrainPatch down = patch.bottomNeighbour; - + UpdatedTerrainPatch utp = updated.get(patch.getName()); if (utp == null) { utp = new UpdatedTerrainPatch(patch, patch.lod); updated.put(utp.getName(), utp); } - + if (right != null) { UpdatedTerrainPatch utpR = updated.get(right.getName()); if (utpR == null) { utpR = new UpdatedTerrainPatch(right, right.lod); updated.put(utpR.getName(), utpR); } - + utp.setRightLod(utpR.getNewLod()); utpR.setLeftLod(utp.getNewLod()); } @@ -464,16 +464,16 @@ public class TerrainQuad extends Node implements Terrain { utpD = new UpdatedTerrainPatch(down, down.lod); updated.put(utpD.getName(), utpD); } - + utp.setBottomLod(utpD.getNewLod()); utpD.setTopLod(utp.getNewLod()); } - + } } } } - + /** * Find any neighbours that should have their edges seamed because another neighbour * changed its LOD to a greater value (less detailed) @@ -487,7 +487,7 @@ public class TerrainQuad extends Node implements Terrain { } else if (child instanceof TerrainPatch) { TerrainPatch patch = (TerrainPatch) child; UpdatedTerrainPatch utp = updated.get(patch.getName()); - + if(utp.lodChanged()) { if (!patch.searchedForNeighboursAlready) { // set the references to the neighbours @@ -538,7 +538,7 @@ public class TerrainQuad extends Node implements Terrain { } } } - + protected synchronized void reIndexPages(HashMap updated) { if (children != null) { for (int i = children.size(); --i >= 0;) { @@ -557,7 +557,7 @@ public class TerrainQuad extends Node implements Terrain { * children are either pages or blocks. This is dependent on the size of the * children. If the child's size is less than or equal to the set block * size, then blocks are created, otherwise, pages are created. - * + * * @param blockSize * the blocks size to test against. * @param heightMap @@ -784,7 +784,7 @@ public class TerrainQuad extends Node implements Terrain { patch4.setLodCalculator(lodCalculatorFactory); TangentBinormalGenerator.generate(patch4); } - + public float[] createHeightSubBlock(float[] heightMap, int x, int y, int side) { float[] rVal = new float[side * side]; @@ -804,7 +804,7 @@ public class TerrainQuad extends Node implements Terrain { * A handy method that will attach all bounding boxes of this terrain * to the node you supply. * Useful to visualize the bounding boxes when debugging. - * + * * @param parent that will get the bounding box shapes of the terrain attached to */ public void attachBoundChildren(Node parent) { @@ -1025,7 +1025,7 @@ public class TerrainQuad extends Node implements Terrain { if (!isPointOnTerrain(x,z)) return; - + adjustHeight(x, z,delta); setNormalRecalcNeeded(xz); @@ -1075,7 +1075,7 @@ public class TerrainQuad extends Node implements Terrain { } } - + // a position can be in multiple quadrants, so use a bit anded value. private int findQuadrant(int x, int y) { int split = (size + 1) >> 1; @@ -1109,7 +1109,7 @@ public class TerrainQuad extends Node implements Terrain { } } - + public int getQuadrant() { return quadrant; } @@ -1117,7 +1117,7 @@ public class TerrainQuad extends Node implements Terrain { public void setQuadrant(short quadrant) { this.quadrant = quadrant; } - + protected TerrainPatch getPatch(int quad) { if (children != null) @@ -1183,8 +1183,8 @@ public class TerrainQuad extends Node implements Terrain { return null; } - - + + protected TerrainPatch findTopPatch(TerrainPatch tp) { if (tp.getQuadrant() == 2) return getPatch(1); @@ -1203,7 +1203,7 @@ public class TerrainQuad extends Node implements Terrain { return null; } - + protected TerrainPatch findLeftPatch(TerrainPatch tp) { if (tp.getQuadrant() == 3) return getPatch(1); @@ -1268,7 +1268,7 @@ public class TerrainQuad extends Node implements Terrain { return null; } - + protected TerrainQuad findTopQuad() { if (getParent() == null || !(getParent() instanceof TerrainQuad)) return null; @@ -1291,7 +1291,7 @@ public class TerrainQuad extends Node implements Terrain { return null; } - + protected TerrainQuad findLeftQuad() { if (getParent() == null || !(getParent() instanceof TerrainQuad)) return null; @@ -1336,7 +1336,7 @@ public class TerrainQuad extends Node implements Terrain { } } } - + /** * fix the normals on the edge of the terrain patches. */ @@ -1372,13 +1372,13 @@ public class TerrainQuad extends Node implements Terrain { bottomLeft = findDownPatch(left); tp.fixNormalEdges(right, bottom, top, left, bottomRight, bottomLeft, topRight, topLeft); - + } } // for each child } - + @Override public int collideWith(Collidable other, CollisionResults results){ @@ -1397,7 +1397,7 @@ public class TerrainQuad extends Node implements Terrain { } return total; } - + /** * Gather the terrain patches that intersect the given ray (toTest). * This only tests the bounding boxes @@ -1405,7 +1405,7 @@ public class TerrainQuad extends Node implements Terrain { * @param results */ public void findPick(Ray toTest, List results) { - + if (getWorldBound() != null) { if (getWorldBound().intersects(toTest)) { // further checking needed. @@ -1460,7 +1460,7 @@ public class TerrainQuad extends Node implements Terrain { } } } - + @Override public void read(JmeImporter e) throws IOException { super.read(e); @@ -1472,7 +1472,7 @@ public class TerrainQuad extends Node implements Terrain { quadrant = c.readInt("quadrant", 0); totalSize = c.readInt("totalSize", 0); lodCalculatorFactory = (LodCalculatorFactory) c.readSavable("lodCalculatorFactory", null); - + // the terrain is re-built on load, so we need to run this once //affectedAreaBBox = new BoundingBox(new Vector3f(0,0,0), size, Float.MAX_VALUE, size); //updateNormals(); @@ -1541,13 +1541,13 @@ public class TerrainQuad extends Node implements Terrain { public int getTotalSize() { return totalSize; } - + public float[] getHeightMap() { //if (true) // return heightMap; - + float[] hm = null; int length = ((size-1)/2)+1; int area = size*size; @@ -1576,7 +1576,7 @@ public class TerrainQuad extends Node implements Terrain { } // combine them into a single heightmap - + // first upper blocks for (int y=0; y