diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java index 523f5d900..c787a5603 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java @@ -201,7 +201,6 @@ public class TerrainGrid extends TerrainQuad { this.offsetAmount = offsetAmount; initData(); this.terrainQuadGrid = terrainQuadGrid; - terrainQuadGrid.setSize(this.size); terrainQuadGrid.setPatchSize(this.patchSize); terrainQuadGrid.setQuadSize(this.quadSize); addControl(new UpdateControl()); @@ -215,6 +214,7 @@ public class TerrainGrid extends TerrainQuad { this(name, patchSize, maxVisibleSize, Vector3f.UNIT_XYZ, terrainQuadGrid); } + @Deprecated public TerrainGrid(String name, int patchSize, int maxVisibleSize, Vector3f scale, HeightMapGrid heightMapGrid, Vector2f offset, float offsetAmount) { this.name = name; @@ -229,10 +229,12 @@ public class TerrainGrid extends TerrainQuad { addControl(new UpdateControl()); } + @Deprecated public TerrainGrid(String name, int patchSize, int maxVisibleSize, Vector3f scale, HeightMapGrid heightMapGrid) { this(name, patchSize, maxVisibleSize, scale, heightMapGrid, new Vector2f(), 0); } + @Deprecated public TerrainGrid(String name, int patchSize, int maxVisibleSize, HeightMapGrid heightMapGrid) { this(name, patchSize, maxVisibleSize, Vector3f.UNIT_XYZ, heightMapGrid); } @@ -455,7 +457,6 @@ public class TerrainGrid extends TerrainQuad { material = (Material) c.readSavable("material", null); initData(); if (terrainQuadGrid != null) { - terrainQuadGrid.setSize(this.size); terrainQuadGrid.setPatchSize(this.patchSize); terrainQuadGrid.setQuadSize(this.quadSize); } diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGridTileLoader.java b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGridTileLoader.java index 8dd6f469d..485f51fec 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGridTileLoader.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGridTileLoader.java @@ -15,8 +15,6 @@ public interface TerrainGridTileLoader extends Savable { public TerrainQuad getTerrainQuadAt(Vector3f location); - public void setSize(int size); - public void setPatchSize(int patchSize); public void setQuadSize(int quadSize); diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/grid/AssetTileLoader.java b/engine/src/terrain/com/jme3/terrain/geomipmap/grid/AssetTileLoader.java index b820b60c3..a8f9e6eb8 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/grid/AssetTileLoader.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/grid/AssetTileLoader.java @@ -56,10 +56,6 @@ public class AssetTileLoader implements TerrainGridTileLoader { return quad; } - public void setSize(int size) { - this.size = size; - } - public void setPatchSize(int patchSize) { this.patchSize = patchSize; } diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/grid/FractalTileLoader.java b/engine/src/terrain/com/jme3/terrain/geomipmap/grid/FractalTileLoader.java new file mode 100644 index 000000000..c52e2e8c1 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/grid/FractalTileLoader.java @@ -0,0 +1,101 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.terrain.geomipmap.grid; + +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.math.Vector3f; +import com.jme3.terrain.MapUtils; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.Grayscale16BitHeightMap; +import com.jme3.terrain.heightmap.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; + +/** + * + * @author Anthyon, normenhansen + */ +public class FractalTileLoader { + 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 patchSize; + private int quadSize; + private final Basis base; + private final String cacheDir; + private final float heightScale; + + public FractalTileLoader(Basis base, String cacheDir, float heightScale) { + this.base = base; + this.cacheDir = cacheDir; + this.heightScale = heightScale; + } + + private 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(heightScale); + } catch (IOException e) {} + } else { + FloatBuffer buffer = this.base.getBuffer(location.x * (this.patchSize - 1), location.z * (this.patchSize - 1), 0, this.patchSize); + if (this.cacheDir != null) { + MapUtils.saveImage(MapUtils.toGrayscale16Image(buffer, this.patchSize), 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; + } + + public TerrainQuad getTerrainQuadAt(Vector3f location) { + HeightMap heightMapAt = getHeightMapAt(location); + TerrainQuad q = new TerrainQuad("Quad" + location, patchSize, quadSize, heightMapAt == null ? null : heightMapAt.getHeightMap()); + return q; + } + + public void setPatchSize(int patchSize) { + this.patchSize = patchSize; + } + + public void setQuadSize(int quadSize) { + this.quadSize = quadSize; + } + + public void write(JmeExporter ex) throws IOException { + //TODO: serialization + } + + public void read(JmeImporter im) throws IOException { + //TODO: serialization + } +} diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/grid/ImageTileLoader.java b/engine/src/terrain/com/jme3/terrain/geomipmap/grid/ImageTileLoader.java new file mode 100644 index 000000000..694aea7da --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/grid/ImageTileLoader.java @@ -0,0 +1,148 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.terrain.geomipmap.grid; + +import com.jme3.asset.AssetInfo; +import com.jme3.asset.AssetKey; +import com.jme3.asset.AssetManager; +import com.jme3.asset.AssetNotFoundException; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.math.Vector3f; +import com.jme3.terrain.geomipmap.TerrainGridTileLoader; +import com.jme3.terrain.geomipmap.TerrainQuad; +import com.jme3.terrain.heightmap.AbstractHeightMap; +import com.jme3.terrain.heightmap.Grayscale16BitHeightMap; +import com.jme3.terrain.heightmap.HeightMap; +import com.jme3.terrain.heightmap.ImageBasedHeightMap; +import com.jme3.terrain.heightmap.ImageHeightmap; +import com.jme3.terrain.heightmap.Namer; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.InputStream; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.imageio.ImageIO; + +/** + * + * @author Anthyon, normenhansen + */ +public class ImageTileLoader implements TerrainGridTileLoader{ + private static final Logger logger = Logger.getLogger(ImageTileLoader.class.getName()); + private final AssetManager assetManager; + private final Namer namer; + private int patchSize; + private int quadSize; + private int imageType = BufferedImage.TYPE_USHORT_GRAY; // 16 bit grayscale + private ImageHeightmap customImageHeightmap; + + public ImageTileLoader(final String textureBase, final String textureExt, AssetManager assetManager) { + this(assetManager, new Namer() { + + public String getName(int x, int y) { + return textureBase + "_" + x + "_" + y + "." + textureExt; + } + }); + } + + public ImageTileLoader(AssetManager assetManager, Namer namer) { + this.assetManager = assetManager; + this.namer = namer; + } + + /** + * Lets you specify the type of images that are being loaded. All images + * must be the same type. + * @param imageType eg. BufferedImage.TYPE_USHORT_GRAY + */ + public void setImageType(int imageType) { + this.imageType = imageType; + } + + /** + * The ImageHeightmap that will parse the image type that you + * specify with setImageType(). + * @param customImageHeightmap must extend AbstractHeightmap + */ + public void setCustomImageHeightmap(ImageHeightmap customImageHeightmap) { + if (!(customImageHeightmap instanceof AbstractHeightMap)) { + throw new IllegalArgumentException("customImageHeightmap must be an AbstractHeightMap!"); + } + this.customImageHeightmap = customImageHeightmap; + } + + private HeightMap getHeightMapAt(Vector3f location) { + // HEIGHTMAP image (for the terrain heightmap) + int x = (int) location.x; + int z = (int) location.z; + + AbstractHeightMap heightmap = null; + BufferedImage im = null; + + try { + String name = namer.getName(x, z); + logger.log(Level.INFO, "Loading heightmap from file: {0}", name); + final AssetInfo assetInfo = assetManager.locateAsset(new AssetKey(name)); + if (assetInfo != null){ + InputStream in = assetInfo.openStream(); + im = ImageIO.read(in); + } else { + im = new BufferedImage(patchSize, patchSize, imageType); + logger.log(Level.WARNING, "File: {0} not found, loading zero heightmap instead", name); + } + // CREATE HEIGHTMAP + if (imageType == BufferedImage.TYPE_USHORT_GRAY) { + heightmap = new Grayscale16BitHeightMap(im); + } else if (imageType == BufferedImage.TYPE_3BYTE_BGR) { + heightmap = new ImageBasedHeightMap(im); + } else if (customImageHeightmap != null && customImageHeightmap instanceof AbstractHeightMap) { + // If it gets here, it means you have specified a different image type, and you must + // then also supply a custom image heightmap class that can parse that image into + // a heightmap. + customImageHeightmap.setImage(im); + heightmap = (AbstractHeightMap) customImageHeightmap; + } else { + // error, no supported image format and no custom image heightmap specified + if (customImageHeightmap == null) + logger.log(Level.SEVERE, "Custom image type specified [{0}] but no customImageHeightmap declared! Use setCustomImageHeightmap()",imageType); + if (!(customImageHeightmap instanceof AbstractHeightMap)) + logger.severe("customImageHeightmap must be an AbstractHeightMap!"); + return null; + } + heightmap.setHeightScale(256); + heightmap.load(); + } catch (IOException e) { + } catch (AssetNotFoundException e) { + } + return heightmap; + } + + public void setSize(int size) { + this.patchSize = size - 1; + } + + public TerrainQuad getTerrainQuadAt(Vector3f location) { + HeightMap heightMapAt = getHeightMapAt(location); + TerrainQuad q = new TerrainQuad("Quad" + location, patchSize, quadSize, heightMapAt == null ? null : heightMapAt.getHeightMap()); + return q; + } + + public void setPatchSize(int patchSize) { + this.patchSize = patchSize; + } + + public void setQuadSize(int quadSize) { + this.quadSize = quadSize; + } + + public void write(JmeExporter ex) throws IOException { + //TODO: serialization + } + + public void read(JmeImporter im) throws IOException { + //TODO: serialization + } +} diff --git a/engine/src/terrain/com/jme3/terrain/heightmap/FractalHeightMapGrid.java b/engine/src/terrain/com/jme3/terrain/heightmap/FractalHeightMapGrid.java index 9aa72ff03..15b1ad4cf 100644 --- a/engine/src/terrain/com/jme3/terrain/heightmap/FractalHeightMapGrid.java +++ b/engine/src/terrain/com/jme3/terrain/heightmap/FractalHeightMapGrid.java @@ -43,6 +43,10 @@ import org.novyon.noise.Basis; import com.jme3.math.Vector3f; import com.jme3.terrain.MapUtils; +@Deprecated +/** + * @Deprecated in favor of FractalTileLoader + */ public class FractalHeightMapGrid implements HeightMapGrid { public class FloatBufferHeightMap extends AbstractHeightMap { diff --git a/engine/src/terrain/com/jme3/terrain/heightmap/HeightMapGrid.java b/engine/src/terrain/com/jme3/terrain/heightmap/HeightMapGrid.java index f06608aa5..8d5942943 100644 --- a/engine/src/terrain/com/jme3/terrain/heightmap/HeightMapGrid.java +++ b/engine/src/terrain/com/jme3/terrain/heightmap/HeightMapGrid.java @@ -10,6 +10,10 @@ import com.jme3.math.Vector3f; * * @author Anthyon */ +@Deprecated +/** + * @Deprecated in favor of TerrainGridTileLoader + */ public interface HeightMapGrid { public HeightMap getHeightMapAt(Vector3f location); diff --git a/engine/src/terrain/com/jme3/terrain/heightmap/ImageBasedHeightMapGrid.java b/engine/src/terrain/com/jme3/terrain/heightmap/ImageBasedHeightMapGrid.java index 6300ac59b..ff12fc3f2 100644 --- a/engine/src/terrain/com/jme3/terrain/heightmap/ImageBasedHeightMapGrid.java +++ b/engine/src/terrain/com/jme3/terrain/heightmap/ImageBasedHeightMapGrid.java @@ -26,6 +26,10 @@ import javax.imageio.ImageIO; * * @author Anthyon, Brent Owens */ +@Deprecated +/** + * @Deprecated in favor of ImageTileLoader + */ public class ImageBasedHeightMapGrid implements HeightMapGrid { private static final Logger logger = Logger.getLogger(ImageBasedHeightMapGrid.class.getName());