From e09a5a5b092d415307c9116dba4dd65272701cef Mon Sep 17 00:00:00 2001 From: Nehon Date: Sat, 9 Sep 2017 14:31:26 +0200 Subject: [PATCH 1/7] glTF: fixed data reading to properly support interleaved data. --- .../jme3/scene/plugins/gltf/GltfLoader.java | 16 +-- .../jme3/scene/plugins/gltf/GltfUtils.java | 136 +++++++++++------- 2 files changed, 95 insertions(+), 57 deletions(-) diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java index 88a3e8382..25ce90977 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java @@ -455,7 +455,7 @@ public class GltfLoader implements AssetLoader { return data; } - public void readBuffer(Integer bufferViewIndex, int byteOffset, int bufferSize, Object store, int numComponents, VertexBuffer.Format format) throws IOException { + public void readBuffer(Integer bufferViewIndex, int byteOffset, int count, Object store, int numComponents, VertexBuffer.Format format) throws IOException { JsonObject bufferView = bufferViews.get(bufferViewIndex).getAsJsonObject(); Integer bufferIndex = getAsInteger(bufferView, "buffer"); @@ -473,7 +473,7 @@ public class GltfLoader implements AssetLoader { data = customContentManager.readExtensionAndExtras("bufferView", bufferView, data); - populateBuffer(store, data, bufferSize, byteOffset + bvByteOffset, byteStride, numComponents, format); + populateBuffer(store, data, count, byteOffset + bvByteOffset, byteStride, numComponents, format); } @@ -1260,7 +1260,7 @@ public class GltfLoader implements AssetLoader { //no referenced buffer, specs says to pad the buffer with zeros. padBuffer(buff, bufferSize); } else { - readBuffer(bufferViewIndex, byteOffset, bufferSize, buff, numComponents, originalFormat); + readBuffer(bufferViewIndex, byteOffset, count, buff, numComponents, originalFormat); } if (bufferType == VertexBuffer.Type.Index) { @@ -1286,7 +1286,7 @@ public class GltfLoader implements AssetLoader { //no referenced buffer, specs says to pad the data with zeros. padBuffer(data, dataSize); } else { - readBuffer(bufferViewIndex, byteOffset, dataSize, data, numComponents, getVertexBufferFormat(componentType)); + readBuffer(bufferViewIndex, byteOffset, count, data, numComponents, getVertexBufferFormat(componentType)); } return data; @@ -1307,7 +1307,7 @@ public class GltfLoader implements AssetLoader { //no referenced buffer, specs says to pad the data with zeros. padBuffer(data, dataSize); } else { - readBuffer(bufferViewIndex, byteOffset, dataSize, data, numComponents, getVertexBufferFormat(componentType)); + readBuffer(bufferViewIndex, byteOffset, count, data, numComponents, getVertexBufferFormat(componentType)); } return data; } @@ -1326,7 +1326,7 @@ public class GltfLoader implements AssetLoader { //no referenced buffer, specs says to pad the data with zeros. padBuffer(data, dataSize); } else { - readBuffer(bufferViewIndex, byteOffset, dataSize, data, numComponents, getVertexBufferFormat(componentType)); + readBuffer(bufferViewIndex, byteOffset, count, data, numComponents, getVertexBufferFormat(componentType)); } return data; @@ -1346,7 +1346,7 @@ public class GltfLoader implements AssetLoader { //no referenced buffer, specs says to pad the data with zeros. padBuffer(data, dataSize); } else { - readBuffer(bufferViewIndex, byteOffset, dataSize, data, numComponents, getVertexBufferFormat(componentType)); + readBuffer(bufferViewIndex, byteOffset, count, data, numComponents, getVertexBufferFormat(componentType)); } return data; @@ -1373,7 +1373,7 @@ public class GltfLoader implements AssetLoader { //no referenced buffer, specs says to pad the data with zeros. padBuffer(data, dataSize); } else { - readBuffer(bufferViewIndex, byteOffset, dataSize, data, numComponents, format); + readBuffer(bufferViewIndex, byteOffset, count, data, numComponents, format); } return new SkinBuffers(data, format.getComponentSize()); diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfUtils.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfUtils.java index bd92d6c01..75d48d06c 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfUtils.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfUtils.java @@ -3,13 +3,8 @@ package com.jme3.scene.plugins.gltf; import com.google.gson.*; import com.jme3.asset.AssetInfo; import com.jme3.asset.AssetLoadException; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Matrix4f; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Mesh; -import com.jme3.scene.Spatial; -import com.jme3.scene.VertexBuffer; +import com.jme3.math.*; +import com.jme3.scene.*; import com.jme3.texture.Texture; import com.jme3.util.*; @@ -237,92 +232,113 @@ public class GltfUtils { } } - public static void populateBuffer(Object store, byte[] source, int length, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { + public static void populateBuffer(Object store, byte[] source, int count, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { if (store instanceof Buffer) { Buffer buffer = (Buffer) store; buffer.clear(); if (buffer instanceof ByteBuffer) { - populateByteBuffer((ByteBuffer) buffer, source, length, byteOffset, byteStride, numComponents, format); + populateByteBuffer((ByteBuffer) buffer, source, count, byteOffset, byteStride, numComponents, format); return; } LittleEndien stream = getStream(source); if (buffer instanceof ShortBuffer) { - populateShortBuffer((ShortBuffer) buffer, stream, length, byteOffset, byteStride, numComponents, format); + populateShortBuffer((ShortBuffer) buffer, stream, count, byteOffset, byteStride, numComponents, format); } else if (buffer instanceof IntBuffer) { - populateIntBuffer((IntBuffer) buffer, stream, length, byteOffset, byteStride, numComponents, format); + populateIntBuffer((IntBuffer) buffer, stream, count, byteOffset, byteStride, numComponents, format); } else if (buffer instanceof FloatBuffer) { - populateFloatBuffer((FloatBuffer) buffer, stream, length, byteOffset, byteStride, numComponents, format); + populateFloatBuffer((FloatBuffer) buffer, stream, count, byteOffset, byteStride, numComponents, format); } buffer.rewind(); return; } LittleEndien stream = getStream(source); if (store instanceof short[]) { - populateShortArray((short[]) store, stream, length, byteOffset, byteStride, numComponents, format); + populateShortArray((short[]) store, stream, count, byteOffset, byteStride, numComponents, format); } else if (store instanceof float[]) { - populateFloatArray((float[]) store, stream, length, byteOffset, byteStride, numComponents, format); + populateFloatArray((float[]) store, stream, count, byteOffset, byteStride, numComponents, format); } else if (store instanceof Vector3f[]) { - populateVector3fArray((Vector3f[]) store, stream, length, byteOffset, byteStride, numComponents, format); + populateVector3fArray((Vector3f[]) store, stream, count, byteOffset, byteStride, numComponents, format); } else if (store instanceof Quaternion[]) { - populateQuaternionArray((Quaternion[]) store, stream, length, byteOffset, byteStride, numComponents, format); + populateQuaternionArray((Quaternion[]) store, stream, count, byteOffset, byteStride, numComponents, format); } else if (store instanceof Matrix4f[]) { - populateMatrix4fArray((Matrix4f[]) store, stream, length, byteOffset, byteStride, numComponents, format); + populateMatrix4fArray((Matrix4f[]) store, stream, count, byteOffset, byteStride, numComponents, format); } } - private static void populateByteBuffer(ByteBuffer buffer, byte[] source, int length, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) { + private static void populateByteBuffer(ByteBuffer buffer, byte[] source, int count, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) { int componentSize = format.getComponentSize(); int index = byteOffset; - while (index < length + byteOffset) { + int dataLength = componentSize * numComponents; + int stride = Math.max(dataLength, byteStride); + int end = count * stride + byteOffset; + while (index < end) { for (int i = 0; i < numComponents; i++) { buffer.put(source[index + i]); } - index += Math.max(componentSize * numComponents, byteStride); + index += stride; } } - private static void populateShortBuffer(ShortBuffer buffer, LittleEndien stream, int length, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { + private static void populateShortBuffer(ShortBuffer buffer, LittleEndien stream, int count, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { int componentSize = format.getComponentSize(); int index = byteOffset; - int end = length * componentSize + byteOffset; + int dataLength = componentSize * numComponents; + int stride = Math.max(dataLength, byteStride); + int end = count * stride + byteOffset; stream.skipBytes(byteOffset); while (index < end) { for (int i = 0; i < numComponents; i++) { buffer.put(stream.readShort()); } - index += Math.max(componentSize * numComponents, byteStride); + + if (dataLength < stride) { + stream.skipBytes(stride - dataLength); + } + index += stride; } + System.err.println(""); } - private static void populateIntBuffer(IntBuffer buffer, LittleEndien stream, int length, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { + + private static void populateIntBuffer(IntBuffer buffer, LittleEndien stream, int count, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { int componentSize = format.getComponentSize(); int index = byteOffset; - int end = length * componentSize + byteOffset; + int dataLength = componentSize * numComponents; + int stride = Math.max(dataLength, byteStride); + int end = count * stride + byteOffset; stream.skipBytes(byteOffset); while (index < end) { for (int i = 0; i < numComponents; i++) { buffer.put(stream.readInt()); } - index += Math.max(componentSize * numComponents, byteStride); + if (dataLength < stride) { + stream.skipBytes(stride - dataLength); + } + index += stride; } } - private static void populateFloatBuffer(FloatBuffer buffer, LittleEndien stream, int length, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { + private static void populateFloatBuffer(FloatBuffer buffer, LittleEndien stream, int count, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { int componentSize = format.getComponentSize(); int index = byteOffset; - int end = length * componentSize + byteOffset; + int dataLength = componentSize * numComponents; + int stride = Math.max(dataLength, byteStride); + int end = count * stride + byteOffset; stream.skipBytes(byteOffset); while (index < end) { for (int i = 0; i < numComponents; i++) { buffer.put(readAsFloat(stream, format)); } - index += Math.max(componentSize * numComponents, byteStride); + if (dataLength < stride) { + stream.skipBytes(stride - dataLength); + } + index += stride; } } - private static float readAsFloat(LittleEndien stream, VertexBuffer.Format format) throws IOException { + public static float readAsFloat(LittleEndien stream, VertexBuffer.Format format) throws IOException { //We may have packed data so depending on the format, we need to read data differently and unpack it // Implementations must use following equations to get corresponding floating-point value f from a normalized integer c and vise-versa: // accessor.componentType int-to-float float-to-int @@ -351,10 +367,12 @@ public class GltfUtils { } - private static void populateShortArray(short[] array, LittleEndien stream, int length, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { + private static void populateShortArray(short[] array, LittleEndien stream, int count, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { int componentSize = format.getComponentSize(); int index = byteOffset; - int end = length * componentSize + byteOffset; + int dataLength = componentSize * numComponents; + int stride = Math.max(dataLength, byteStride); + int end = count * stride + byteOffset; stream.skipBytes(byteOffset); int arrayIndex = 0; while (index < end) { @@ -366,8 +384,10 @@ public class GltfUtils { } arrayIndex++; } - - index += Math.max(componentSize * numComponents, byteStride); + if (dataLength < stride) { + stream.skipBytes(stride - dataLength); + } + index += stride; } } @@ -447,10 +467,12 @@ public class GltfUtils { mesh.setBuffer(VertexBuffer.Type.BoneWeight, 4, BufferUtils.createFloatBuffer(weightsArray)); } - private static void populateFloatArray(float[] array, LittleEndien stream, int length, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { + private static void populateFloatArray(float[] array, LittleEndien stream, int count, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { int componentSize = format.getComponentSize(); int index = byteOffset; - int end = length * componentSize + byteOffset; + int dataLength = componentSize * numComponents; + int stride = Math.max(dataLength, byteStride); + int end = count * stride + byteOffset; stream.skipBytes(byteOffset); int arrayIndex = 0; while (index < end) { @@ -458,15 +480,19 @@ public class GltfUtils { array[arrayIndex] = readAsFloat(stream, format); arrayIndex++; } - - index += Math.max(componentSize * numComponents, byteStride); + if (dataLength < stride) { + stream.skipBytes(stride - dataLength); + } + index += stride; } } - private static void populateVector3fArray(Vector3f[] array, LittleEndien stream, int length, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { + private static void populateVector3fArray(Vector3f[] array, LittleEndien stream, int count, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { int componentSize = format.getComponentSize(); int index = byteOffset; - int end = length * componentSize + byteOffset; + int dataLength = componentSize * numComponents; + int stride = Math.max(dataLength, byteStride); + int end = count * stride + byteOffset; stream.skipBytes(byteOffset); int arrayIndex = 0; while (index < end) { @@ -477,15 +503,20 @@ public class GltfUtils { ); arrayIndex++; + if (dataLength < stride) { + stream.skipBytes(stride - dataLength); + } - index += Math.max(componentSize * numComponents, byteStride); + index += stride; } } - private static void populateQuaternionArray(Quaternion[] array, LittleEndien stream, int length, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { + private static void populateQuaternionArray(Quaternion[] array, LittleEndien stream, int count, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { int componentSize = format.getComponentSize(); int index = byteOffset; - int end = length * componentSize + byteOffset; + int dataLength = componentSize * numComponents; + int stride = Math.max(dataLength, byteStride); + int end = count * stride + byteOffset; stream.skipBytes(byteOffset); int arrayIndex = 0; while (index < end) { @@ -497,15 +528,19 @@ public class GltfUtils { ); arrayIndex++; - - index += Math.max(componentSize * numComponents, byteStride); + if (dataLength < stride) { + stream.skipBytes(stride - dataLength); + } + index += stride; } } - private static void populateMatrix4fArray(Matrix4f[] array, LittleEndien stream, int length, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { + private static void populateMatrix4fArray(Matrix4f[] array, LittleEndien stream, int count, int byteOffset, int byteStride, int numComponents, VertexBuffer.Format format) throws IOException { int componentSize = format.getComponentSize(); int index = byteOffset; - int end = length * componentSize + byteOffset; + int dataLength = componentSize * numComponents; + int stride = Math.max(dataLength, byteStride); + int end = count * stride + byteOffset; stream.skipBytes(byteOffset); int arrayIndex = 0; while (index < end) { @@ -531,8 +566,11 @@ public class GltfUtils { //gltf matrix are column major, JME ones are row major. arrayIndex++; + if (dataLength < stride) { + stream.skipBytes(stride - dataLength); + } - index += Math.max(componentSize * numComponents, byteStride); + index += stride; } } @@ -566,7 +604,7 @@ public class GltfUtils { return key.isKeepSkeletonPose(); } - private static LittleEndien getStream(byte[] buffer) { + public static LittleEndien getStream(byte[] buffer) { return new LittleEndien(new DataInputStream(new ByteArrayInputStream(buffer))); } From 7f8fa4d74c86dd2821ba756b5e6439f9224bbf35 Mon Sep 17 00:00:00 2001 From: Kirill Vainer Date: Thu, 7 Sep 2017 23:07:38 -0400 Subject: [PATCH 2/7] Fix depth texture support in OpenGL ES 2.0 --- .../main/java/com/jme3/renderer/opengl/GLImageFormats.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java index f12bfd1bc..23bee3604 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java @@ -206,9 +206,14 @@ public final class GLImageFormats { // Need to check if Caps.DepthTexture is supported prior to using for textures // But for renderbuffers its OK. - format(formatToGL, Format.Depth, GL.GL_DEPTH_COMPONENT, GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_BYTE); format(formatToGL, Format.Depth16, GL.GL_DEPTH_COMPONENT16, GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_SHORT); + // NOTE: OpenGL ES 2.0 does not support DEPTH_COMPONENT as internal format -- fallback to 16-bit depth. + if (caps.contains(Caps.OpenGLES20)) { + format(formatToGL, Format.Depth, GL.GL_DEPTH_COMPONENT16, GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_BYTE); + } else { + format(formatToGL, Format.Depth, GL.GL_DEPTH_COMPONENT, GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_BYTE); + } if (caps.contains(Caps.OpenGL20)) { format(formatToGL, Format.Depth24, GL2.GL_DEPTH_COMPONENT24, GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_INT); } From 381d69ccb7367b47367f9eb7f06b279a8674bd83 Mon Sep 17 00:00:00 2001 From: Kirill Vainer Date: Thu, 7 Sep 2017 23:02:45 -0400 Subject: [PATCH 3/7] Support LWJGL 3.1.2 --- jme3-lwjgl3/build.gradle | 5 ++++- .../main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java | 12 ++++++------ .../main/java/com/jme3/opencl/lwjgl/LwjglImage.java | 12 ++++++------ .../main/java/com/jme3/opencl/lwjgl/info/CLUtil.java | 2 +- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/jme3-lwjgl3/build.gradle b/jme3-lwjgl3/build.gradle index 0abb4928b..785ce75de 100644 --- a/jme3-lwjgl3/build.gradle +++ b/jme3-lwjgl3/build.gradle @@ -2,7 +2,7 @@ if (!hasProperty('mainClass')) { ext.mainClass = '' } -def lwjglVersion = '3.1.0' +def lwjglVersion = '3.1.2' sourceCompatibility = '1.8' @@ -25,6 +25,9 @@ dependencies { runtime "org.lwjgl:lwjgl-jemalloc:${lwjglVersion}:natives-windows" runtime "org.lwjgl:lwjgl-jemalloc:${lwjglVersion}:natives-linux" runtime "org.lwjgl:lwjgl-jemalloc:${lwjglVersion}:natives-macos" + runtime "org.lwjgl:lwjgl-opengl:${lwjglVersion}:natives-windows" + runtime "org.lwjgl:lwjgl-opengl:${lwjglVersion}:natives-linux" + runtime "org.lwjgl:lwjgl-opengl:${lwjglVersion}:natives-macos" runtime "org.lwjgl:lwjgl-openal:${lwjglVersion}:natives-windows" runtime "org.lwjgl:lwjgl-openal:${lwjglVersion}:natives-linux" runtime "org.lwjgl:lwjgl-openal:${lwjglVersion}:natives-macos" diff --git a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java index 522cb48c7..3921e5320 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java @@ -67,7 +67,7 @@ public class LwjglBuffer extends Buffer { //Note: LWJGL does not support the size parameter, I have to set the buffer limit dest.limit((int) (dest.position() + size)); int ret = CL10.clEnqueueReadBuffer(((LwjglCommandQueue)queue).getQueue(), - buffer, CL10.CL_TRUE, offset, dest, null, null); + buffer, true, offset, dest, null, null); Utils.checkError(ret, "clEnqueueReadBuffer"); } @@ -77,7 +77,7 @@ public class LwjglBuffer extends Buffer { dest.limit((int) (dest.position() + size)); Utils.pointerBuffers[0].rewind(); long q = ((LwjglCommandQueue)queue).getQueue(); - int ret = CL10.clEnqueueReadBuffer(q, buffer, CL10.CL_FALSE, offset, dest, null, Utils.pointerBuffers[0]); + int ret = CL10.clEnqueueReadBuffer(q, buffer, false, offset, dest, null, Utils.pointerBuffers[0]); Utils.checkError(ret, "clEnqueueReadBuffer"); long event = Utils.pointerBuffers[0].get(0); return new LwjglEvent(event); @@ -88,7 +88,7 @@ public class LwjglBuffer extends Buffer { //Note: LWJGL does not support the size parameter, I have to set the buffer limit src.limit((int) (src.position() + size)); long q = ((LwjglCommandQueue)queue).getQueue(); - int ret = CL10.clEnqueueWriteBuffer(q, buffer, CL10.CL_TRUE, offset, src, null, null); + int ret = CL10.clEnqueueWriteBuffer(q, buffer, true, offset, src, null, null); Utils.checkError(ret, "clEnqueueWriteBuffer"); } @@ -98,7 +98,7 @@ public class LwjglBuffer extends Buffer { src.limit((int) (src.position() + size)); Utils.pointerBuffers[0].rewind(); long q = ((LwjglCommandQueue)queue).getQueue(); - int ret = CL10.clEnqueueWriteBuffer(q, buffer, CL10.CL_FALSE, offset, src, null, Utils.pointerBuffers[0]); + int ret = CL10.clEnqueueWriteBuffer(q, buffer, false, offset, src, null, Utils.pointerBuffers[0]); Utils.checkError(ret, "clEnqueueWriteBuffer"); long event = Utils.pointerBuffers[0].get(0); return new LwjglEvent(event); @@ -130,7 +130,7 @@ public class LwjglBuffer extends Buffer { long q = ((LwjglCommandQueue) queue).getQueue(); long flags = Utils.getMappingAccessFlags(access); Utils.errorBuffer.rewind(); - ByteBuffer b = CL10.clEnqueueMapBuffer(q, buffer, CL10.CL_TRUE, flags, offset, size, null, null, Utils.errorBuffer, null); + ByteBuffer b = CL10.clEnqueueMapBuffer(q, buffer, true, flags, offset, size, null, null, Utils.errorBuffer, null); Utils.checkError(Utils.errorBuffer, "clEnqueueMapBuffer"); return b; } @@ -153,7 +153,7 @@ public class LwjglBuffer extends Buffer { Utils.errorBuffer.rewind(); long q = ((LwjglCommandQueue) queue).getQueue(); long flags = Utils.getMappingAccessFlags(access); - ByteBuffer buf = CL10.clEnqueueMapBuffer(q, buffer, CL10.CL_FALSE, flags, offset, size, null, Utils.pointerBuffers[0], Utils.errorBuffer, null); + ByteBuffer buf = CL10.clEnqueueMapBuffer(q, buffer, false, flags, offset, size, null, Utils.pointerBuffers[0], Utils.errorBuffer, null); Utils.checkError(Utils.errorBuffer, "clEnqueueMapBuffer"); long event = Utils.pointerBuffers[0].get(0); return new com.jme3.opencl.Buffer.AsyncMapping(new LwjglEvent(event), buf); diff --git a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java index 30171772f..bf6f86281 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java @@ -302,7 +302,7 @@ public class LwjglImage extends Image { Utils.pointerBuffers[1].put(origin).position(0); Utils.pointerBuffers[2].put(region).position(0); long q = ((LwjglCommandQueue) queue).getQueue(); - int ret = CL10.clEnqueueReadImage(q, image, CL10.CL_TRUE, + int ret = CL10.clEnqueueReadImage(q, image, true, Utils.pointerBuffers[1], Utils.pointerBuffers[2], rowPitch, slicePitch, dest, null, null); Utils.checkError(ret, "clEnqueueReadImage"); @@ -319,7 +319,7 @@ public class LwjglImage extends Image { Utils.pointerBuffers[1].put(origin).position(0); Utils.pointerBuffers[2].put(region).position(0); long q = ((LwjglCommandQueue) queue).getQueue(); - int ret = CL10.clEnqueueReadImage(q, image, CL10.CL_FALSE, + int ret = CL10.clEnqueueReadImage(q, image, false, Utils.pointerBuffers[1], Utils.pointerBuffers[2], rowPitch, slicePitch, dest, null, Utils.pointerBuffers[0]); Utils.checkError(ret, "clEnqueueReadImage"); @@ -337,7 +337,7 @@ public class LwjglImage extends Image { Utils.pointerBuffers[1].put(origin).position(0); Utils.pointerBuffers[2].put(region).position(0); long q = ((LwjglCommandQueue) queue).getQueue(); - int ret = CL10.clEnqueueWriteImage(q, image, CL10.CL_TRUE, + int ret = CL10.clEnqueueWriteImage(q, image, true, Utils.pointerBuffers[1], Utils.pointerBuffers[2], rowPitch, slicePitch, dest, null, null); Utils.checkError(ret, "clEnqueueWriteImage"); @@ -354,7 +354,7 @@ public class LwjglImage extends Image { Utils.pointerBuffers[1].put(origin).position(0); Utils.pointerBuffers[2].put(region).position(0); long q = ((LwjglCommandQueue) queue).getQueue(); - int ret = CL10.clEnqueueWriteImage(q, image, CL10.CL_FALSE, + int ret = CL10.clEnqueueWriteImage(q, image, false, Utils.pointerBuffers[1], Utils.pointerBuffers[2], rowPitch, slicePitch, dest, null, Utils.pointerBuffers[0]); Utils.checkError(ret, "clEnqueueWriteImage"); @@ -419,7 +419,7 @@ public class LwjglImage extends Image { long q = ((LwjglCommandQueue) queue).getQueue(); long flags = Utils.getMappingAccessFlags(access); Utils.errorBuffer.rewind(); - ByteBuffer buf = CL10.clEnqueueMapImage(q, image, CL10.CL_TRUE, flags, + ByteBuffer buf = CL10.clEnqueueMapImage(q, image, true, flags, Utils.pointerBuffers[1], Utils.pointerBuffers[2], Utils.pointerBuffers[3], Utils.pointerBuffers[4], null, null, Utils.errorBuffer, null); @@ -442,7 +442,7 @@ public class LwjglImage extends Image { long q = ((LwjglCommandQueue) queue).getQueue(); long flags = Utils.getMappingAccessFlags(access); Utils.errorBuffer.rewind(); - ByteBuffer buf = CL10.clEnqueueMapImage(q, image, CL10.CL_FALSE, flags, + ByteBuffer buf = CL10.clEnqueueMapImage(q, image, false, flags, Utils.pointerBuffers[1], Utils.pointerBuffers[2], Utils.pointerBuffers[3], Utils.pointerBuffers[4], null, Utils.pointerBuffers[0], Utils.errorBuffer, null); diff --git a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/CLUtil.java b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/CLUtil.java index 3e1e64598..c63339aef 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/CLUtil.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/CLUtil.java @@ -4,7 +4,7 @@ */ package com.jme3.opencl.lwjgl.info; -import com.jme3.lwjgl3.utils.APIUtil.TokenFilter; +import static com.jme3.lwjgl3.utils.APIUtil.apiOptionalClass; import com.jme3.opencl.OpenCLException; import java.lang.reflect.Field; import java.nio.ByteBuffer; From bf18ef304833a5428362e85fdd479b578e5f10df Mon Sep 17 00:00:00 2001 From: Kirill Vainer Date: Mon, 4 Sep 2017 12:39:56 -0400 Subject: [PATCH 4/7] Use MPOs for skinning --- .../java/com/jme3/animation/Skeleton.java | 4 +- .../com/jme3/animation/SkeletonControl.java | 135 +++++++----------- 2 files changed, 55 insertions(+), 84 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/animation/Skeleton.java b/jme3-core/src/main/java/com/jme3/animation/Skeleton.java index 47efc629d..904d7a298 100644 --- a/jme3-core/src/main/java/com/jme3/animation/Skeleton.java +++ b/jme3-core/src/main/java/com/jme3/animation/Skeleton.java @@ -70,7 +70,7 @@ public final class Skeleton implements Savable, JmeCloneable { public Skeleton(Bone[] boneList) { this.boneList = boneList; - List rootBoneList = new ArrayList(); + List rootBoneList = new ArrayList<>(); for (int i = boneList.length - 1; i >= 0; i--) { Bone b = boneList[i]; if (b.getParent() == null) { @@ -289,6 +289,7 @@ public final class Skeleton implements Savable, JmeCloneable { return sb.toString(); } + @Override public void read(JmeImporter im) throws IOException { InputCapsule input = im.getCapsule(this); @@ -308,6 +309,7 @@ public final class Skeleton implements Savable, JmeCloneable { } } + @Override public void write(JmeExporter ex) throws IOException { OutputCapsule output = ex.getCapsule(this); output.write(rootBones, "rootBones", null); diff --git a/jme3-core/src/main/java/com/jme3/animation/SkeletonControl.java b/jme3-core/src/main/java/com/jme3/animation/SkeletonControl.java index 63e4d09e3..4cefd721c 100644 --- a/jme3-core/src/main/java/com/jme3/animation/SkeletonControl.java +++ b/jme3-core/src/main/java/com/jme3/animation/SkeletonControl.java @@ -32,8 +32,7 @@ package com.jme3.animation; import com.jme3.export.*; -import com.jme3.material.MatParam; -import com.jme3.material.Material; +import com.jme3.material.MatParamOverride; import com.jme3.math.FastMath; import com.jme3.math.Matrix4f; import com.jme3.renderer.RenderManager; @@ -43,6 +42,7 @@ import com.jme3.scene.*; import com.jme3.scene.VertexBuffer.Type; import com.jme3.scene.control.AbstractControl; import com.jme3.scene.control.Control; +import com.jme3.scene.mesh.IndexBuffer; import com.jme3.shader.VarType; import com.jme3.util.*; import com.jme3.util.clone.Cloner; @@ -51,8 +51,6 @@ import java.io.IOException; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.FloatBuffer; -import java.util.HashSet; -import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -107,13 +105,11 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl * Bone offset matrices, recreated each frame */ private transient Matrix4f[] offsetMatrices; - /** - * Material references used for hardware skinning - */ - private Set materials = new HashSet(); - //temp reader - private BufferUtils.ByteShortIntBufferReader indexReader = new BufferUtils.ByteShortIntBufferReader(); + + private MatParamOverride numberOfBonesParam; + private MatParamOverride boneMatricesParam; + /** * Serialization only. Do not use. */ @@ -121,11 +117,13 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl } private void switchToHardware() { + numberOfBonesParam.setEnabled(true); + boneMatricesParam.setEnabled(true); + // Next full 10 bones (e.g. 30 on 24 bones) int numBones = ((skeleton.getBoneCount() / 10) + 1) * 10; - for (Material m : materials) { - m.setInt("NumberOfBones", numBones); - } + numberOfBonesParam.setValue(numBones); + for (Geometry geometry : targets) { Mesh mesh = geometry.getMesh(); if (mesh != null && mesh.isAnimated()) { @@ -135,11 +133,9 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl } private void switchToSoftware() { - for (Material m : materials) { - if (m.getParam("NumberOfBones") != null) { - m.clearParam("NumberOfBones"); - } - } + numberOfBonesParam.setEnabled(false); + boneMatricesParam.setEnabled(false); + for (Geometry geometry : targets) { Mesh mesh = geometry.getMesh(); if (mesh != null && mesh.isAnimated()) { @@ -149,19 +145,6 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl } private boolean testHardwareSupported(RenderManager rm) { - for (Material m : materials) { - // Some of the animated mesh(es) do not support hardware skinning, - // so it is not supported by the model. - if (m.getMaterialDef().getMaterialParam("NumberOfBones") == null) { - Logger.getLogger(SkeletonControl.class.getName()).log(Level.WARNING, - "Not using hardware skinning for {0}, " + - "because material {1} doesn''t support it.", - new Object[]{spatial, m.getMaterialDef().getName()}); - - return false; - } - } - switchToHardware(); try { @@ -178,6 +161,7 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl * supported by GPU, it shall be enabled, if its not preferred, or not * supported by GPU, then it shall be disabled. * + * @param preferred * @see #isHardwareSkinningUsed() */ public void setHardwareSkinningPreferred(boolean preferred) { @@ -212,6 +196,8 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl throw new IllegalArgumentException("skeleton cannot be null"); } this.skeleton = skeleton; + this.numberOfBonesParam = new MatParamOverride(VarType.Int, "NumberOfBones", null); + this.boneMatricesParam = new MatParamOverride(VarType.Matrix4Array, "BoneMatrices", null); } /** @@ -222,8 +208,8 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl Mesh mesh = geometry.getMesh(); if (mesh != null && mesh.isAnimated()) { targets.add(geometry); - materials.add(geometry.getMaterial()); } + } private void findTargets(Node node) { @@ -238,8 +224,21 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl @Override public void setSpatial(Spatial spatial) { + Spatial oldSpatial = this.spatial; super.setSpatial(spatial); updateTargetsAndMaterials(spatial); + + if (oldSpatial != null) { + oldSpatial.removeMatParamOverride(numberOfBonesParam); + oldSpatial.removeMatParamOverride(boneMatricesParam); + } + + if (spatial != null) { + spatial.removeMatParamOverride(numberOfBonesParam); + spatial.removeMatParamOverride(boneMatricesParam); + spatial.addMatParamOverride(numberOfBonesParam); + spatial.addMatParamOverride(boneMatricesParam); + } } private void controlRenderSoftware() { @@ -258,27 +257,8 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl private void controlRenderHardware() { offsetMatrices = skeleton.computeSkinningMatrices(); - for (Material m : materials) { - MatParam currentParam = m.getParam("BoneMatrices"); - - if (currentParam != null) { - if (currentParam.getValue() != offsetMatrices) { - // Check to see if other SkeletonControl - // is operating on this material, in that case, user - // is sharing materials between models which is NOT allowed - // when hardware skinning used. - - Logger.getLogger(SkeletonControl.class.getName()).log(Level.SEVERE, - "Material instances cannot be shared when hardware skinning is used. " + - "Ensure all models use unique material instances." - ); - } - } - - m.setParam("BoneMatrices", VarType.Matrix4Array, offsetMatrices); - } + boneMatricesParam.setValue(offsetMatrices); } - @Override protected void controlRender(RenderManager rm, ViewPort vp) { @@ -296,7 +276,7 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl if (hwSkinningSupported) { hwSkinningEnabled = true; - Logger.getLogger(SkeletonControl.class.getName()).log(Level.INFO, "Hardware skinning engaged for " + spatial); + Logger.getLogger(SkeletonControl.class.getName()).log(Level.INFO, "Hardware skinning engaged for {0}", spatial); } else { switchToSoftware(); } @@ -420,28 +400,8 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl // were shared then this will share them. this.targets = cloner.clone(targets); - // Not automatic set cloning yet - Set newMaterials = new HashSet(); - for( Material m : this.materials ) { - Material mClone = cloner.clone(m); - newMaterials.add(mClone); - if( mClone != m ) { - // Material was really cloned so clear the bone matrices in case - // this is hardware skinned. This allows a local version to be - // used and will be reset on the material. Really this just avoids - // the 'safety' check in controlRenderHardware(). Right now material - // doesn't clone itself with the cloner (and doesn't clone its parameters) - // else this would be unnecessary. - MatParam boneMatrices = mClone.getParam("BoneMatrices"); - - // ...because for some strange reason you can't clear a non-existant - // parameter. - if( boneMatrices != null ) { - mClone.clearParam("BoneMatrices"); - } - } - } - this.materials = newMaterials; + this.numberOfBonesParam = cloner.clone(numberOfBonesParam); + this.boneMatricesParam = cloner.clone(boneMatricesParam); } /** @@ -547,10 +507,9 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl fnb.rewind(); // get boneIndexes and weights for mesh - indexReader.setBuffer(mesh.getBuffer(Type.BoneIndex).getData()); + IndexBuffer ib = IndexBuffer.wrapIndexBuffer(mesh.getBuffer(Type.BoneIndex).getData()); FloatBuffer wb = (FloatBuffer) mesh.getBuffer(Type.BoneWeight).getData(); - indexReader.rewind(); wb.rewind(); float[] weights = wb.array(); @@ -591,7 +550,7 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl for (int w = maxWeightsPerVert - 1; w >= 0; w--) { float weight = weights[idxWeights]; - Matrix4f mat = offsetMatrices[indexReader.getUnsigned(idxWeights++)]; + Matrix4f mat = offsetMatrices[ib.get(idxWeights++)]; rx += (mat.m00 * vtx + mat.m01 * vty + mat.m02 * vtz + mat.m03) * weight; ry += (mat.m10 * vtx + mat.m11 * vty + mat.m12 * vtz + mat.m13) * weight; @@ -664,10 +623,9 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl // get boneIndexes and weights for mesh - indexReader.setBuffer(mesh.getBuffer(Type.BoneIndex).getData()); + IndexBuffer ib = IndexBuffer.wrapIndexBuffer(mesh.getBuffer(Type.BoneIndex).getData()); FloatBuffer wb = (FloatBuffer) mesh.getBuffer(Type.BoneWeight).getData(); - indexReader.rewind(); wb.rewind(); float[] weights = wb.array(); @@ -723,7 +681,7 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl for (int w = maxWeightsPerVert - 1; w >= 0; w--) { float weight = weights[idxWeights]; - Matrix4f mat = offsetMatrices[indexReader.getUnsigned(idxWeights++)]; + Matrix4f mat = offsetMatrices[ib.get(idxWeights++)]; rx += (mat.m00 * vtx + mat.m01 * vty + mat.m02 * vtz + mat.m03) * weight; ry += (mat.m10 * vtx + mat.m11 * vty + mat.m12 * vtz + mat.m13) * weight; @@ -781,7 +739,9 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl super.write(ex); OutputCapsule oc = ex.getCapsule(this); oc.write(skeleton, "skeleton", null); - //Targets and materials don't need to be saved, they'll be gathered on each frame + + oc.write(numberOfBonesParam, "numberOfBonesParam", null); + oc.write(boneMatricesParam, "boneMatricesParam", null); } @Override @@ -789,6 +749,16 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl super.read(im); InputCapsule in = im.getCapsule(this); skeleton = (Skeleton) in.readSavable("skeleton", null); + + numberOfBonesParam = (MatParamOverride) in.readSavable("numberOfBonesParam", null); + boneMatricesParam = (MatParamOverride) in.readSavable("boneMatricesParam", null); + + if (numberOfBonesParam == null) { + numberOfBonesParam = new MatParamOverride(VarType.Int, "NumberOfBones", null); + boneMatricesParam = new MatParamOverride(VarType.Matrix4Array, "BoneMatrices", null); + getSpatial().addMatParamOverride(numberOfBonesParam); + getSpatial().addMatParamOverride(boneMatricesParam); + } } /** @@ -798,7 +768,6 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl */ private void updateTargetsAndMaterials(Spatial spatial) { targets.clear(); - materials.clear(); if (spatial instanceof Node) { findTargets((Node) spatial); From d606c30a529c6fd61b25e06f8c2caed521f742d7 Mon Sep 17 00:00:00 2001 From: Nehon Date: Sat, 9 Sep 2017 14:58:27 +0200 Subject: [PATCH 5/7] Used IndexBuffer instead of the ByteShortIntBufferReader and removed the class --- .../src/main/java/com/jme3/scene/Mesh.java | 2 +- .../java/com/jme3/scene/mesh/IndexBuffer.java | 24 +++++++- .../com/jme3/scene/mesh/IndexByteBuffer.java | 7 ++- .../com/jme3/scene/mesh/IndexIntBuffer.java | 4 ++ .../com/jme3/scene/mesh/IndexShortBuffer.java | 4 ++ .../jme3/scene/mesh/VirtualIndexBuffer.java | 18 ++++++ .../main/java/com/jme3/util/BufferUtils.java | 58 ------------------- 7 files changed, 56 insertions(+), 61 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/scene/Mesh.java b/jme3-core/src/main/java/com/jme3/scene/Mesh.java index bc9781040..87dff6aec 100644 --- a/jme3-core/src/main/java/com/jme3/scene/Mesh.java +++ b/jme3-core/src/main/java/com/jme3/scene/Mesh.java @@ -1447,7 +1447,7 @@ public class Mesh implements Savable, Cloneable, JmeCloneable { return false; // no bone animation data } - BufferUtils.ByteShortIntBufferReader boneIndexBuffer = new BufferUtils.ByteShortIntBufferReader(biBuf.getData()); + IndexBuffer boneIndexBuffer = IndexBuffer.wrapIndexBuffer(biBuf.getData()); boneIndexBuffer.rewind(); int numBoneIndices = boneIndexBuffer.remaining(); assert numBoneIndices % 4 == 0 : numBoneIndices; diff --git a/jme3-core/src/main/java/com/jme3/scene/mesh/IndexBuffer.java b/jme3-core/src/main/java/com/jme3/scene/mesh/IndexBuffer.java index a67bb6704..43846b541 100644 --- a/jme3-core/src/main/java/com/jme3/scene/mesh/IndexBuffer.java +++ b/jme3-core/src/main/java/com/jme3/scene/mesh/IndexBuffer.java @@ -75,7 +75,29 @@ public abstract class IndexBuffer { return new IndexShortBuffer(BufferUtils.createShortBuffer(indexCount)); } } - + + /** + * @see Buffer#rewind() + */ + public void rewind() { + getBuffer().rewind(); + } + + /** + * @return + * @see Buffer#remaining() + */ + public int remaining() { + return getBuffer().remaining(); + } + + /** + * Returns the vertex index for the current position. + * + * @return + */ + public abstract int get(); + /** * Returns the vertex index for the given index in the index buffer. * diff --git a/jme3-core/src/main/java/com/jme3/scene/mesh/IndexByteBuffer.java b/jme3-core/src/main/java/com/jme3/scene/mesh/IndexByteBuffer.java index 2c06c25a9..ab7461c2a 100644 --- a/jme3-core/src/main/java/com/jme3/scene/mesh/IndexByteBuffer.java +++ b/jme3-core/src/main/java/com/jme3/scene/mesh/IndexByteBuffer.java @@ -47,7 +47,12 @@ public class IndexByteBuffer extends IndexBuffer { buf = buffer; buf.rewind(); } - + + @Override + public int get() { + return buf.get() & 0x000000FF; + } + @Override public int get(int i) { return buf.get(i) & 0x000000FF; diff --git a/jme3-core/src/main/java/com/jme3/scene/mesh/IndexIntBuffer.java b/jme3-core/src/main/java/com/jme3/scene/mesh/IndexIntBuffer.java index 4412be260..ca109ba66 100644 --- a/jme3-core/src/main/java/com/jme3/scene/mesh/IndexIntBuffer.java +++ b/jme3-core/src/main/java/com/jme3/scene/mesh/IndexIntBuffer.java @@ -48,6 +48,10 @@ public class IndexIntBuffer extends IndexBuffer { buf.rewind(); } + @Override + public int get() { + return buf.get(); + } @Override public int get(int i) { return buf.get(i); diff --git a/jme3-core/src/main/java/com/jme3/scene/mesh/IndexShortBuffer.java b/jme3-core/src/main/java/com/jme3/scene/mesh/IndexShortBuffer.java index 5f3c25ae9..e87b5533f 100644 --- a/jme3-core/src/main/java/com/jme3/scene/mesh/IndexShortBuffer.java +++ b/jme3-core/src/main/java/com/jme3/scene/mesh/IndexShortBuffer.java @@ -48,6 +48,10 @@ public class IndexShortBuffer extends IndexBuffer { buf.rewind(); } + @Override + public int get() { + return buf.get() & 0x0000FFFF; + } @Override public int get(int i) { return buf.get(i) & 0x0000FFFF; diff --git a/jme3-core/src/main/java/com/jme3/scene/mesh/VirtualIndexBuffer.java b/jme3-core/src/main/java/com/jme3/scene/mesh/VirtualIndexBuffer.java index 18fefa90a..64aa438eb 100644 --- a/jme3-core/src/main/java/com/jme3/scene/mesh/VirtualIndexBuffer.java +++ b/jme3-core/src/main/java/com/jme3/scene/mesh/VirtualIndexBuffer.java @@ -55,6 +55,7 @@ public class VirtualIndexBuffer extends IndexBuffer { protected int numVerts = 0; protected int numIndices = 0; protected Mode meshMode; + protected int position = 0; public VirtualIndexBuffer(int numVerts, Mode meshMode){ this.numVerts = numVerts; @@ -86,6 +87,23 @@ public class VirtualIndexBuffer extends IndexBuffer { } } + @Override + public int get() { + int i = get(position); + position++; + return i; + } + + @Override + public void rewind() { + position = 0; + } + + @Override + public int remaining() { + return numIndices - position; + } + @Override public int get(int i) { if (meshMode == Mode.Triangles || meshMode == Mode.Lines || meshMode == Mode.Points){ diff --git a/jme3-core/src/main/java/com/jme3/util/BufferUtils.java b/jme3-core/src/main/java/com/jme3/util/BufferUtils.java index 72e50c8b0..628b2451d 100644 --- a/jme3-core/src/main/java/com/jme3/util/BufferUtils.java +++ b/jme3-core/src/main/java/com/jme3/util/BufferUtils.java @@ -1341,62 +1341,4 @@ public final class BufferUtils { } } - public static class ByteShortIntBufferReader { - Buffer buffer; - - public ByteShortIntBufferReader() { - } - - public ByteShortIntBufferReader(Buffer buffer) { - this.buffer = buffer; - } - - public int get() { - if (buffer instanceof ByteBuffer) { - return ((ByteBuffer) buffer).get(); - } else if (buffer instanceof ShortBuffer) { - return ((ShortBuffer) buffer).get(); - } else if (buffer instanceof IntBuffer) { - return ((IntBuffer) buffer).get(); - } else { - throw new UnsupportedOperationException("Buffer must be a ByteBuffer, a ShortBuffer or an IntBuffer"); - } - } - - public int get(int index) { - if (buffer instanceof ByteBuffer) { - return ((ByteBuffer) buffer).get(index); - } else if (buffer instanceof ShortBuffer) { - return ((ShortBuffer) buffer).get(index); - } else if (buffer instanceof IntBuffer) { - return ((IntBuffer) buffer).get(index); - } else { - throw new UnsupportedOperationException("Buffer must be a ByteBuffer, a ShortBuffer or an IntBuffer"); - } - } - - public int getUnsigned(int index) { - if (buffer instanceof ByteBuffer) { - return ((ByteBuffer) buffer).get(index) & 0xff; - } else if (buffer instanceof ShortBuffer) { - return ((ShortBuffer) buffer).get(index) & 0xffff; - } else if (buffer instanceof IntBuffer) { - return ((IntBuffer) buffer).get(index) & 0xffffff; - } else { - throw new UnsupportedOperationException("Buffer must be a ByteBuffer, a ShortBuffer or an IntBuffer"); - } - } - - public void setBuffer(Buffer buffer) { - this.buffer = buffer; - } - - public void rewind() { - buffer.rewind(); - } - - public int remaining() { - return buffer.remaining(); - } - } } From 21fbaf8f11faa1ccf00f60abc78d055a07a86281 Mon Sep 17 00:00:00 2001 From: Nehon Date: Sat, 9 Sep 2017 18:34:03 +0200 Subject: [PATCH 6/7] glTF: prevent direct loading of .bin files. --- .../java/com/jme3/scene/plugins/gltf/BinDataKey.java | 12 ++++++++++++ .../java/com/jme3/scene/plugins/gltf/BinLoader.java | 8 ++++++-- .../java/com/jme3/scene/plugins/gltf/GltfLoader.java | 3 ++- 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/BinDataKey.java diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/BinDataKey.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/BinDataKey.java new file mode 100644 index 000000000..c84678751 --- /dev/null +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/BinDataKey.java @@ -0,0 +1,12 @@ +package com.jme3.scene.plugins.gltf; + +import com.jme3.asset.AssetKey; + +/** + * Created by Nehon on 09/09/2017. + */ +class BinDataKey extends AssetKey { + public BinDataKey(String name) { + super(name); + } +} diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/BinLoader.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/BinLoader.java index b4b7fbf4d..17826d59c 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/BinLoader.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/BinLoader.java @@ -1,7 +1,6 @@ package com.jme3.scene.plugins.gltf; -import com.jme3.asset.AssetInfo; -import com.jme3.asset.AssetLoader; +import com.jme3.asset.*; import java.io.IOException; @@ -11,6 +10,11 @@ import java.io.IOException; public class BinLoader implements AssetLoader { @Override public Object load(AssetInfo assetInfo) throws IOException { + + if (!(assetInfo.getKey() instanceof BinDataKey)) { + throw new AssetLoadException(".bin files cannot be loaded directly, load the associated .gltf file"); + } + return assetInfo.openStream(); } } diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java index 25ce90977..6536bdf2f 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java @@ -499,7 +499,8 @@ public class GltfLoader implements AssetLoader { throw new AssetLoadException("Cannot load " + uri + ", a .bin extension is required."); } - InputStream input = (InputStream) info.getManager().loadAsset(info.getKey().getFolder() + uri); + BinDataKey key = new BinDataKey(info.getKey().getFolder() + uri); + InputStream input = (InputStream) info.getManager().loadAsset(key); data = new byte[bufferLength]; input.read(data); } From 9472c6dc8123361f148f3ed5d4eabb957ea0c3b9 Mon Sep 17 00:00:00 2001 From: Kirill Vainer Date: Sat, 9 Sep 2017 13:39:46 -0400 Subject: [PATCH 7/7] Try to fix Travis-CI buffer overflow on JDK7 (#721) --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index fc785f47f..c24f8941b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,9 @@ matrix: addons: ssh_known_hosts: github.com + hosts: + - travisci + hostname: travisci apt: packages: - gcc-multilib