|
@@ -47,6 +47,7 @@ import com.jme3.scene.Mesh;
|
|
|
import com.jme3.scene.Mesh.Mode;
|
|
|
import com.jme3.scene.VertexBuffer.Type;
|
|
|
import com.jme3.util.BufferUtils;
|
|
|
+import com.jme3.util.TangentBinormalGenerator;
|
|
|
import java.io.IOException;
|
|
|
|
|
|
/**
|
|
@@ -80,10 +81,12 @@ public class LODGeomap extends GeoMap {
|
|
|
FloatBuffer tb = writeTexCoordArray(null, tcOffset, tcScale, offsetAmount, totalSize);
|
|
|
FloatBuffer nb = writeNormalArray(null, scale);
|
|
|
IntBuffer ib = writeIndexArrayLodDiff(null, lod, rightLod, topLod, leftLod, bottomLod);
|
|
|
+ FloatBuffer tanb = writeTangentArray(null, scale);
|
|
|
Mesh m = new Mesh();
|
|
|
m.setMode(Mode.TriangleStrip);
|
|
|
m.setBuffer(Type.Position, 3, pb);
|
|
|
m.setBuffer(Type.Normal, 3, nb);
|
|
|
+ m.setBuffer(Type.Tangent, 3, tanb);
|
|
|
m.setBuffer(Type.TexCoord, 2, tb);
|
|
|
m.setBuffer(Type.Index, 3, ib);
|
|
|
m.setStatic();
|
|
@@ -110,8 +113,8 @@ public class LODGeomap extends GeoMap {
|
|
|
|
|
|
Vector2f tcStore = new Vector2f();
|
|
|
|
|
|
- for (int y = 0; y < getHeight(); y++) {
|
|
|
-
|
|
|
+ // work from bottom of heightmap up, so we don't flip the coords
|
|
|
+ for (int y = getHeight()-1; y >= 0; y--) {
|
|
|
for (int x = 0; x < getWidth(); x++) {
|
|
|
getUV(x, y, tcStore, offset, offsetAmount, totalSize);
|
|
|
float tx = tcStore.x * scale.x;
|
|
@@ -125,8 +128,8 @@ public class LODGeomap extends GeoMap {
|
|
|
}
|
|
|
|
|
|
public Vector2f getUV(int x, int y, Vector2f store, Vector2f offset, float offsetAmount, int totalSize) {
|
|
|
- float offsetX = offset.x + (offsetAmount * 1.0f);//stepScale.x);
|
|
|
- float offsetY = offset.y + (offsetAmount * 1.0f);//stepScale.z);
|
|
|
+ float offsetX = offset.x + (offsetAmount * 1.0f);
|
|
|
+ float offsetY = -offset.y + (offsetAmount * 1.0f);//note the -, we flip the tex coords
|
|
|
|
|
|
store.set((((float) x) + offsetX) / (float) totalSize, // calculates percentage of texture here
|
|
|
(((float) y) + offsetY) / (float) totalSize);
|
|
@@ -620,7 +623,44 @@ public class LODGeomap extends GeoMap {
|
|
|
//System.out.println("Index buffer size: "+num);
|
|
|
return num;
|
|
|
}
|
|
|
+
|
|
|
+ public FloatBuffer writeTangentArray(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();
|
|
|
+
|
|
|
+ Vector3f tangent = new Vector3f();
|
|
|
+ Vector3f v1 = new Vector3f();
|
|
|
+ Vector3f v2 = new Vector3f();
|
|
|
+
|
|
|
+ for (int r = 0; r < getHeight(); r++) {
|
|
|
+ for (int c = 0; c < getWidth(); c++) {
|
|
|
+
|
|
|
+ v1.set(c, getValue(c, r), r);
|
|
|
+
|
|
|
+ if (c == getWidth()-1) { // last column
|
|
|
+ v2.set(c+1, getValue(c, r ), r); // use same height
|
|
|
+ } else {
|
|
|
+ v2.set(c+1, getValue(c+1, r), r);
|
|
|
+ }
|
|
|
+ tangent.set(v2.mult(scale).subtract(v1.mult(scale)));
|
|
|
+ BufferUtils.setInBuffer(tangent, store, (r * getWidth() + c)); // save the tangent
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return store;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
@Override
|
|
|
public FloatBuffer writeNormalArray(FloatBuffer store, Vector3f scale) {
|
|
|
if (!isLoaded()) {
|
|
@@ -653,34 +693,34 @@ public class LODGeomap extends GeoMap {
|
|
|
if (c == 0) { // first column
|
|
|
rightPoint.set(c + 1, getValue(c + 1, r), r);
|
|
|
bottomPoint.set(c, getValue(c, r + 1), r + 1);
|
|
|
- normal.set(getNormal(bottomPoint, rootPoint, rightPoint));
|
|
|
+ normal.set(getNormal(bottomPoint, rootPoint, rightPoint, scale));
|
|
|
} else if (c == getWidth() - 1) { // last column
|
|
|
leftPoint.set(c - 1, getValue(c - 1, r), r);
|
|
|
bottomPoint.set(c, getValue(c, r + 1), r + 1);
|
|
|
- normal.set(getNormal(leftPoint, rootPoint, bottomPoint));
|
|
|
+ normal.set(getNormal(leftPoint, rootPoint, bottomPoint, scale));
|
|
|
} else { // all middle columns
|
|
|
leftPoint.set(c - 1, getValue(c - 1, r), r);
|
|
|
rightPoint.set(c + 1, getValue(c + 1, r), r);
|
|
|
bottomPoint.set(c, getValue(c, r + 1), r + 1);
|
|
|
- Vector3f n1 = getNormal(leftPoint, rootPoint, bottomPoint);
|
|
|
- Vector3f n2 = getNormal(bottomPoint, rootPoint, rightPoint);
|
|
|
+ Vector3f n1 = getNormal(leftPoint, rootPoint, bottomPoint, scale);
|
|
|
+ Vector3f n2 = getNormal(bottomPoint, rootPoint, rightPoint, scale);
|
|
|
normal.set(n1.add(n2).normalizeLocal());
|
|
|
}
|
|
|
} else if (r == getHeight() - 1) { // last row
|
|
|
if (c == 0) { // first column
|
|
|
topPoint.set(c, getValue(c, r - 1), r - 1);
|
|
|
rightPoint.set(c + 1, getValue(c + 1, r), r);
|
|
|
- normal.set(getNormal(rightPoint, rootPoint, topPoint));
|
|
|
+ normal.set(getNormal(rightPoint, rootPoint, topPoint, scale));
|
|
|
} else if (c == getWidth() - 1) { // last column
|
|
|
topPoint.set(c, getValue(c, r - 1), r - 1);
|
|
|
leftPoint.set(c - 1, getValue(c - 1, r), r);
|
|
|
- normal.set(getNormal(topPoint, rootPoint, leftPoint));
|
|
|
+ normal.set(getNormal(topPoint, rootPoint, leftPoint, scale));
|
|
|
} else { // all middle columns
|
|
|
topPoint.set(c, getValue(c, r - 1), r - 1);
|
|
|
leftPoint.set(c - 1, getValue(c - 1, r), r);
|
|
|
rightPoint.set(c + 1, getValue(c + 1, r), r);
|
|
|
- Vector3f n1 = getNormal(topPoint, rootPoint, leftPoint);
|
|
|
- Vector3f n2 = getNormal(rightPoint, rootPoint, topPoint);
|
|
|
+ Vector3f n1 = getNormal(topPoint, rootPoint, leftPoint, scale);
|
|
|
+ Vector3f n2 = getNormal(rightPoint, rootPoint, topPoint, scale);
|
|
|
normal.set(n1.add(n2).normalizeLocal());
|
|
|
}
|
|
|
} else { // all middle rows
|
|
@@ -688,25 +728,25 @@ public class LODGeomap extends GeoMap {
|
|
|
topPoint.set(c, getValue(c, r - 1), r - 1);
|
|
|
rightPoint.set(c + 1, getValue(c + 1, r), r);
|
|
|
bottomPoint.set(c, getValue(c, r + 1), r + 1);
|
|
|
- Vector3f n1 = getNormal(rightPoint, rootPoint, topPoint);
|
|
|
- Vector3f n2 = getNormal(bottomPoint, rootPoint, rightPoint);
|
|
|
+ Vector3f n1 = getNormal(rightPoint, rootPoint, topPoint, scale);
|
|
|
+ Vector3f n2 = getNormal(bottomPoint, rootPoint, rightPoint, scale);
|
|
|
normal.set(n1.add(n2).normalizeLocal());
|
|
|
} else if (c == getWidth() - 1) { // last column
|
|
|
topPoint.set(c, getValue(c, r - 1), r - 1);
|
|
|
leftPoint.set(c - 1, getValue(c - 1, r), r);
|
|
|
bottomPoint.set(c, getValue(c, r + 1), r + 1);
|
|
|
- Vector3f n1 = getNormal(topPoint, rootPoint, leftPoint);
|
|
|
- Vector3f n2 = getNormal(leftPoint, rootPoint, bottomPoint);
|
|
|
+ Vector3f n1 = getNormal(topPoint, rootPoint, leftPoint, scale);
|
|
|
+ Vector3f n2 = getNormal(leftPoint, rootPoint, bottomPoint, scale);
|
|
|
normal.set(n1.add(n2).normalizeLocal());
|
|
|
} else { // all middle columns
|
|
|
topPoint.set(c, getValue(c, r - 1), r - 1);
|
|
|
leftPoint.set(c - 1, getValue(c - 1, r), r);
|
|
|
rightPoint.set(c + 1, getValue(c + 1, r), r);
|
|
|
bottomPoint.set(c, getValue(c, r + 1), r + 1);
|
|
|
- Vector3f n1 = getNormal(topPoint, rootPoint, leftPoint);
|
|
|
- Vector3f n2 = getNormal(leftPoint, rootPoint, bottomPoint);
|
|
|
- Vector3f n3 = getNormal(bottomPoint, rootPoint, rightPoint);
|
|
|
- Vector3f n4 = getNormal(rightPoint, rootPoint, topPoint);
|
|
|
+ Vector3f n1 = getNormal(topPoint, rootPoint, leftPoint, scale);
|
|
|
+ Vector3f n2 = getNormal(leftPoint, rootPoint, bottomPoint, scale);
|
|
|
+ Vector3f n3 = getNormal(bottomPoint, rootPoint, rightPoint, scale);
|
|
|
+ Vector3f n4 = getNormal(rightPoint, rootPoint, topPoint, scale);
|
|
|
normal.set(n1.add(n2).add(n3).add(n4).normalizeLocal());
|
|
|
}
|
|
|
}
|
|
@@ -719,9 +759,10 @@ public class LODGeomap extends GeoMap {
|
|
|
return store;
|
|
|
}
|
|
|
|
|
|
- private Vector3f getNormal(Vector3f firstPoint, Vector3f rootPoint, Vector3f secondPoint) {
|
|
|
+ private Vector3f getNormal(Vector3f firstPoint, Vector3f rootPoint, Vector3f secondPoint, Vector3f scale) {
|
|
|
Vector3f normal = new Vector3f();
|
|
|
- normal.set(firstPoint).subtractLocal(rootPoint).crossLocal(secondPoint.subtract(rootPoint)).normalizeLocal();
|
|
|
+ //scale = Vector3f.UNIT_XYZ;
|
|
|
+ normal.set(firstPoint.mult(scale)).subtractLocal(rootPoint.mult(scale)).crossLocal(secondPoint.mult(scale).subtract(rootPoint.mult(scale))).normalizeLocal();
|
|
|
return normal;
|
|
|
}
|
|
|
|