From 0a3f7903a4cc75a4c5dd764fb24dc3e76e5155df Mon Sep 17 00:00:00 2001 From: "Sha..rd" Date: Wed, 11 Jul 2012 00:39:25 +0000 Subject: [PATCH] * Added methods to BufferUtils to create Vector4f buffers or set them * Start implementing issue 504 (capacity -> limit) git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9556 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../com/jme3/texture/plugins/DXTFlipper.java | 9 +- .../com/jme3/animation/SkeletonControl.java | 5 +- .../src/core/com/jme3/audio/AudioBuffer.java | 2 +- engine/src/core/com/jme3/scene/BatchNode.java | 2 +- engine/src/core/com/jme3/scene/Mesh.java | 19 +--- .../src/core/com/jme3/scene/VertexBuffer.java | 8 +- .../src/core/com/jme3/util/BufferUtils.java | 47 +++++++++- .../jme3/util/TangentBinormalGenerator.java | 24 ++--- .../lodcalc/util/EntropyComputeUtil.java | 2 +- .../optimize/GeometryBatchFactory.java | 92 ++++++++++--------- .../jme3tools/optimize/TextureAtlas.java | 2 +- 11 files changed, 125 insertions(+), 87 deletions(-) diff --git a/engine/src/core-plugins/com/jme3/texture/plugins/DXTFlipper.java b/engine/src/core-plugins/com/jme3/texture/plugins/DXTFlipper.java index ff90f03b0..e1d692ddb 100644 --- a/engine/src/core-plugins/com/jme3/texture/plugins/DXTFlipper.java +++ b/engine/src/core-plugins/com/jme3/texture/plugins/DXTFlipper.java @@ -197,6 +197,7 @@ public class DXTFlipper { } public static ByteBuffer flipDXT(ByteBuffer img, int w, int h, Format format){ + int originalLimit = img.limit(); int blocksX = (int) FastMath.ceil((float)w / 4f); int blocksY = (int) FastMath.ceil((float)h / 4f); @@ -227,11 +228,9 @@ public class DXTFlipper { int bpb = type == 1 || type == 5 ? 8 : 16; ByteBuffer retImg = BufferUtils.createByteBuffer(blocksX * blocksY * bpb); - if (h == 1){ retImg.put(img); retImg.rewind(); - return retImg; }else if (h == 2){ byte[] colorBlock = new byte[8]; byte[] alphaBlock = type != 1 && type != 5 ? new byte[8] : null; @@ -265,7 +264,6 @@ public class DXTFlipper { } } retImg.rewind(); - return retImg; }else if (h >= 4){ byte[] colorBlock = new byte[8]; byte[] alphaBlock = type != 1 && type != 5 ? new byte[8] : null; @@ -309,10 +307,11 @@ public class DXTFlipper { } retImg.limit(retImg.capacity()); retImg.position(0); - return retImg; - }else{ + } else { return null; } + img.limit(originalLimit); // make sure to restore original limit. + return retImg; } } diff --git a/engine/src/core/com/jme3/animation/SkeletonControl.java b/engine/src/core/com/jme3/animation/SkeletonControl.java index fb39e589d..c6a96cd41 100644 --- a/engine/src/core/com/jme3/animation/SkeletonControl.java +++ b/engine/src/core/com/jme3/animation/SkeletonControl.java @@ -325,11 +325,10 @@ public class SkeletonControl extends AbstractControl implements Cloneable { TempVars vars = TempVars.get(); - float[] posBuf = vars.skinPositions; float[] normBuf = vars.skinNormals; - int iterations = (int) FastMath.ceil(fvb.capacity() / ((float) posBuf.length)); + int iterations = (int) FastMath.ceil(fvb.limit() / ((float) posBuf.length)); int bufLength = posBuf.length; for (int i = iterations - 1; i >= 0; i--) { // read next set of positions and normals from native buffer @@ -439,7 +438,7 @@ public class SkeletonControl extends AbstractControl implements Cloneable { float[] normBuf = vars.skinNormals; float[] tanBuf = vars.skinTangents; - int iterations = (int) FastMath.ceil(fvb.capacity() / ((float) posBuf.length)); + int iterations = (int) FastMath.ceil(fvb.limit() / ((float) posBuf.length)); int bufLength = 0; int tanLength = 0; for (int i = iterations - 1; i >= 0; i--) { diff --git a/engine/src/core/com/jme3/audio/AudioBuffer.java b/engine/src/core/com/jme3/audio/AudioBuffer.java index 7d29c496d..37d467f57 100644 --- a/engine/src/core/com/jme3/audio/AudioBuffer.java +++ b/engine/src/core/com/jme3/audio/AudioBuffer.java @@ -70,7 +70,7 @@ public class AudioBuffer extends AudioData { public float getDuration(){ int bytesPerSec = (bitsPerSample / 8) * channels * sampleRate; if (audioData != null) - return (float) audioData.capacity() / bytesPerSec; + return (float) audioData.limit() / bytesPerSec; else return Float.NaN; // unknown } diff --git a/engine/src/core/com/jme3/scene/BatchNode.java b/engine/src/core/com/jme3/scene/BatchNode.java index 96fa69489..5e7d3da71 100644 --- a/engine/src/core/com/jme3/scene/BatchNode.java +++ b/engine/src/core/com/jme3/scene/BatchNode.java @@ -665,7 +665,7 @@ public class BatchNode extends Node implements Savable { // convert to be in component units offset *= componentSize; - for (int i = 0; i < inBuf.capacity() / componentSize; i++) { + for (int i = 0; i < inBuf.limit() / componentSize; i++) { pos.x = inBuf.get(i * componentSize + 0); pos.y = inBuf.get(i * componentSize + 1); pos.z = inBuf.get(i * componentSize + 2); diff --git a/engine/src/core/com/jme3/scene/Mesh.java b/engine/src/core/com/jme3/scene/Mesh.java index 036e52567..2a854e2eb 100644 --- a/engine/src/core/com/jme3/scene/Mesh.java +++ b/engine/src/core/com/jme3/scene/Mesh.java @@ -687,10 +687,10 @@ public class Mesh implements Savable, Cloneable { VertexBuffer pb = getBuffer(Type.Position); VertexBuffer ib = getBuffer(Type.Index); if (pb != null){ - vertCount = pb.getData().capacity() / pb.getNumComponents(); + vertCount = pb.getData().limit() / pb.getNumComponents(); } if (ib != null){ - elementCount = computeNumElements(ib.getData().capacity()); + elementCount = computeNumElements(ib.getData().limit()); }else{ elementCount = computeNumElements(vertCount); } @@ -710,7 +710,7 @@ public class Mesh implements Savable, Cloneable { if (lod >= lodLevels.length) throw new IllegalArgumentException("LOD level "+lod+" does not exist!"); - return computeNumElements(lodLevels[lod].getData().capacity()); + return computeNumElements(lodLevels[lod].getData().limit()); }else if (lod == 0){ return elementCount; }else{ @@ -1039,16 +1039,7 @@ public class Mesh implements Savable, Cloneable { if (vb == null) return null; - Buffer buf = vb.getData(); - if (buf instanceof ByteBuffer) { - return new IndexByteBuffer((ByteBuffer) buf); - } else if (buf instanceof ShortBuffer) { - return new IndexShortBuffer((ShortBuffer) buf); - } else if (buf instanceof IntBuffer) { - return new IndexIntBuffer((IntBuffer) buf); - } else { - throw new UnsupportedOperationException("Index buffer type unsupported: "+ buf.getClass()); - } + return IndexBuffer.wrapIndexBuffer(vb.getData()); } /** @@ -1188,7 +1179,7 @@ public class Mesh implements Savable, Cloneable { FloatBuffer fb = (FloatBuffer) tc.getData(); fb.clear(); - for (int i = 0; i < fb.capacity() / 2; i++){ + for (int i = 0; i < fb.limit() / 2; i++){ float x = fb.get(); float y = fb.get(); fb.position(fb.position()-2); diff --git a/engine/src/core/com/jme3/scene/VertexBuffer.java b/engine/src/core/com/jme3/scene/VertexBuffer.java index 64a75b495..bb1551b06 100644 --- a/engine/src/core/com/jme3/scene/VertexBuffer.java +++ b/engine/src/core/com/jme3/scene/VertexBuffer.java @@ -495,7 +495,7 @@ public class VertexBuffer extends NativeObject implements Savable, Cloneable { * @return The total number of data elements in the data buffer. */ public int getNumElements(){ - int elements = data.capacity() / components; + int elements = data.limit() / components; if (format == Format.Half) elements /= 2; return elements; @@ -595,7 +595,7 @@ public class VertexBuffer extends NativeObject implements Savable, Cloneable { if (format != Format.Float) throw new IllegalStateException("Format must be float!"); - int numElements = data.capacity() / components; + int numElements = data.limit() / components; format = Format.Half; this.componentsLength = components * format.getComponentSize(); @@ -605,7 +605,7 @@ public class VertexBuffer extends NativeObject implements Savable, Cloneable { FloatBuffer floatData = (FloatBuffer) data; floatData.rewind(); - for (int i = 0; i < floatData.capacity(); i++){ + for (int i = 0; i < floatData.limit(); i++){ float f = floatData.get(i); short half = FastMath.convertFloatToHalf(f); halfData.putShort(half); @@ -931,7 +931,7 @@ public class VertexBuffer extends NativeObject implements Savable, Cloneable { public String toString(){ String dataTxt = null; if (data != null){ - dataTxt = ", elements="+data.capacity(); + dataTxt = ", elements="+data.limit(); } return getClass().getSimpleName() + "[fmt="+format.name() +", type="+bufType.name() diff --git a/engine/src/core/com/jme3/util/BufferUtils.java b/engine/src/core/com/jme3/util/BufferUtils.java index 36bfb93ce..022209f73 100644 --- a/engine/src/core/com/jme3/util/BufferUtils.java +++ b/engine/src/core/com/jme3/util/BufferUtils.java @@ -31,10 +31,7 @@ */ package com.jme3.util; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; +import com.jme3.math.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.*; @@ -196,6 +193,28 @@ public final class BufferUtils { buff.flip(); return buff; } + + /** + * Generate a new FloatBuffer using the given array of Vector4 objects. + * The FloatBuffer will be 4 * data.length long and contain the vector data. + * + * @param data array of Vector4 objects to place into a new FloatBuffer + */ + public static FloatBuffer createFloatBuffer(Vector4f... data) { + if (data == null) { + return null; + } + FloatBuffer buff = createFloatBuffer(4 * data.length); + for (int x = 0; x < data.length; x++) { + if (data[x] != null) { + buff.put(data[x].getX()).put(data[x].getY()).put(data[x].getZ()).put(data[x].getW()); + } else { + buff.put(0).put(0).put(0); + } + } + buff.flip(); + return buff; + } /** * Generate a new FloatBuffer using the given array of float primitives. @@ -286,6 +305,26 @@ public final class BufferUtils { buf.put(quat.getZ()); buf.put(quat.getW()); } + + /** + * Sets the data contained in the given vector4 into the FloatBuffer at the + * specified index. + * + * @param vec + * the {@link Vector4f} to insert + * @param buf + * the buffer to insert into + * @param index + * the postion to place the data; in terms of vector4 not floats + */ + public static void setInBuffer(Vector4f vec, FloatBuffer buf, + int index) { + buf.position(index * 4); + buf.put(vec.getX()); + buf.put(vec.getY()); + buf.put(vec.getZ()); + buf.put(vec.getW()); + } /** * Sets the data contained in the given Vector3F into the FloatBuffer at the diff --git a/engine/src/core/com/jme3/util/TangentBinormalGenerator.java b/engine/src/core/com/jme3/util/TangentBinormalGenerator.java index 13eded2d0..ffff22037 100644 --- a/engine/src/core/com/jme3/util/TangentBinormalGenerator.java +++ b/engine/src/core/com/jme3/util/TangentBinormalGenerator.java @@ -191,7 +191,7 @@ public class TangentBinormalGenerator { FloatBuffer textureBuffer = (FloatBuffer) mesh.getBuffer(Type.TexCoord).getData(); - VertexData[] vertices = initVertexData(vertexBuffer.capacity() / 3); + VertexData[] vertices = initVertexData(vertexBuffer.limit() / 3); for (int i = 0; i < indexBuffer.size() / 3; i++) { for (int j = 0; j < 3; j++) { @@ -217,7 +217,7 @@ public class TangentBinormalGenerator { FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData(); FloatBuffer textureBuffer = (FloatBuffer) mesh.getBuffer(Type.TexCoord).getData(); - VertexData[] vertices = initVertexData(vertexBuffer.capacity() / 3); + VertexData[] vertices = initVertexData(vertexBuffer.limit() / 3); index[0] = indexBuffer.get(0); index[1] = indexBuffer.get(1); @@ -265,7 +265,7 @@ public class TangentBinormalGenerator { FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData(); FloatBuffer textureBuffer = (FloatBuffer) mesh.getBuffer(Type.TexCoord).getData(); - VertexData[] vertices = initVertexData(vertexBuffer.capacity() / 3); + VertexData[] vertices = initVertexData(vertexBuffer.limit() / 3); index[0] = indexBuffer.get(0); index[1] = indexBuffer.get(1); @@ -276,7 +276,7 @@ public class TangentBinormalGenerator { populateFromBuffer(t[0], textureBuffer, index[0]); populateFromBuffer(t[1], textureBuffer, index[1]); - for (int i = 2; i < vertexBuffer.capacity() / 3; i++) { + for (int i = 2; i < vertexBuffer.limit() / 3; i++) { index[2] = indexBuffer.get(i); populateFromBuffer(v[2], vertexBuffer, index[2]); populateFromBuffer(t[2], textureBuffer, index[2]); @@ -406,7 +406,7 @@ public class TangentBinormalGenerator { Vector3f normal = new Vector3f(); Vector2f texCoord = new Vector2f(); - final int size = vertexBuffer.capacity() / 3; + final int size = vertexBuffer.limit() / 3; for (int i = 0; i < size; i++) { populateFromBuffer(position, vertexBuffer, i); @@ -638,10 +638,10 @@ public class TangentBinormalGenerator { Vector3f origin = new Vector3f(); Vector3f point = new Vector3f(); - FloatBuffer lineVertex = BufferUtils.createFloatBuffer(vertexBuffer.capacity() * 2); - FloatBuffer lineColor = BufferUtils.createFloatBuffer(vertexBuffer.capacity() / 3 * 4 * 2); + FloatBuffer lineVertex = BufferUtils.createFloatBuffer(vertexBuffer.limit() * 2); + FloatBuffer lineColor = BufferUtils.createFloatBuffer(vertexBuffer.limit() / 3 * 4 * 2); - for (int i = 0; i < vertexBuffer.capacity() / 3; i++) { + for (int i = 0; i < vertexBuffer.limit() / 3; i++) { populateFromBuffer(origin, vertexBuffer, i); populateFromBuffer(point, normalBuffer, i); @@ -687,14 +687,14 @@ public class TangentBinormalGenerator { Vector3f tangent = new Vector3f(); Vector3f normal = new Vector3f(); - IntBuffer lineIndex = BufferUtils.createIntBuffer(vertexBuffer.capacity() / 3 * 6); - FloatBuffer lineVertex = BufferUtils.createFloatBuffer(vertexBuffer.capacity() * 4); - FloatBuffer lineColor = BufferUtils.createFloatBuffer(vertexBuffer.capacity() / 3 * 4 * 4); + IntBuffer lineIndex = BufferUtils.createIntBuffer(vertexBuffer.limit() / 3 * 6); + FloatBuffer lineVertex = BufferUtils.createFloatBuffer(vertexBuffer.limit() * 4); + FloatBuffer lineColor = BufferUtils.createFloatBuffer(vertexBuffer.limit() / 3 * 4 * 4); boolean hasParity = mesh.getBuffer(Type.Tangent).getNumComponents() == 4; float tangentW = 1; - for (int i = 0; i < vertexBuffer.capacity() / 3; i++) { + for (int i = 0; i < vertexBuffer.limit() / 3; i++) { populateFromBuffer(origin, vertexBuffer, i); populateFromBuffer(normal, normalBuffer, i); diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/util/EntropyComputeUtil.java b/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/util/EntropyComputeUtil.java index c358aae10..a2e4678c3 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/util/EntropyComputeUtil.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/lodcalc/util/EntropyComputeUtil.java @@ -47,7 +47,7 @@ public class EntropyComputeUtil { terrainBlock.createCollisionData(); float entropy = 0; - for (int i = 0; i < positions.capacity() / 3; i++){ + for (int i = 0; i < positions.limit() / 3; i++){ BufferUtils.populateFromBuffer(pos, positions, i); float realHeight = pos.y; diff --git a/engine/src/tools/jme3tools/optimize/GeometryBatchFactory.java b/engine/src/tools/jme3tools/optimize/GeometryBatchFactory.java index 596ac7f32..7cc09ef15 100644 --- a/engine/src/tools/jme3tools/optimize/GeometryBatchFactory.java +++ b/engine/src/tools/jme3tools/optimize/GeometryBatchFactory.java @@ -28,7 +28,7 @@ public class GeometryBatchFactory { // convert to be in component units offset *= 3; - for (int i = 0; i < inBuf.capacity() / 3; i++) { + for (int i = 0; i < inBuf.limit() / 3; i++) { pos.x = inBuf.get(i * 3 + 0); pos.y = inBuf.get(i * 3 + 1); pos.z = inBuf.get(i * 3 + 2); @@ -48,7 +48,7 @@ public class GeometryBatchFactory { // convert to be in component units offset *= 3; - for (int i = 0; i < inBuf.capacity() / 3; i++) { + for (int i = 0; i < inBuf.limit() / 3; i++) { norm.x = inBuf.get(i * 3 + 0); norm.y = inBuf.get(i * 3 + 1); norm.z = inBuf.get(i * 3 + 2); @@ -68,7 +68,7 @@ public class GeometryBatchFactory { // convert to be in component units offset *= components; - for (int i = 0; i < inBuf.capacity() / components; i++) { + for (int i = 0; i < inBuf.limit() / components; i++) { tan.x = inBuf.get(i * components + 0); tan.y = inBuf.get(i * components + 1); tan.z = inBuf.get(i * components + 2); @@ -224,52 +224,62 @@ public class GeometryBatchFactory { } public static void makeLods(Collection geometries, Mesh outMesh) { - int lodLevels = 0; - int[] lodSize = null; - int index = 0; + // Determine number of LOD levels required. + int lodLevels = Integer.MAX_VALUE; for (Geometry g : geometries) { - if (lodLevels == 0) { - lodLevels = g.getMesh().getNumLodLevels(); - } - if (lodSize == null) { - lodSize = new int[lodLevels]; - } - for (int i = 0; i < lodLevels; i++) { - lodSize[i] += g.getMesh().getLodLevel(i).getData().capacity(); - //if( i == 0) System.out.println(index + " " +lodSize[i]); - } - index++; + lodLevels = Math.min(lodLevels, g.getMesh().getNumLodLevels()); } - int[][] lodData = new int[lodLevels][]; - for (int i = 0; i < lodLevels; i++) { - lodData[i] = new int[lodSize[i]]; + if (lodLevels == Integer.MAX_VALUE || lodLevels == 0) { + // No LOD on any of the meshes. + return; } - VertexBuffer[] lods = new VertexBuffer[lodLevels]; - int bufferPos[] = new int[lodLevels]; - //int index = 0; - int numOfVertices = 0; - int curGeom = 0; + + // Sizes of the final LOD index buffers for each level. + int[] lodSizes = new int[lodLevels]; for (Geometry g : geometries) { - if (numOfVertices == 0) { - numOfVertices = g.getVertexCount(); - } for (int i = 0; i < lodLevels; i++) { - ShortBuffer buffer = (ShortBuffer) g.getMesh().getLodLevel(i).getDataReadOnly(); - //System.out.println("buffer: " + buffer.capacity() + " limit: " + lodSize[i] + " " + index); - for (int j = 0; j < buffer.capacity(); j++) { - lodData[i][bufferPos[i] + j] = buffer.get() + numOfVertices * curGeom; - //bufferPos[i]++; - } - bufferPos[i] += buffer.capacity(); + lodSizes[i] += g.getMesh().getLodLevel(i).getData().limit(); } - curGeom++; } - for (int i = 0; i < lodLevels; i++) { - lods[i] = new VertexBuffer(Type.Index); - lods[i].setupData(Usage.Dynamic, 1, Format.UnsignedInt, BufferUtils.createIntBuffer(lodData[i])); + + // final LOD buffers for each LOD level. + IndexBuffer[] lods = new IndexBuffer[lodLevels]; + int bufferPos[] = new int[lodLevels]; + int numOfVertices = 0; + int curGeom = 0; + +// int components = compsForBuf[bufType]; +// for (int tri = 0; tri < geomTriCount; tri++) { +// for (int comp = 0; comp < components; comp++) { +// int idx = inIdx.get(tri * components + comp) + globalVertIndex; +// outIdx.put((globalTriIndex + tri) * components + comp, idx); +// } +// } + + for (int lodLevel = 0; lodLevel < lodLevels; lodLevel++) { + } - System.out.println(lods.length); - outMesh.setLodLevels(lods); + +// for (Geometry g : geometries) { +// if (numOfVertices == 0) { +// numOfVertices = g.getVertexCount(); +// } +// for (int i = 0; i < lodLevels; i++) { +// IndexBuffer buffer = IndexBuffer.wrapIndexBuffer(g.getMesh().getLodLevel(i).getData()); +// //System.out.println("buffer: " + buffer.capacity() + " limit: " + lodSize[i] + " " + index); +// for (int j = 0; j < buffer.size(); j++) { +// lodData[i][bufferPos[i] + j] = buffer.get(j) + numOfVertices * curGeom; +// //bufferPos[i]++; +// } +// bufferPos[i] += buffer.size(); +// } +// curGeom++; +// } +// for (int i = 0; i < lodLevels; i++) { +// lods[i] = new VertexBuffer(Type.Index); +// lods[i].setupData(Usage.Dynamic, 1, Format.UnsignedInt, BufferUtils.createIntBuffer(lodData[i])); +// } +// outMesh.setLodLevels(lods); } public static List makeBatches(Collection geometries) { diff --git a/engine/src/tools/jme3tools/optimize/TextureAtlas.java b/engine/src/tools/jme3tools/optimize/TextureAtlas.java index ef8ac120f..c7a032414 100644 --- a/engine/src/tools/jme3tools/optimize/TextureAtlas.java +++ b/engine/src/tools/jme3tools/optimize/TextureAtlas.java @@ -657,7 +657,7 @@ public class TextureAtlas { // convert to be in component units offset *= 2; - for (int i = 0; i < inBuf.capacity() / 2; i++) { + for (int i = 0; i < inBuf.limit() / 2; i++) { tex.x = inBuf.get(i * 2 + 0); tex.y = inBuf.get(i * 2 + 1); Vector2f location = getLocation(tex);