public float getHeightmapHeight(float x, float z) { if (x < 0 || z < 0 || x >= size || z >= size) return 0; int idx = (int) (z * size + x); return getMesh().getFloatBuffer(Type.Position).get(idx*3+1); // 3 floats per entry (x,y,z), the +1 is to get the Y }
/** * Unlocks the mesh (sets it dynamic) to make it editable. * It will be editable but performance will be reduced. * Call lockMesh to improve performance. */ public void unlockMesh() { getMesh().setDynamic(); }
/** * Locks the mesh (sets it static) to improve performance. * But it it not editable then. Set unlock to make it editable. */ public void lockMesh() { getMesh().setStatic(); }
public Vector2f getTex(float x, float z, Vector2f store) { if (x < 0 || z < 0 || x >= size || z >= size) { store.set(Vector2f.ZERO); return store; } int idx = (int) (z * size + x); return store.set(getMesh().getFloatBuffer(Type.TexCoord).get(idx*2), getMesh().getFloatBuffer(Type.TexCoord).get(idx*2+1) ); }
protected Vector3f getMeshNormal(int x, int z) { if (x >= size || z >= size) return null; // out of range int index = (z*size+x)*3; FloatBuffer nb = (FloatBuffer)this.getMesh().getBuffer(Type.Normal).getData(); Vector3f normal = new Vector3f(); normal.x = nb.get(index); normal.y = nb.get(index+1); normal.z = nb.get(index+2); return normal; }
/** * recalculate all of the normal vectors in this terrain patch */ protected void updateNormals() { FloatBuffer newNormalBuffer = geomap.writeNormalArray(null, getWorldScale()); getMesh().getBuffer(Type.Normal).updateData(newNormalBuffer); FloatBuffer newTangentBuffer = null; FloatBuffer newBinormalBuffer = null; FloatBuffer[] tb = geomap.writeTangentArray(newNormalBuffer, newTangentBuffer, newBinormalBuffer, (FloatBuffer)getMesh().getBuffer(Type.TexCoord).getData(), getWorldScale()); newTangentBuffer = tb[0]; newBinormalBuffer = tb[1]; getMesh().getBuffer(Type.Tangent).updateData(newTangentBuffer); getMesh().getBuffer(Type.Binormal).updateData(newBinormalBuffer); }
public void updateAll() { updatedPatch.setLod(newLod); updatedPatch.setLodRight(rightLod); updatedPatch.setLodTop(topLod); updatedPatch.setLodLeft(leftLod); updatedPatch.setLodBottom(bottomLod); if (newIndexBuffer != null && isReIndexNeeded()) { updatedPatch.setPreviousLod(previousLod); updatedPatch.getMesh().clearBuffer(Type.Index); if (newIndexBuffer instanceof IntBuffer) updatedPatch.getMesh().setBuffer(Type.Index, 3, (IntBuffer)newIndexBuffer); else if (newIndexBuffer instanceof ShortBuffer) updatedPatch.getMesh().setBuffer(Type.Index, 3, (ShortBuffer)newIndexBuffer); } }
setInBuffer(this.getMesh(), s, normal, tangent, binormal); setInBuffer(right.getMesh(), 0, normal, tangent, binormal); } else { topPoint.set(0, top.getHeightmapHeight(s,s-1), -1); setInBuffer(this.getMesh(), s, normal, tangent, binormal); setInBuffer(right.getMesh(), 0, normal, tangent, binormal); setInBuffer(top.getMesh(), (s+1)*(s+1)-1, normal, tangent, binormal); setInBuffer(this.getMesh(), (s+1)*(s+1)-1, normal, tangent, binormal); setInBuffer(right.getMesh(), (s+1)*(s), normal, tangent, binormal); } else { bottomPoint.set(0, bottom.getHeightmapHeight(s,1), 1); averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal); setInBuffer(this.getMesh(), (s+1)*(s+1)-1, normal, tangent, binormal); setInBuffer(right.getMesh(), (s+1)*s, normal, tangent, binormal); setInBuffer(bottom.getMesh(), s, normal, tangent, binormal); bottomPoint.set(0, this.getHeightmapHeight(s,i+1), 1); averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal); setInBuffer(this.getMesh(), (s+1)*(i+1)-1, normal, tangent, binormal); setInBuffer(right.getMesh(), (s+1)*(i), normal, tangent, binormal); setInBuffer(this.getMesh(), 0, normal, tangent, binormal); setInBuffer(left.getMesh(), s, normal, tangent, binormal); } else { topPoint.set(0, top.getHeightmapHeight(0,s-1), -1); setInBuffer(this.getMesh(), 0, normal, tangent, binormal);
public void generateDebugTangents(Material mat) { for (int x = children.size(); --x >= 0;) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { ((TerrainQuad)child).generateDebugTangents(mat); } else if (child instanceof TerrainPatch) { Geometry debug = new Geometry( "Debug " + name, TangentBinormalGenerator.genTbnLines( ((TerrainPatch)child).getMesh(), 0.8f)); attachChild(debug); debug.setLocalTranslation(child.getLocalTranslation()); debug.setCullHint(CullHint.Never); debug.setMaterial(mat); } } }
@Override public void write(JmeExporter ex) throws IOException { // the mesh is removed, and reloaded when read() is called // this reduces the save size to 10% by not saving the mesh Mesh temp = getMesh(); mesh = null; super.write(ex); OutputCapsule oc = ex.getCapsule(this); oc.write(size, "size", 16); oc.write(totalSize, "totalSize", 16); oc.write(quadrant, "quadrant", (short)0); oc.write(stepScale, "stepScale", Vector3f.UNIT_XYZ); oc.write(offset, "offset", Vector3f.UNIT_XYZ); oc.write(offsetAmount, "offsetAmount", 0); //oc.write(lodCalculator, "lodCalculator", null); //oc.write(lodCalculatorFactory, "lodCalculatorFactory", null); oc.write(lodEntropy, "lodEntropy", null); oc.write(geomap, "geomap", null); setMesh(temp); }
public float getHeightmapHeight(float x, float z) { if (x < 0 || z < 0 || x >= size || z >= size) return 0; int idx = (int) (z * size + x); return getMesh().getFloatBuffer(Type.Position).get(idx*3+1); // 3 floats per entry (x,y,z), the +1 is to get the Y }
/** * Locks the mesh (sets it static) to improve performance. * But it it not editable then. Set unlock to make it editable. */ public void lockMesh() { getMesh().setStatic(); }
/** * Unlocks the mesh (sets it dynamic) to make it editable. * It will be editable but performance will be reduced. * Call lockMesh to improve performance. */ public void unlockMesh() { getMesh().setDynamic(); }
public Vector2f getTex(float x, float z, Vector2f store) { if (x < 0 || z < 0 || x >= size || z >= size) { store.set(Vector2f.ZERO); return store; } int idx = (int) (z * size + x); return store.set(getMesh().getFloatBuffer(Type.TexCoord).get(idx*2), getMesh().getFloatBuffer(Type.TexCoord).get(idx*2+1) ); }
protected Vector3f getMeshNormal(int x, int z) { if (x >= size || z >= size) return null; // out of range int index = (z*size+x)*3; FloatBuffer nb = (FloatBuffer)this.getMesh().getBuffer(Type.Normal).getData(); Vector3f normal = new Vector3f(); normal.x = nb.get(index); normal.y = nb.get(index+1); normal.z = nb.get(index+2); return normal; }
protected void setHeight(List<LocationHeight> locationHeights, boolean overrideHeight) { for (LocationHeight lh : locationHeights) { if (lh.x < 0 || lh.z < 0 || lh.x >= size || lh.z >= size) continue; int idx = lh.z * size + lh.x; if (overrideHeight) { geomap.getHeightArray()[idx] = lh.h; } else { float h = getMesh().getFloatBuffer(Type.Position).get(idx*3+1); geomap.getHeightArray()[idx] = h+lh.h; } } FloatBuffer newVertexBuffer = geomap.writeVertexArray(null, stepScale, false); getMesh().clearBuffer(Type.Position); getMesh().setBuffer(Type.Position, 3, newVertexBuffer); }
/** * recalculate all of the normal vectors in this terrain patch */ protected void updateNormals() { FloatBuffer newNormalBuffer = geomap.writeNormalArray(null, getWorldScale()); getMesh().getBuffer(Type.Normal).updateData(newNormalBuffer); FloatBuffer newTangentBuffer = null; FloatBuffer newBinormalBuffer = null; FloatBuffer[] tb = geomap.writeTangentArray(newNormalBuffer, newTangentBuffer, newBinormalBuffer, (FloatBuffer)getMesh().getBuffer(Type.TexCoord).getData(), getWorldScale()); newTangentBuffer = tb[0]; newBinormalBuffer = tb[1]; getMesh().getBuffer(Type.Tangent).updateData(newTangentBuffer); getMesh().getBuffer(Type.Binormal).updateData(newBinormalBuffer); }
public void updateAll() { updatedPatch.setLod(newLod); updatedPatch.setLodRight(rightLod); updatedPatch.setLodTop(topLod); updatedPatch.setLodLeft(leftLod); updatedPatch.setLodBottom(bottomLod); if (newIndexBuffer != null && isReIndexNeeded()) { updatedPatch.setPreviousLod(previousLod); updatedPatch.getMesh().clearBuffer(Type.Index); if (newIndexBuffer instanceof IntBuffer) updatedPatch.getMesh().setBuffer(Type.Index, 3, (IntBuffer)newIndexBuffer); else if (newIndexBuffer instanceof ShortBuffer) updatedPatch.getMesh().setBuffer(Type.Index, 3, (ShortBuffer)newIndexBuffer); } }
public void generateDebugTangents(Material mat) { for (int x = children.size(); --x >= 0;) { Spatial child = children.get(x); if (child instanceof TerrainQuad) { ((TerrainQuad)child).generateDebugTangents(mat); } else if (child instanceof TerrainPatch) { Geometry debug = new Geometry( "Debug " + name, TangentBinormalGenerator.genTbnLines( ((TerrainPatch)child).getMesh(), 0.8f)); attachChild(debug); debug.setLocalTranslation(child.getLocalTranslation()); debug.setCullHint(CullHint.Never); debug.setMaterial(mat); } } }
@Override public void write(JmeExporter ex) throws IOException { // the mesh is removed, and reloaded when read() is called // this reduces the save size to 10% by not saving the mesh Mesh temp = getMesh(); mesh = null; super.write(ex); OutputCapsule oc = ex.getCapsule(this); oc.write(size, "size", 16); oc.write(totalSize, "totalSize", 16); oc.write(quadrant, "quadrant", (short)0); oc.write(stepScale, "stepScale", Vector3f.UNIT_XYZ); oc.write(offset, "offset", Vector3f.UNIT_XYZ); oc.write(offsetAmount, "offsetAmount", 0); //oc.write(lodCalculator, "lodCalculator", null); //oc.write(lodCalculatorFactory, "lodCalculatorFactory", null); oc.write(lodEntropy, "lodEntropy", null); oc.write(geomap, "geomap", null); setMesh(temp); }