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-0572b91ccdca3.0
parent
1fbd05a3ca
commit
58ede837c6
Binary file not shown.
@ -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 |
||||
|
@ -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(); |
||||
} |
||||
} |
||||
} |
@ -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 <code>LinkedHashMap</code>. |
||||
* |
||||
* <p> |
||||
* This cache has a fixed maximum number of elements (<code>cacheSize</code>). |
||||
* If the cache is full and another entry is added, the LRU (least recently |
||||
* used) entry is dropped. |
||||
* |
||||
* <p> |
||||
* This class is thread-safe. All methods of this class are synchronized. |
||||
* |
||||
* <p> |
||||
* Author: Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland<br> |
||||
* Multi-licensed: EPL / LGPL / GPL / AL / BSD. |
||||
*/ |
||||
public class LRUCache<K, V> { |
||||
|
||||
private static final float hashTableLoadFactor = 0.75f; |
||||
|
||||
private LinkedHashMap<K, V> 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<K, V>(hashTableCapacity, LRUCache.hashTableLoadFactor, true) { |
||||
// (an anonymous inner class)
|
||||
private static final long serialVersionUID = 1; |
||||
|
||||
@Override |
||||
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { |
||||
return this.size() > LRUCache.this.cacheSize; |
||||
} |
||||
}; |
||||
} |
||||
|
||||
/** |
||||
* Retrieves an entry from the cache.<br> |
||||
* 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 <code>Collection</code> that contains a copy of all cache |
||||
* entries. |
||||
* |
||||
* @return a <code>Collection</code> with a copy of the cache content. |
||||
*/ |
||||
public synchronized Collection<Map.Entry<K, V>> getAll() { |
||||
return new ArrayList<Map.Entry<K, V>>(this.map.entrySet()); |
||||
} |
||||
|
||||
} // end class LRUCache
|
@ -0,0 +1,75 @@ |
||||
package com.jme3.terrain.heightmap; |
||||
|
||||
import java.awt.image.BufferedImage; |
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.nio.FloatBuffer; |
||||
|
||||
import javax.imageio.ImageIO; |
||||
|
||||
import org.novyon.noise.Basis; |
||||
|
||||
import com.jme3.math.Vector3f; |
||||
import com.jme3.terrain.MapUtils; |
||||
|
||||
public class FractalHeightMapGrid implements HeightMapGrid { |
||||
|
||||
public class FloatBufferHeightMap extends AbstractHeightMap { |
||||
|
||||
private final FloatBuffer buffer; |
||||
|
||||
public FloatBufferHeightMap(FloatBuffer buffer) { |
||||
this.buffer = buffer; |
||||
} |
||||
|
||||
@Override |
||||
public boolean load() { |
||||
this.heightData = this.buffer.array(); |
||||
return true; |
||||
} |
||||
|
||||
} |
||||
|
||||
private int size; |
||||
private final Basis base; |
||||
private final String cacheDir; |
||||
private final float heightScale; |
||||
|
||||
public FractalHeightMapGrid(Basis base, String cacheDir, float heightScale) { |
||||
this.base = base; |
||||
this.cacheDir = cacheDir; |
||||
this.heightScale = heightScale; |
||||
} |
||||
|
||||
@Override |
||||
public HeightMap getHeightMapAt(Vector3f location) { |
||||
AbstractHeightMap heightmap = null; |
||||
if (this.cacheDir != null && new File(this.cacheDir, "terrain_" + (int) location.x + "_" + (int) location.z + ".png").exists()) { |
||||
try { |
||||
BufferedImage im = null; |
||||
im = ImageIO.read(new File(this.cacheDir, "terrain_" + (int) location.x + "_" + (int) location.z + ".png")); |
||||
heightmap = new Grayscale16BitHeightMap(im); |
||||
heightmap.setHeightScale(256); |
||||
} catch (IOException e) {} |
||||
} else { |
||||
FloatBuffer buffer = this.base.getBuffer(location.x * (this.size - 1), location.z * (this.size - 1), 0, this.size); |
||||
if (this.cacheDir != null) { |
||||
MapUtils.saveImage(MapUtils.toGrayscale16Image(buffer, this.size), new File(this.cacheDir, "terrain_" + (int) location.x |
||||
+ "_" + (int) location.z + ".png")); |
||||
} |
||||
float[] arr = buffer.array(); |
||||
for (int i = 0; i < arr.length; i++) { |
||||
arr[i] = arr[i] * this.heightScale; |
||||
} |
||||
heightmap = new FloatBufferHeightMap(buffer); |
||||
} |
||||
heightmap.load(); |
||||
return heightmap; |
||||
} |
||||
|
||||
@Override |
||||
public void setSize(int size) { |
||||
this.size = size; |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue