git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8699 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
parent
9e18ec6184
commit
cfbf116b2d
@ -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
|
||||||
|
} |
||||||
|
} |
@ -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
|
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue