removed unused geomap classes, replaced with single GeoMap class (part 1 of 2 part commit, blasted netbeans)
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7819 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
parent
c5d0b7b8e8
commit
1a78dd200c
@ -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; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -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; r<height; r++) { |
|
||||||
for (int c=0; c<width; c++) { |
|
||||||
float f = fb.get( (width*r) + c + 1); |
|
||||||
hdata.put( f ); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,183 +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 java.nio.FloatBuffer; |
|
||||||
import java.nio.IntBuffer; |
|
||||||
|
|
||||||
public interface Geomap { |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns true if this Geomap has a normalmap associated with it |
|
||||||
*/ |
|
||||||
public boolean hasNormalmap(); |
|
||||||
|
|
||||||
/** |
|
||||||
* 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 The maximum possible value that <code>getValue()</code> 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); |
|
||||||
} |
|
@ -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);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//}
|
|
@ -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); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -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(); |
|
||||||
|
|
||||||
} |
|
@ -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 <code>getValue()</code> 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<height; r++) { |
||||||
|
for (int c=0; c<width; c++) { |
||||||
|
float f = fb.get( (width*r) + c + 1); |
||||||
|
hdata.put( f ); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue