diff --git a/engine/src/core/com/jme3/terrain/AbstractGeomap.java b/engine/src/core/com/jme3/terrain/AbstractGeomap.java deleted file mode 100644 index 0e140995b..000000000 --- a/engine/src/core/com/jme3/terrain/AbstractGeomap.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (c) 2009-2010 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * 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; - -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.scene.Mesh; -import com.jme3.scene.VertexBuffer; -import com.jme3.scene.VertexBuffer.Type; -import com.jme3.util.BufferUtils; -import java.nio.BufferUnderflowException; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; - -/** - * implements all writeXXXXArray methods to reduce boilerplate code - * Geomap implementations are encouraged to extend this class - */ -public abstract class AbstractGeomap implements Geomap { - - public Vector2f getUV(int x, int y, Vector2f store){ - store.set( (float)x / (float)getWidth(), - (float)y / (float)getHeight() ); - return store; - } - - public Vector2f getUV(int i, Vector2f store){ - return store; - } - - /* - * (non-Javadoc) - * Subclasses are encouraged to provide a better implementation - * which directly accesses the data rather than using getHeight - */ - public FloatBuffer writeVertexArray(FloatBuffer store, Vector3f scale, boolean center){ - // check now so we don't have an NPE at the loop (getHeight call) - if (!isLoaded()) - throw new NullPointerException(); - - if (store!=null){ - // you might want to write this data as a part of a larger - // vertex array/buffer to reduce draw calls and that is - // why remaining() is used instead of limit() - if (store.remaining() < getWidth()*getHeight()*3) - throw new BufferUnderflowException(); - }else{ - // allocate a new buffer, this buffer is accessible to the user - // through the return of this method.. - store = BufferUtils.createFloatBuffer(getWidth()*getHeight()*3); - } - - Vector3f offset = new Vector3f(-getWidth() * scale.x, 0, -getWidth() * scale.z); - if (!center) - offset.zero(); - - // going through Y/Z first, scanlines are horizontal - for (int z = 0; z < getHeight(); z++){ - for (int x = 0; x < getWidth(); x++){ - store.put( (float)x*scale.x + offset.x ); - store.put( (float)getValue(x,z)*scale.y ); - store.put( (float)z*scale.z + offset.y ); - } - } - - return store; - } - - public IntBuffer writeIndexArray(IntBuffer store){ - int faceN = (getWidth()-1)*(getHeight()-1)*2; - - if (store!=null){ - if (store.remaining() < faceN*3) - throw new BufferUnderflowException(); - }else{ - store = BufferUtils.createIntBuffer(faceN*3); - } - - int i = 0; - for (int z = 0; z < getHeight()-1; z++){ - for (int x = 0; x < getWidth()-1; x++){ - store.put(i).put(i+getWidth()).put(i+getWidth()+1); - store.put(i+getWidth()+1).put(i+1).put(i); - i++; - - // TODO: There's probably a better way to do this.. - if (x==getWidth()-2) i++; - } - } - store.flip(); - - return store; - } - - /** - * This one has indexed LOD - * @param store - * @return - */ - public IntBuffer writeIndexArray2(IntBuffer store){ - int faceN = (getWidth()-1)*(getHeight()-1)*2; - - final int lod2 = 32; - final int lod = 1; - - if (store!=null){ - if (store.remaining() < faceN*3) - throw new BufferUnderflowException(); - }else{ - store = BufferUtils.createIntBuffer(faceN*3); - } - - for (int z = 0; z < getHeight()-1; z += lod ){ - for (int x = 0; x < getWidth()-1; x += lod){ - int i = x + z * getWidth(); - store.put(i).put(i+getWidth()*lod).put(i+getWidth()*lod+lod); - store.put(i+getWidth()*lod+lod).put(i+lod).put(i); - } - } - store.flip(); - - for(int i = 0; i < store.limit(); i++ ){ - int index = store.get(); - if( index < getWidth()-3 && index % lod2 != 0 ){ - store.position(store.position()-1); - store.put(index - index % lod2); - } - } - - return store; - } - - /* - * (non-Javadoc) - * Subclasses are encourged to provide a better implementation - * which directly accesses the data rather than using getNormal - */ - public FloatBuffer writeNormalArray(FloatBuffer store, Vector3f scale) { - if (!isLoaded()) - throw new NullPointerException(); - - if (store!=null){ - if (store.remaining() < getWidth()*getHeight()*3) - throw new BufferUnderflowException(); - }else{ - store = BufferUtils.createFloatBuffer(getWidth()*getHeight()*3); - } - store.rewind(); - - if (!hasNormalmap()){ - Vector3f oppositePoint = new Vector3f(); - Vector3f adjacentPoint = new Vector3f(); - Vector3f rootPoint = new Vector3f(); - Vector3f tempNorm = new Vector3f(); - int normalIndex = 0; - - for (int y = 0; y < getHeight(); y++) { - for (int x = 0; x < getWidth(); x++) { - rootPoint.set(x, getValue(x,y), y); - if (y == getHeight() - 1) { - if (x == getWidth() - 1) { // case #4 : last row, last col - // left cross up -// adj = normalIndex - getWidth(); -// opp = normalIndex - 1; - adjacentPoint.set(x, getValue(x,y-1), y-1); - oppositePoint.set(x-1, getValue(x-1, y), y); - } else { // case #3 : last row, except for last col - // right cross up -// adj = normalIndex + 1; -// opp = normalIndex - getWidth(); - adjacentPoint.set(x+1, getValue(x+1,y), y); - oppositePoint.set(x, getValue(x,y-1), y-1); - } - } else { - if (x == getWidth() - 1) { // case #2 : last column except for last row - // left cross down - adjacentPoint.set(x-1, getValue(x-1,y), y); - oppositePoint.set(x, getValue(x,y+1), y+1); -// adj = normalIndex - 1; -// opp = normalIndex + getWidth(); - } else { // case #1 : most cases - // right cross down - adjacentPoint.set(x, getValue(x,y+1), y+1); - oppositePoint.set(x+1, getValue(x+1,y), y); -// adj = normalIndex + getWidth(); -// opp = normalIndex + 1; - } - } - - - - tempNorm.set(adjacentPoint).subtractLocal(rootPoint) - .crossLocal(oppositePoint.subtractLocal(rootPoint)); - tempNorm.multLocal(scale).normalizeLocal(); -// store.put(tempNorm.x).put(tempNorm.y).put(tempNorm.z); - BufferUtils.setInBuffer(tempNorm, store, - normalIndex); - normalIndex++; - } - } - }else{ - Vector3f temp = new Vector3f(); - for (int z = 0; z < getHeight(); z++){ - for (int x = 0; x < getWidth(); x++){ - getNormal(x,z,temp); - store.put(temp.x).put(temp.y).put(temp.z); - } - } - } - - return store; - } - - - /* - * (non-Javadoc) - * ... - */ - public FloatBuffer writeTexCoordArray(FloatBuffer store, Vector2f offset, Vector2f scale){ - if (store!=null){ - if (store.remaining() < getWidth()*getHeight()*2) - throw new BufferUnderflowException(); - }else{ - store = BufferUtils.createFloatBuffer(getWidth()*getHeight()*2); - } - - if (offset == null) - offset = new Vector2f(); - - Vector2f tcStore = new Vector2f(); - for (int y = 0; y < getHeight(); y++){ - for (int x = 0; x < getWidth(); x++){ - getUV(x,y,tcStore); - store.put( offset.x + tcStore.x * scale.x ); - store.put( offset.y + tcStore.y * scale.y ); - -// store.put( ((float)x) / getWidth() ); -// store.put( ((float)y) / getHeight() ); - } - - } - - return store; - } - - public Mesh createMesh(Vector3f scale, Vector2f tcScale, boolean center){ - FloatBuffer pb = writeVertexArray(null, scale, center); - FloatBuffer tb = writeTexCoordArray(null, Vector2f.ZERO, tcScale); - FloatBuffer nb = writeNormalArray(null, scale); - IntBuffer ib = writeIndexArray(null); - Mesh m = new Mesh(); - m.setBuffer(Type.Position, 3, pb); - m.setBuffer(Type.Normal, 3, nb); - m.setBuffer(Type.TexCoord, 2, tb); - m.setBuffer(Type.Index, 3, ib); - m.setStatic(); - m.updateBound(); - return m; - } - -} diff --git a/engine/src/core/com/jme3/terrain/BufferGeomap.java b/engine/src/core/com/jme3/terrain/BufferGeomap.java deleted file mode 100644 index b76d4b02d..000000000 --- a/engine/src/core/com/jme3/terrain/BufferGeomap.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (c) 2009-2010 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * 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; - -import com.jme3.export.InputCapsule; -import com.jme3.export.JmeExporter; -import com.jme3.export.JmeImporter; -import com.jme3.export.OutputCapsule; -import com.jme3.export.Savable; -import com.jme3.math.Vector3f; -import com.jme3.scene.Mesh; -import com.jme3.scene.VertexBuffer; -import com.jme3.scene.VertexBuffer.Type; -import com.jme3.util.BufferUtils; -import java.io.IOException; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; - -/** - * Implementation of the Geomap interface which stores data in memory as native buffers - */ -public class BufferGeomap extends AbstractGeomap implements Geomap, Savable { - - protected FloatBuffer hdata; - protected ByteBuffer ndata; - protected int width, height, maxval; - - public BufferGeomap() {} - - public BufferGeomap(FloatBuffer heightData, ByteBuffer normalData, int width, int height, int maxval){ - this.hdata = heightData; - this.ndata = normalData; - this.width = width; - this.height = height; - this.maxval = maxval; - } - - public BufferGeomap(int width, int height, int maxval) { - this(ByteBuffer.allocateDirect(width*height*4).asFloatBuffer(),null,width,height,maxval); - } - - public FloatBuffer getHeightData(){ - if (!isLoaded()) - return null; - - return hdata; - } - - public ByteBuffer getNormalData(){ - if (!isLoaded() || !hasNormalmap()) - return null; - - return ndata; - } - - public int getMaximumValue(){ - return maxval; - } - - public float getValue(int x, int y) { - return hdata.get(y*width+x); - } - - public float getValue(int i) { - return hdata.get(i); - } - - public Vector3f getNormal(int x, int y, Vector3f store) { - return getNormal(y*width+x,store); - } - - public Vector3f getNormal(int i, Vector3f store) { - ndata.position( i*3 ); - if (store==null) store = new Vector3f(); - store.setX( (((float)(ndata.get() & 0xFF)/255f)-0.5f)*2f ); - store.setY( (((float)(ndata.get() & 0xFF)/255f)-0.5f)*2f ); - store.setZ( (((float)(ndata.get() & 0xFF)/255f)-0.5f)*2f ); - return store; - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public SharedGeomap getSubGeomap(int x, int y, int w, int h) { - if (w+x > width) - w = width - x; - if (h+y > height) - h = height - y; - - return new SharedBufferGeomap(this,x,y,w,h); - } - - public Geomap copySubGeomap(int x, int y, int w, int h){ - FloatBuffer nhdata = ByteBuffer.allocateDirect(w*h*4).asFloatBuffer(); - hdata.position(y*width+x); - for (int cy = 0; cy < height; cy++){ - hdata.limit(hdata.position()+w); - nhdata.put(hdata); - hdata.limit(hdata.capacity()); - hdata.position(hdata.position()+width); - } - nhdata.flip(); - - ByteBuffer nndata = null; - if (ndata!=null){ - nndata = ByteBuffer.allocateDirect(w*h*3); - ndata.position( (y*width+x)*3 ); - for (int cy = 0; cy < height; cy++){ - ndata.limit(ndata.position()+w*3); - nndata.put(ndata); - ndata.limit(ndata.capacity()); - ndata.position(ndata.position()+width*3); - } - nndata.flip(); - } - - return new BufferGeomap(nhdata,nndata,w,h,maxval); - } - - public boolean hasNormalmap() { - return ndata != null; - } - - public boolean isLoaded() { - return true; - } - -// @Override -// public FloatBuffer writeNormalArray(FloatBuffer store) { -// if (!isLoaded() || !hasNormalmap()) throw new NullPointerException(); -// -// if (store!=null){ -// if (store.remaining() < width*height*3) -// throw new BufferUnderflowException(); -// }else{ -// store = BufferUtils.createFloatBuffer(width*height*3); -// } -// ndata.rewind(); -// -// for (int z = 0; z < height; z++){ -// for (int x = 0; x < width; x++){ -// float r = ((float)(ndata.get() & 0xFF)/255f -0.5f) * 2f; -// float g = ((float)(ndata.get() & 0xFF)/255f -0.5f) * 2f; -// float b = ((float)(ndata.get() & 0xFF)/255f -0.5f) * 2f; -// store.put(r).put(b).put(g); -// } -// } -// -// return store; -// } - - @Override - public FloatBuffer writeVertexArray(FloatBuffer store, Vector3f scale, boolean center) { - if (!isLoaded()) throw new NullPointerException(); - - if (store!=null){ - if (store.remaining() < width*height*3) - throw new BufferUnderflowException(); - }else{ - store = BufferUtils.createFloatBuffer(width*height*3); - } - hdata.rewind(); - - assert hdata.limit() == height*width; - - Vector3f offset = new Vector3f(-getWidth() * scale.x * 0.5f, - 0, - -getWidth() * scale.z * 0.5f); - if (!center) - offset.zero(); - - for (int z = 0; z < height; z++){ - for (int x = 0; x < width; x++){ - store.put( (float)x*scale.x + offset.x ); - store.put( (float)hdata.get()*scale.y ); - store.put( (float)z*scale.z + offset.z ); - } - } - - return store; - } - - public void write(JmeExporter ex) throws IOException { - OutputCapsule oc = ex.getCapsule(this); - oc.write(hdata, "hdata", null); - oc.write(width, "width", 0); - oc.write(height, "height", 0); - oc.write(maxval, "maxval", 0); - } - - public void read(JmeImporter im) throws IOException { - InputCapsule ic = im.getCapsule(this); - hdata = ic.readFloatBuffer("hdata", null); - width = ic.readInt("width", 0); - height = ic.readInt("height", 0); - maxval = ic.readInt("maxval", 0); - } - - /** - * Populate the height data from the supplied mesh. - * The mesh's dimensions should be the same as width and height - * of this geomap - */ - public void populateHdataFromMesh(Mesh mesh) { - hdata = BufferUtils.createFloatBuffer(width*height); - hdata.rewind(); - VertexBuffer pb = mesh.getBuffer(Type.Position); - FloatBuffer fb = (FloatBuffer) pb.getData(); - for (int r=0; rgetValue() can - * return. Mostly depends on the source data format (byte, short, int, etc). - */ - public int getMaximumValue(); - - /** - * Returns the height value for a given point. - * - * MUST return the same value as getHeight(y*getWidth()+x) - * - * @param x the X coordinate - * @param y the Y coordinate - * @returns an arbitary height looked up from the heightmap - * - * @throws NullPointerException If isLoaded() is false - */ - public float getValue(int x, int y); - - /** - * Returns the height value at the given index. - * - * zero index is top left of map, - * getWidth()*getHeight() index is lower right - * - * @param i The index - * @returns an arbitary height looked up from the heightmap - * - * @throws NullPointerException If isLoaded() is false - */ - public float getValue(int i); - - /** - * Returns the normal at a point - * - * If store is null, then a new vector is returned, - * otherwise, the result is stored in the provided vector - * and then returned from this method - * - * @param x the X coordinate - * @param y the Y coordinate - * @param store A preallocated vector for storing the normal data, optional - * @returns store, or a new vector with the normal data if store is null - * - * @throws NullPointerException If isLoaded() or hasNormalmap() is false - */ - public Vector3f getNormal(int x, int y, Vector3f store); - - /** - * Returns the normal at an index - * - * If store is null, then a new vector is returned, - * otherwise, the result is stored in the provided vector - * and then returned from this method - * - * See getHeight(int) for information about index lookup - * - * @param i the index - * @param store A preallocated vector for storing the normal data, optional - * @returns store, or a new vector with the normal data if store is null - * - * @throws NullPointerException If isLoaded() or hasNormalmap() is false - */ - public Vector3f getNormal(int i, Vector3f store); - - public Vector2f getUV(int x, int y, Vector2f store); - public Vector2f getUV(int i, Vector2f store); - - /** - * Returns the width of this Geomap - * - * @returns the width of this Geomap - */ - public int getWidth(); - - /** - * Returns the height of this Geomap - * - * @returns the height of this Geomap - */ - public int getHeight(); - - /** - * Returns a section of this geomap as a new geomap - * - * The created geomap references data from this geomap - * If part of the geomap is contained within the original, - * then that part is returned - */ - public SharedGeomap getSubGeomap(int x, int y, int w, int h); - - /** - * Copies a section of this geomap as a new geomap - */ - public Geomap copySubGeomap(int x, int y, int w, int h); - - /** - * Creates a normal array from the normal data in this Geomap - * - * @param store A preallocated FloatBuffer where to store the data (optional), size must be >= getWidth()*getHeight()*3 - * @returns store, or a new FloatBuffer if store is null - * - * @throws NullPointerException If isLoaded() or hasNormalmap() is false - */ - public FloatBuffer writeNormalArray(FloatBuffer store, Vector3f scale); - - /** - * Creates a vertex array from the height data in this Geomap - * - * The scale argument specifies the scale to use for the vertex buffer. - * For example, if scale is 10,1,10, then the greatest X value is getWidth()*10 - * - * @param store A preallocated FloatBuffer where to store the data (optional), size must be >= getWidth()*getHeight()*3 - * @param scale Created vertexes are scaled by this vector - * - * @returns store, or a new FloatBuffer if store is null - * - * @throws NullPointerException If isLoaded() is false - */ - public FloatBuffer writeVertexArray(FloatBuffer store, Vector3f scale, boolean center); - - public FloatBuffer writeTexCoordArray(FloatBuffer store, Vector2f offset, Vector2f scale); - - public IntBuffer writeIndexArray(IntBuffer store); - - public Mesh createMesh(Vector3f scale, Vector2f tcScale, boolean center); -} diff --git a/engine/src/core/com/jme3/terrain/GeomapLoader.java b/engine/src/core/com/jme3/terrain/GeomapLoader.java deleted file mode 100644 index 1b5f09f9d..000000000 --- a/engine/src/core/com/jme3/terrain/GeomapLoader.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2009-2010 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * 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; -// -//import java.awt.Graphics2D; -//import java.awt.image.BufferedImage; -//import java.io.IOException; -//import java.io.InputStream; -//import java.net.URL; -//import java.nio.ByteBuffer; -//import java.nio.ByteOrder; -//import java.nio.IntBuffer; -//import javax.imageio.ImageIO; -// -//public class GeomapLoader { -// -// /** -// * Loads a heightmap from the image -// * -// * The returned IntBuffer has heights ranging from 0 to 2^16 -// */ -// protected static IntBuffer loadHeightmapImage(BufferedImage bi, boolean invertY){ -// BufferedImage hm = null; -// -// if (bi.getType()!=BufferedImage.TYPE_USHORT_GRAY || invertY){ -// hm = new BufferedImage(bi.getWidth(),bi.getHeight(),BufferedImage.TYPE_USHORT_GRAY); -// -// Graphics2D g = hm.createGraphics(); -// if (invertY){ -// g.scale(1d,-1d); -// g.translate(0, -bi.getHeight()); -// } -// g.drawImage(bi,null,0,0); -// g.dispose(); -// }else{ -// hm = bi; -// } -// -// IntBuffer ib = BufferUtils.createIntBuffer(bi.getWidth()*bi.getHeight()); -// short[] data = (short[]) hm.getData().getDataElements(0,0,bi.getWidth(),bi.getHeight(),null); -// for (int i = 0; i < hm.getWidth()*hm.getHeight(); i++){ -// //System.out.println(data[i] & 0xFFFF); -//// ib.put( (((data[i] & 0xFF00) >> 8) | ((data[i] & 0x00FF) << 8)) ); -// ib.put( data[i] & 0xFFFF ); -// } -// -// //for (int y = 0; y < hm.getHeight(); y++){ -// // for (int x = 0; x < hm.getWidth(); x++){ -// // ib.put(db.getElem -// // } -// //} -// ib.flip(); -// -// return ib; -// } -// -// protected static IntBuffer loadHeightmapRAW(ByteBuffer raw, int width, int height, ByteOrder order, int bitsize){ -// raw.order(order); -// -// if (bitsize == 32){ -// // directly map to heightmap -// raw = raw.duplicate(); -// raw.limit(width * height * 4); -// return raw.asIntBuffer(); -// } -// -// ByteBuffer target = ByteBuffer.allocateDirect(width * height * 4); -// switch (bitsize){ -// case 8: -// for (int i = 0, len = width*height; i < len; i++){ -// target.putInt(raw.get() & 0xFF); -// } -// break; -// case 16: -// for (int i = 0, len = width*height; i < len; i++){ -// target.putInt(raw.getShort() & 0xFFFF); -// } -// break; -// case 24: -// //for (int i = 0, len = width*height; i < len; i++){ -// //} -// throw new UnsupportedOperationException("24 bitsize is not supported!"); -// case 32: -// //for (int i = 0, len = width*height; i < len; i++){ -// // target.putInt(raw.getInt() & 0xFFFFFFFF); -// //} -// target.put(raw); -// break; -// } -// target.flip(); -// -// return target.asIntBuffer(); -// } -// -// public static Geomap fromRaw(URL rawURL, int width, int height, int bitsize) throws IOException{ -// InputStream in = rawURL.openStream(); -// -// // read bytes from stream -// byte[] data = new byte[width * height * bitsize / 8]; -// in.read(data); -// -// // convert to bytebuffer -// ByteBuffer bb = ByteBuffer.allocateDirect(data.length).order(ByteOrder.nativeOrder()); -// bb.put(data); -// bb.flip(); -// -// IntBuffer ib = loadHeightmapRAW(bb, width, height, ByteOrder.BIG_ENDIAN, bitsize); -// return new BufferGeomap(ib, null, width, height, (int)Math.pow(2, bitsize)); -// } -// -// public static Geomap fromImage(URL imageURL) throws IOException { -// BufferedImage image = ImageIO.read(imageURL); -// IntBuffer ib = loadHeightmapImage(image, false); -// // maximum value is of unsigned short, because loadHeightmapImage -// // converts the image into a TYPE_USHORT_GRAY before reading in the -// // values. -// return new BufferGeomap(ib, null, image.getWidth(), image.getHeight(), 65536); -// } -// -//} diff --git a/engine/src/core/com/jme3/terrain/SharedBufferGeomap.java b/engine/src/core/com/jme3/terrain/SharedBufferGeomap.java deleted file mode 100644 index 35369e978..000000000 --- a/engine/src/core/com/jme3/terrain/SharedBufferGeomap.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2009-2010 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * 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; - -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; - -public class SharedBufferGeomap extends AbstractGeomap implements SharedGeomap { - - protected final BufferGeomap parent; - protected final FloatBuffer hdata; - protected final ByteBuffer ndata; - protected final int startX, startY, width, height; - - public SharedBufferGeomap(BufferGeomap parent, int x, int y, int w, int h){ - this.parent = parent; - hdata = parent.getHeightData(); - ndata = parent.getNormalData(); - startX = x; - startY = y; - width = w; - height = h; - } - - public boolean hasNormalmap() { - return parent.hasNormalmap(); - } - - public boolean isLoaded() { - return parent.isLoaded(); - } - - public int getMaximumValue(){ - return parent.getMaximumValue(); - } - - public Geomap getParent() { - return parent; - } - - public int getXOffset() { - return startX; - } - - public int getYOffset() { - return startY; - } - - public float getValue(int x, int y) { - return parent.getValue(startX+x,startY+y); - } - - public float getValue(int i) { - int r = i % width; - return getValue(r,(i-r)/width); - } - - public Vector3f getNormal(int x, int y, Vector3f store) { - return parent.getNormal(startX+x,startY+y,store); - } - - public Vector3f getNormal(int i, Vector3f store) { - int r = i % width; - return getNormal(r,(i-r)/width,store); - } - - @Override - public Vector2f getUV(int x, int y, Vector2f store){ - return parent.getUV(startX+x, startY+y, store); - } - - @Override - public Vector2f getUV(int i, Vector2f store){ - int r = i % width; - return getUV(r,(i-r)/width,store); - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public Geomap copy() { - return parent.copySubGeomap(startX,startY,width,height); - } - - public SharedGeomap getSubGeomap(int x, int y, int w, int h) { - if (x<0 || y<0 || x>width || y>height || w+x>width || h+y>height) - throw new IndexOutOfBoundsException(); - - return parent.getSubGeomap(startX+x,startY+y,w,h); - } - - public Geomap copySubGeomap(int x, int y, int w, int h) { - if (x<0 || y<0 || x>width || y>height || w>width || h>height) - throw new IndexOutOfBoundsException(); - - return parent.copySubGeomap(startX+x,startY+y,w,h); - } - -} diff --git a/engine/src/core/com/jme3/terrain/SharedGeomap.java b/engine/src/core/com/jme3/terrain/SharedGeomap.java deleted file mode 100644 index d576ed44e..000000000 --- a/engine/src/core/com/jme3/terrain/SharedGeomap.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2009-2010 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * 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; - -public interface SharedGeomap extends Geomap { - - /** - * Copies the data shared by this SharedGeomap into a new Geomap - */ - public Geomap copy(); - - /** - * Returns the Geomap from which the data is shared - */ - public Geomap getParent(); - - /** - * Returns the X offset of the shared Geomap relative to the parent origin - */ - public int getXOffset(); - - /** - * Returns the Y offset of the shared Geomap relative to the parent origin - */ - public int getYOffset(); - -} diff --git a/engine/src/terrain/com/jme3/terrain/GeoMapNew.java b/engine/src/terrain/com/jme3/terrain/GeoMapNew.java new file mode 100644 index 000000000..de14f9dae --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/GeoMapNew.java @@ -0,0 +1,471 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * 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; + +import com.jme3.export.InputCapsule; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.export.OutputCapsule; +import com.jme3.export.Savable; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Mesh; +import com.jme3.scene.VertexBuffer; +import com.jme3.scene.VertexBuffer.Type; +import com.jme3.util.BufferUtils; +import java.io.IOException; +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +/** + * Constructs heightfields to be used in Terrain. + */ +public class GeoMapNew implements Savable { + + protected FloatBuffer hdata; + protected ByteBuffer ndata; + protected int width, height, maxval; + + public GeoMapNew() {} + + public GeoMapNew(FloatBuffer heightData, ByteBuffer normalData, int width, int height, int maxval){ + this.hdata = heightData; + this.ndata = normalData; + this.width = width; + this.height = height; + this.maxval = maxval; + } + + public GeoMapNew(int width, int height, int maxval) { + this(ByteBuffer.allocateDirect(width*height*4).asFloatBuffer(),null,width,height,maxval); + } + + public FloatBuffer getHeightData(){ + if (!isLoaded()) + return null; + + return hdata; + } + + public ByteBuffer getNormalData(){ + if (!isLoaded() || !hasNormalmap()) + return null; + + return ndata; + } + + /** + * @return The maximum possible value that getValue() can + * return. Mostly depends on the source data format (byte, short, int, etc). + */ + public int getMaximumValue(){ + return maxval; + } + + /** + * Returns the height value for a given point. + * + * MUST return the same value as getHeight(y*getWidth()+x) + * + * @param x the X coordinate + * @param y the Y coordinate + * @returns an arbitrary height looked up from the heightmap + * + * @throws NullPointerException If isLoaded() is false + */ + public float getValue(int x, int y) { + return hdata.get(y*width+x); + } + + /** + * Returns the height value at the given index. + * + * zero index is top left of map, + * getWidth()*getHeight() index is lower right + * + * @param i The index + * @returns an arbitrary height looked up from the heightmap + * + * @throws NullPointerException If isLoaded() is false + */ + public float getValue(int i) { + return hdata.get(i); + } + + /** + * Returns the normal at a point + * + * If store is null, then a new vector is returned, + * otherwise, the result is stored in the provided vector + * and then returned from this method + * + * @param x the X coordinate + * @param y the Y coordinate + * @param store A preallocated vector for storing the normal data, optional + * @returns store, or a new vector with the normal data if store is null + * + * @throws NullPointerException If isLoaded() or hasNormalmap() is false + */ + public Vector3f getNormal(int x, int y, Vector3f store) { + return getNormal(y*width+x,store); + } + + /** + * Returns the normal at an index + * + * If store is null, then a new vector is returned, + * otherwise, the result is stored in the provided vector + * and then returned from this method + * + * See getHeight(int) for information about index lookup + * + * @param i the index + * @param store A preallocated vector for storing the normal data, optional + * @returns store, or a new vector with the normal data if store is null + * + * @throws NullPointerException If isLoaded() or hasNormalmap() is false + */ + public Vector3f getNormal(int i, Vector3f store) { + ndata.position( i*3 ); + if (store==null) store = new Vector3f(); + store.setX( (((float)(ndata.get() & 0xFF)/255f)-0.5f)*2f ); + store.setY( (((float)(ndata.get() & 0xFF)/255f)-0.5f)*2f ); + store.setZ( (((float)(ndata.get() & 0xFF)/255f)-0.5f)*2f ); + return store; + } + + /** + * Returns the width of this Geomap + * + * @returns the width of this Geomap + */ + public int getWidth() { + return width; + } + + /** + * Returns the height of this Geomap + * + * @returns the height of this Geomap + */ + public int getHeight() { + return height; + } + + /** + * Copies a section of this geomap as a new geomap + */ + public Geomap copySubGeomap(int x, int y, int w, int h){ + FloatBuffer nhdata = ByteBuffer.allocateDirect(w*h*4).asFloatBuffer(); + hdata.position(y*width+x); + for (int cy = 0; cy < height; cy++){ + hdata.limit(hdata.position()+w); + nhdata.put(hdata); + hdata.limit(hdata.capacity()); + hdata.position(hdata.position()+width); + } + nhdata.flip(); + + ByteBuffer nndata = null; + if (ndata!=null){ + nndata = ByteBuffer.allocateDirect(w*h*3); + ndata.position( (y*width+x)*3 ); + for (int cy = 0; cy < height; cy++){ + ndata.limit(ndata.position()+w*3); + nndata.put(ndata); + ndata.limit(ndata.capacity()); + ndata.position(ndata.position()+width*3); + } + nndata.flip(); + } + + return new BufferGeomap(nhdata,nndata,w,h,maxval); + } + + /** + * Returns true if this Geomap has a normalmap associated with it + */ + public boolean hasNormalmap() { + return ndata != null; + } + + /** + * Returns true if the Geomap data is loaded in memory + * If false, then the data is unavailable- must be loaded with load() + * before the methods getHeight/getNormal can be used + * + * @returns wether the geomap data is loaded in system memory + */ + public boolean isLoaded() { + return true; + } + + /** + * Creates a normal array from the normal data in this Geomap + * + * @param store A preallocated FloatBuffer where to store the data (optional), size must be >= getWidth()*getHeight()*3 + * @returns store, or a new FloatBuffer if store is null + * + * @throws NullPointerException If isLoaded() or hasNormalmap() is false + */ + public FloatBuffer writeNormalArray(FloatBuffer store, Vector3f scale) { + if (!isLoaded()) + throw new NullPointerException(); + + if (store!=null){ + if (store.remaining() < getWidth()*getHeight()*3) + throw new BufferUnderflowException(); + }else{ + store = BufferUtils.createFloatBuffer(getWidth()*getHeight()*3); + } + store.rewind(); + + if (!hasNormalmap()){ + Vector3f oppositePoint = new Vector3f(); + Vector3f adjacentPoint = new Vector3f(); + Vector3f rootPoint = new Vector3f(); + Vector3f tempNorm = new Vector3f(); + int normalIndex = 0; + + for (int y = 0; y < getHeight(); y++) { + for (int x = 0; x < getWidth(); x++) { + rootPoint.set(x, getValue(x,y), y); + if (y == getHeight() - 1) { + if (x == getWidth() - 1) { // case #4 : last row, last col + // left cross up +// adj = normalIndex - getWidth(); +// opp = normalIndex - 1; + adjacentPoint.set(x, getValue(x,y-1), y-1); + oppositePoint.set(x-1, getValue(x-1, y), y); + } else { // case #3 : last row, except for last col + // right cross up +// adj = normalIndex + 1; +// opp = normalIndex - getWidth(); + adjacentPoint.set(x+1, getValue(x+1,y), y); + oppositePoint.set(x, getValue(x,y-1), y-1); + } + } else { + if (x == getWidth() - 1) { // case #2 : last column except for last row + // left cross down + adjacentPoint.set(x-1, getValue(x-1,y), y); + oppositePoint.set(x, getValue(x,y+1), y+1); +// adj = normalIndex - 1; +// opp = normalIndex + getWidth(); + } else { // case #1 : most cases + // right cross down + adjacentPoint.set(x, getValue(x,y+1), y+1); + oppositePoint.set(x+1, getValue(x+1,y), y); +// adj = normalIndex + getWidth(); +// opp = normalIndex + 1; + } + } + + + + tempNorm.set(adjacentPoint).subtractLocal(rootPoint) + .crossLocal(oppositePoint.subtractLocal(rootPoint)); + tempNorm.multLocal(scale).normalizeLocal(); +// store.put(tempNorm.x).put(tempNorm.y).put(tempNorm.z); + BufferUtils.setInBuffer(tempNorm, store, + normalIndex); + normalIndex++; + } + } + }else{ + Vector3f temp = new Vector3f(); + for (int z = 0; z < getHeight(); z++){ + for (int x = 0; x < getWidth(); x++){ + getNormal(x,z,temp); + store.put(temp.x).put(temp.y).put(temp.z); + } + } + } + + return store; + } + + /** + * Creates a vertex array from the height data in this Geomap + * + * The scale argument specifies the scale to use for the vertex buffer. + * For example, if scale is 10,1,10, then the greatest X value is getWidth()*10 + * + * @param store A preallocated FloatBuffer where to store the data (optional), size must be >= getWidth()*getHeight()*3 + * @param scale Created vertexes are scaled by this vector + * + * @returns store, or a new FloatBuffer if store is null + * + * @throws NullPointerException If isLoaded() is false + */ + public FloatBuffer writeVertexArray(FloatBuffer store, Vector3f scale, boolean center) { + if (!isLoaded()) throw new NullPointerException(); + + if (store!=null){ + if (store.remaining() < width*height*3) + throw new BufferUnderflowException(); + }else{ + store = BufferUtils.createFloatBuffer(width*height*3); + } + hdata.rewind(); + + assert hdata.limit() == height*width; + + Vector3f offset = new Vector3f(-getWidth() * scale.x * 0.5f, + 0, + -getWidth() * scale.z * 0.5f); + if (!center) + offset.zero(); + + for (int z = 0; z < height; z++){ + for (int x = 0; x < width; x++){ + store.put( (float)x*scale.x + offset.x ); + store.put( (float)hdata.get()*scale.y ); + store.put( (float)z*scale.z + offset.z ); + } + } + + return store; + } + + public Vector2f getUV(int x, int y, Vector2f store){ + store.set( (float)x / (float)getWidth(), + (float)y / (float)getHeight() ); + return store; + } + + public Vector2f getUV(int i, Vector2f store){ + return store; + } + + public FloatBuffer writeTexCoordArray(FloatBuffer store, Vector2f offset, Vector2f scale){ + if (store!=null){ + if (store.remaining() < getWidth()*getHeight()*2) + throw new BufferUnderflowException(); + }else{ + store = BufferUtils.createFloatBuffer(getWidth()*getHeight()*2); + } + + if (offset == null) + offset = new Vector2f(); + + Vector2f tcStore = new Vector2f(); + for (int y = 0; y < getHeight(); y++){ + for (int x = 0; x < getWidth(); x++){ + getUV(x,y,tcStore); + store.put( offset.x + tcStore.x * scale.x ); + store.put( offset.y + tcStore.y * scale.y ); + } + + } + + return store; + } + + public IntBuffer writeIndexArray(IntBuffer store){ + int faceN = (getWidth()-1)*(getHeight()-1)*2; + + if (store!=null){ + if (store.remaining() < faceN*3) + throw new BufferUnderflowException(); + }else{ + store = BufferUtils.createIntBuffer(faceN*3); + } + + int i = 0; + for (int z = 0; z < getHeight()-1; z++){ + for (int x = 0; x < getWidth()-1; x++){ + store.put(i).put(i+getWidth()).put(i+getWidth()+1); + store.put(i+getWidth()+1).put(i+1).put(i); + i++; + + // TODO: There's probably a better way to do this.. + if (x==getWidth()-2) i++; + } + } + store.flip(); + + return store; + } + + public Mesh createMesh(Vector3f scale, Vector2f tcScale, boolean center){ + FloatBuffer pb = writeVertexArray(null, scale, center); + FloatBuffer tb = writeTexCoordArray(null, Vector2f.ZERO, tcScale); + FloatBuffer nb = writeNormalArray(null, scale); + IntBuffer ib = writeIndexArray(null); + Mesh m = new Mesh(); + m.setBuffer(Type.Position, 3, pb); + m.setBuffer(Type.Normal, 3, nb); + m.setBuffer(Type.TexCoord, 2, tb); + m.setBuffer(Type.Index, 3, ib); + m.setStatic(); + m.updateBound(); + return m; + } + + /** + * Populate the height data from the supplied mesh. + * The mesh's dimensions should be the same as width and height + * of this geomap + */ + public void populateHdataFromMesh(Mesh mesh) { + hdata = BufferUtils.createFloatBuffer(width*height); + hdata.rewind(); + VertexBuffer pb = mesh.getBuffer(Type.Position); + FloatBuffer fb = (FloatBuffer) pb.getData(); + for (int r=0; r