From 6712fccbc3adf3cfbbe74daf1c7319fa9bd9b1bb Mon Sep 17 00:00:00 2001 From: "bre..ns" Date: Sun, 6 Nov 2011 17:32:56 +0000 Subject: [PATCH] cleaned up terrainQuad constructor. Added flexibility to image heightmap git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8585 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../jme3/terrain/geomipmap/TerrainGrid.java | 2 +- .../jme3/terrain/geomipmap/TerrainQuad.java | 2 +- .../heightmap/ImageBasedHeightMap.java | 10 +++- .../heightmap/ImageBasedHeightMapGrid.java | 54 +++++++++++++++++-- .../terrain/heightmap/ImageHeightmap.java | 29 ++++++++++ 5 files changed, 90 insertions(+), 7 deletions(-) create mode 100644 engine/src/terrain/com/jme3/terrain/heightmap/ImageHeightmap.java diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java index 7eb1103a5..f54ce8a5f 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainGrid.java @@ -86,7 +86,7 @@ public class TerrainGrid extends TerrainQuad { if (q == null) { // create the new Quad since it doesn't exist HeightMap heightMapAt = heightMapGrid.getHeightMapAt(temp); - q = new TerrainQuad(getName() + "Quad" + temp, patchSize, quadSize, totalSize, heightMapAt == null ? null : heightMapAt.getHeightMap()); + q = new TerrainQuad(getName() + "Quad" + temp, patchSize, totalSize, quadSize, heightMapAt == null ? null : heightMapAt.getHeightMap()); q.setMaterial(material.clone()); log.log(Level.FINE, "Loaded TerrainQuad {0}", q.getName()); } diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java index b83c55118..d1e7dad84 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java @@ -161,7 +161,7 @@ public class TerrainQuad extends Node implements Terrain { * @param heightMap */ public TerrainQuad(String name, int patchSize, int quadSize, int totalSize, float[] heightMap) { - this(name, patchSize, totalSize, Vector3f.UNIT_XYZ, heightMap); + this(name, patchSize, totalSize, quadSize, Vector3f.UNIT_XYZ, heightMap); } /** diff --git a/engine/src/terrain/com/jme3/terrain/heightmap/ImageBasedHeightMap.java b/engine/src/terrain/com/jme3/terrain/heightmap/ImageBasedHeightMap.java index 37219b251..89d3b2857 100644 --- a/engine/src/terrain/com/jme3/terrain/heightmap/ImageBasedHeightMap.java +++ b/engine/src/terrain/com/jme3/terrain/heightmap/ImageBasedHeightMap.java @@ -48,7 +48,7 @@ import java.awt.image.WritableRaster; * @author Mike Kienenberger * @version $id$ */ -public class ImageBasedHeightMap extends AbstractHeightMap { +public class ImageBasedHeightMap extends AbstractHeightMap implements ImageHeightmap { static protected class ImageConverter { @@ -137,6 +137,14 @@ public class ImageBasedHeightMap extends AbstractHeightMap { protected float dampen = 1.0f; + public void setImage(Image image) { + this.colorImage = image; + } + + public int getSupportedImageType() { + return BufferedImage.TYPE_3BYTE_BGR; + } + /** * Creates a HeightMap from an Image. The image will be converted to * grayscale, and the grayscale values will be used to generate the height diff --git a/engine/src/terrain/com/jme3/terrain/heightmap/ImageBasedHeightMapGrid.java b/engine/src/terrain/com/jme3/terrain/heightmap/ImageBasedHeightMapGrid.java index 42dbed82c..6300ac59b 100644 --- a/engine/src/terrain/com/jme3/terrain/heightmap/ImageBasedHeightMapGrid.java +++ b/engine/src/terrain/com/jme3/terrain/heightmap/ImageBasedHeightMapGrid.java @@ -17,8 +17,14 @@ import java.util.logging.Logger; import javax.imageio.ImageIO; /** - * - * @author Anthyon + * Loads Terrain grid tiles with image heightmaps. + * By default it expects a 16-bit grayscale image as the heightmap, but + * you can also call setImageType(BufferedImage.TYPE_) to set it to be a different + * image type. If you do this, you must also set a custom ImageHeightmap that will + * understand and be able to parse the image. By default if you pass in an image of type + * BufferedImage.TYPE_3BYTE_BGR, it will use the ImageBasedHeightMap for you. + * + * @author Anthyon, Brent Owens */ public class ImageBasedHeightMapGrid implements HeightMapGrid { @@ -26,6 +32,8 @@ public class ImageBasedHeightMapGrid implements HeightMapGrid { private final AssetManager assetManager; private final Namer namer; private int size; + private int imageType = BufferedImage.TYPE_USHORT_GRAY; // 16 bit grayscale + private ImageHeightmap customImageHeightmap; public ImageBasedHeightMapGrid(final String textureBase, final String textureExt, AssetManager assetManager) { this(assetManager, new Namer() { @@ -40,6 +48,27 @@ public class ImageBasedHeightMapGrid implements HeightMapGrid { 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; + } public HeightMap getHeightMapAt(Vector3f location) { // HEIGHTMAP image (for the terrain heightmap) @@ -57,11 +86,28 @@ public class ImageBasedHeightMapGrid implements HeightMapGrid { InputStream in = assetInfo.openStream(); im = ImageIO.read(in); } else { - im = new BufferedImage(size, size, BufferedImage.TYPE_USHORT_GRAY); + im = new BufferedImage(size, size, imageType); logger.log(Level.WARNING, "File: {0} not found, loading zero heightmap instead", name); } // CREATE HEIGHTMAP - heightmap = new Grayscale16BitHeightMap(im); + 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) { diff --git a/engine/src/terrain/com/jme3/terrain/heightmap/ImageHeightmap.java b/engine/src/terrain/com/jme3/terrain/heightmap/ImageHeightmap.java new file mode 100644 index 000000000..fe1baae7e --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/heightmap/ImageHeightmap.java @@ -0,0 +1,29 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.terrain.heightmap; + +import java.awt.Image; + +/** + * A heightmap that is built off an image. + * If you want to be able to supply different Image types to + * ImageBaseHeightMapGrid, you need to implement this interface, + * and have that class extend Abstract heightmap. + * + * @author bowens + */ +public interface ImageHeightmap { + + /** + * Set the image to use for this heightmap + */ + public void setImage(Image image); + + /** + * The BufferedImage.TYPE_ that is supported + * by this ImageHeightmap + */ + public int getSupportedImageType(); +}