180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright (c) 2009-2010 jMonkeyEngine 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * All rights reserved. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Redistribution and use in source and binary forms, with or without 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * modification, are permitted provided that the following conditions are 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * met: 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * * Redistributions of source code must retain the above copyright 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * notice, this list of conditions and the following disclaimer. 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 12363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * * Redistributions in binary form must reproduce the above copyright 13363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * notice, this list of conditions and the following disclaimer in the 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * documentation and/or other materials provided with the distribution. 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * may be used to endorse or promote products derived from this software 18096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * without specific prior written permission. 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 20e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupackage com.jme3.terrain; 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruimport com.jme3.export.*; 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruimport com.jme3.math.Vector2f; 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruimport com.jme3.math.Vector3f; 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruimport com.jme3.scene.Mesh; 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruimport com.jme3.scene.VertexBuffer.Type; 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruimport com.jme3.util.BufferUtils; 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruimport java.io.IOException; 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruimport java.nio.BufferUnderflowException; 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruimport java.nio.FloatBuffer; 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruimport java.nio.IntBuffer; 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Constructs heightfields to be used in Terrain. 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic class GeoMap implements Savable { 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru protected float[] hdata; 51d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger protected int width, height, maxval; 52d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 53d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger public GeoMap() {} 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru @Deprecated 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru public GeoMap(FloatBuffer heightData, int width, int height, int maxval){ 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru hdata = new float[heightData.limit()]; 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru heightData.get(hdata); 59d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this.width = width; 60d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this.height = height; 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this.maxval = maxval; 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 63d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru public GeoMap(float[] heightData, int width, int height, int maxval){ 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this.hdata = heightData; 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this.width = width; 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this.height = height; 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this.maxval = maxval; 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru @Deprecated 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru public FloatBuffer getHeightData(){ 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!isLoaded()) 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return null; 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return BufferUtils.createFloatBuffer(hdata); 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru public float[] getHeightArray(){ 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!isLoaded()) 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return null; 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return hdata; 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 84e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger /** 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @return The maximum possible value that <code>getValue()</code> can 86096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * return. Mostly depends on the source data format (byte, short, int, etc). 87096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger */ 88096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger public int getMaximumValue(){ 89096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return maxval; 90096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 91096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 92096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger /** 93096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * Returns the height value for a given point. 94096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * 95096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * MUST return the same value as getHeight(y*getWidth()+x) 96096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * 97096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * @param x the X coordinate 98096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * @param y the Y coordinate 99096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * @returns an arbitrary height looked up from the heightmap 100096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * 101096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * @throws NullPointerException If isLoaded() is false 102096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger */ 103096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger public float getValue(int x, int y) { 104096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return hdata[y*width+x]; 105096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 106096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 107096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger /** 108096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * Returns the height value at the given index. 109096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * 110096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * zero index is top left of map, 111096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * getWidth()*getHeight() index is lower right 112096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * 113096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * @param i The index 114363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * @returns an arbitrary height looked up from the heightmap 115363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * 116363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * @throws NullPointerException If isLoaded() is false 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru public float getValue(int i) { 119363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return hdata[i]; 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 122096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 123096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger /** 124096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * Returns the width of this Geomap 125096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * 126096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * @returns the width of this Geomap 127096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger */ 128096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger public int getWidth() { 129096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return width; 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Returns the height of this Geomap 134096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @returns the height of this Geomap 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 137363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger public int getHeight() { 138096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return height; 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Returns true if the Geomap data is loaded in memory 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * If false, then the data is unavailable- must be loaded with load() 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * before the methods getHeight/getNormal can be used 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @returns wether the geomap data is loaded in system memory 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru public boolean isLoaded() { 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 150363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 153363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Creates a normal array from the normal data in this Geomap 154363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param store A preallocated FloatBuffer where to store the data (optional), size must be >= getWidth()*getHeight()*3 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @returns store, or a new FloatBuffer if store is null 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @throws NullPointerException If isLoaded() or hasNormalmap() is false 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 160363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger public FloatBuffer writeNormalArray(FloatBuffer store, Vector3f scale) { 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (store!=null){ 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (store.remaining() < getWidth()*getHeight()*3) 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru throw new BufferUnderflowException(); 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }else{ 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru store = BufferUtils.createFloatBuffer(getWidth()*getHeight()*3); 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru store.rewind(); 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Vector3f oppositePoint = new Vector3f(); 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Vector3f adjacentPoint = new Vector3f(); 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Vector3f rootPoint = new Vector3f(); 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Vector3f tempNorm = new Vector3f(); 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int normalIndex = 0; 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int y = 0; y < getHeight(); y++) { 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int x = 0; x < getWidth(); x++) { 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rootPoint.set(x, getValue(x,y), y); 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (y == getHeight() - 1) { 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (x == getWidth() - 1) { // case #4 : last row, last col 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // left cross up 182363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// adj = normalIndex - getWidth(); 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// opp = normalIndex - 1; 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru adjacentPoint.set(x, getValue(x,y-1), y-1); 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru oppositePoint.set(x-1, getValue(x-1, y), y); 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { // case #3 : last row, except for last col 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // right cross up 188096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// adj = normalIndex + 1; 189096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// opp = normalIndex - getWidth(); 190096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger adjacentPoint.set(x+1, getValue(x+1,y), y); 191096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger oppositePoint.set(x, getValue(x,y-1), y-1); 192096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (x == getWidth() - 1) { // case #2 : last column except for last row 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // left cross down 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru adjacentPoint.set(x-1, getValue(x-1,y), y); 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru oppositePoint.set(x, getValue(x,y+1), y+1); 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// adj = normalIndex - 1; 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// opp = normalIndex + getWidth(); 200363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { // case #1 : most cases 201363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // right cross down 202363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger adjacentPoint.set(x, getValue(x,y+1), y+1); 203363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger oppositePoint.set(x+1, getValue(x+1,y), y); 204363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// adj = normalIndex + getWidth(); 205363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// opp = normalIndex + 1; 206363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 207363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 208363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 209e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger 210e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger 211e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger tempNorm.set(adjacentPoint).subtractLocal(rootPoint) 212e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger .crossLocal(oppositePoint.subtractLocal(rootPoint)); 213e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger tempNorm.multLocal(scale).normalizeLocal(); 214e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger// store.put(tempNorm.x).put(tempNorm.y).put(tempNorm.z); 215e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger BufferUtils.setInBuffer(tempNorm, store, 216e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger normalIndex); 217e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger normalIndex++; 218e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger } 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 220d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 221d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return store; 222d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 225d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * Creates a vertex array from the height data in this Geomap 226d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * 227d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * The scale argument specifies the scale to use for the vertex buffer. 228363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * For example, if scale is 10,1,10, then the greatest X value is getWidth()*10 229363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * 230d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * @param store A preallocated FloatBuffer where to store the data (optional), size must be >= getWidth()*getHeight()*3 231d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * @param scale Created vertexes are scaled by this vector 232d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * 233d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * @returns store, or a new FloatBuffer if store is null 234d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * 235d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * @throws NullPointerException If isLoaded() is false 236d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger */ 237d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger public FloatBuffer writeVertexArray(FloatBuffer store, Vector3f scale, boolean center) { 238363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 239096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (store!=null){ 240096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (store.remaining() < width*height*3) 241096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger throw new BufferUnderflowException(); 242096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger }else{ 243096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger store = BufferUtils.createFloatBuffer(width*height*3); 244096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 245096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 246096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger assert hdata.length == height*width; 247096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 248096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger Vector3f offset = new Vector3f(-getWidth() * scale.x * 0.5f, 249096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 0, 250096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger -getWidth() * scale.z * 0.5f); 251096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (!center) 252d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger offset.zero(); 253d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int i = 0; 255096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger for (int z = 0; z < height; z++){ 256096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger for (int x = 0; x < width; x++){ 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru store.put( (float)x*scale.x + offset.x ); 258096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger store.put( (float)hdata[i++]*scale.y ); 259096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger store.put( (float)z*scale.z + offset.z ); 260096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return store; 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru public Vector2f getUV(int x, int y, Vector2f store){ 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru store.set( (float)x / (float)getWidth(), 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (float)y / (float)getHeight() ); 26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return store; 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru public Vector2f getUV(int i, Vector2f store){ 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return store; 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru public FloatBuffer writeTexCoordArray(FloatBuffer store, Vector2f offset, Vector2f scale){ 27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (store!=null){ 27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (store.remaining() < getWidth()*getHeight()*2) 27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru throw new BufferUnderflowException(); 28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }else{ 28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru store = BufferUtils.createFloatBuffer(getWidth()*getHeight()*2); 28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (offset == null) 28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru offset = new Vector2f(); 28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 287096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger Vector2f tcStore = new Vector2f(); 288363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int y = 0; y < getHeight(); y++){ 289363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int x = 0; x < getWidth(); x++){ 290363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger getUV(x,y,tcStore); 291363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger store.put( offset.x + tcStore.x * scale.x ); 29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru store.put( offset.y + tcStore.y * scale.y ); 293096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 294096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 295096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 296096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 297363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return store; 298363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 300096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger public IntBuffer writeIndexArray(IntBuffer store){ 301096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger int faceN = (getWidth()-1)*(getHeight()-1)*2; 302363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 303e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger if (store!=null){ 304e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger if (store.remaining() < faceN*3) 30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru throw new BufferUnderflowException(); 30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }else{ 30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru store = BufferUtils.createIntBuffer(faceN*3); 308 } 309 310 int i = 0; 311 for (int z = 0; z < getHeight()-1; z++){ 312 for (int x = 0; x < getWidth()-1; x++){ 313 store.put(i).put(i+getWidth()).put(i+getWidth()+1); 314 store.put(i+getWidth()+1).put(i+1).put(i); 315 i++; 316 317 // TODO: There's probably a better way to do this.. 318 if (x==getWidth()-2) i++; 319 } 320 } 321 store.flip(); 322 323 return store; 324 } 325 326 public Mesh createMesh(Vector3f scale, Vector2f tcScale, boolean center){ 327 FloatBuffer pb = writeVertexArray(null, scale, center); 328 FloatBuffer tb = writeTexCoordArray(null, Vector2f.ZERO, tcScale); 329 FloatBuffer nb = writeNormalArray(null, scale); 330 IntBuffer ib = writeIndexArray(null); 331 Mesh m = new Mesh(); 332 m.setBuffer(Type.Position, 3, pb); 333 m.setBuffer(Type.Normal, 3, nb); 334 m.setBuffer(Type.TexCoord, 2, tb); 335 m.setBuffer(Type.Index, 3, ib); 336 m.setStatic(); 337 m.updateBound(); 338 return m; 339 } 340 341 public void write(JmeExporter ex) throws IOException { 342 OutputCapsule oc = ex.getCapsule(this); 343 oc.write(hdata, "hdataarray", null); 344 oc.write(width, "width", 0); 345 oc.write(height, "height", 0); 346 oc.write(maxval, "maxval", 0); 347 } 348 349 public void read(JmeImporter im) throws IOException { 350 InputCapsule ic = im.getCapsule(this); 351 hdata = ic.readFloatArray("hdataarray", null); 352 if (hdata == null) { 353 FloatBuffer buf = ic.readFloatBuffer("hdata", null); 354 if (buf != null) { 355 hdata = new float[buf.limit()]; 356 buf.get(hdata); 357 } 358 } 359 width = ic.readInt("width", 0); 360 height = ic.readInt("height", 0); 361 maxval = ic.readInt("maxval", 0); 362 } 363 364 365} 366