Added support for attachment nodes.
JME now supports byte buffers for index buffer
This commit is contained in:
parent
d6c74dbf37
commit
1bdebd5505
@ -2592,6 +2592,7 @@ public final class GLRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (indexBuf.getFormat()) {
|
switch (indexBuf.getFormat()) {
|
||||||
|
case UnsignedByte:
|
||||||
case UnsignedShort:
|
case UnsignedShort:
|
||||||
// OK: Works on all platforms.
|
// OK: Works on all platforms.
|
||||||
break;
|
break;
|
||||||
|
@ -53,6 +53,8 @@ import com.jme3.util.IntMap.Entry;
|
|||||||
import com.jme3.util.SafeArrayList;
|
import com.jme3.util.SafeArrayList;
|
||||||
import com.jme3.util.clone.Cloner;
|
import com.jme3.util.clone.Cloner;
|
||||||
import com.jme3.util.clone.JmeCloneable;
|
import com.jme3.util.clone.JmeCloneable;
|
||||||
|
import com.sun.javaws.exceptions.InvalidArgumentException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.*;
|
import java.nio.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -402,11 +404,20 @@ public class Mesh implements Savable, Cloneable, JmeCloneable {
|
|||||||
// convert indices to ubytes on the heap
|
// convert indices to ubytes on the heap
|
||||||
VertexBuffer indices = getBuffer(Type.BoneIndex);
|
VertexBuffer indices = getBuffer(Type.BoneIndex);
|
||||||
if (!indices.getData().hasArray()) {
|
if (!indices.getData().hasArray()) {
|
||||||
|
if (indices.getFormat() == Format.UnsignedByte) {
|
||||||
ByteBuffer originalIndex = (ByteBuffer) indices.getData();
|
ByteBuffer originalIndex = (ByteBuffer) indices.getData();
|
||||||
ByteBuffer arrayIndex = ByteBuffer.allocate(originalIndex.capacity());
|
ByteBuffer arrayIndex = ByteBuffer.allocate(originalIndex.capacity());
|
||||||
originalIndex.clear();
|
originalIndex.clear();
|
||||||
arrayIndex.put(originalIndex);
|
arrayIndex.put(originalIndex);
|
||||||
indices.updateData(arrayIndex);
|
indices.updateData(arrayIndex);
|
||||||
|
} else {
|
||||||
|
//bone indices can be stored in an UnsignedShort buffer
|
||||||
|
ShortBuffer originalIndex = (ShortBuffer) indices.getData();
|
||||||
|
ShortBuffer arrayIndex = ShortBuffer.allocate(originalIndex.capacity());
|
||||||
|
originalIndex.clear();
|
||||||
|
arrayIndex.put(originalIndex);
|
||||||
|
indices.updateData(arrayIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
indices.setUsage(Usage.CpuOnly);
|
indices.setUsage(Usage.CpuOnly);
|
||||||
|
|
||||||
@ -1437,7 +1448,7 @@ public class Mesh implements Savable, Cloneable, JmeCloneable {
|
|||||||
return false; // no bone animation data
|
return false; // no bone animation data
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuffer boneIndexBuffer = (ByteBuffer) biBuf.getData();
|
BufferUtils.ByteShortIntBufferReader boneIndexBuffer = new BufferUtils.ByteShortIntBufferReader(biBuf.getData());
|
||||||
boneIndexBuffer.rewind();
|
boneIndexBuffer.rewind();
|
||||||
int numBoneIndices = boneIndexBuffer.remaining();
|
int numBoneIndices = boneIndexBuffer.remaining();
|
||||||
assert numBoneIndices % 4 == 0 : numBoneIndices;
|
assert numBoneIndices % 4 == 0 : numBoneIndices;
|
||||||
@ -1450,10 +1461,10 @@ public class Mesh implements Savable, Cloneable, JmeCloneable {
|
|||||||
/*
|
/*
|
||||||
* Test each vertex to determine whether the bone affects it.
|
* Test each vertex to determine whether the bone affects it.
|
||||||
*/
|
*/
|
||||||
byte biByte = (byte) boneIndex; // bone indices wrap after 127
|
int biByte = boneIndex;
|
||||||
for (int vIndex = 0; vIndex < numVertices; vIndex++) {
|
for (int vIndex = 0; vIndex < numVertices; vIndex++) {
|
||||||
for (int wIndex = 0; wIndex < 4; wIndex++) {
|
for (int wIndex = 0; wIndex < 4; wIndex++) {
|
||||||
byte bIndex = boneIndexBuffer.get();
|
int bIndex = boneIndexBuffer.get();
|
||||||
float weight = weightBuffer.get();
|
float weight = weightBuffer.get();
|
||||||
if (wIndex < maxNumWeights && bIndex == biByte && weight != 0f) {
|
if (wIndex < maxNumWeights && bIndex == biByte && weight != 0f) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -1340,4 +1340,44 @@ public final class BufferUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ByteShortIntBufferReader {
|
||||||
|
Buffer buffer;
|
||||||
|
|
||||||
|
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 void rewind() {
|
||||||
|
buffer.rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int remaining() {
|
||||||
|
return buffer.remaining();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -894,7 +894,6 @@ public class GltfLoader implements AssetLoader {
|
|||||||
int boneIndex = joints.get(i).getAsInt();
|
int boneIndex = joints.get(i).getAsInt();
|
||||||
//we don't need the inverse bind matrix, we need the bind matrix so let's invert it.
|
//we don't need the inverse bind matrix, we need the bind matrix so let's invert it.
|
||||||
Matrix4f modelBindMatrix = inverseBindMatrices[i].invertLocal();
|
Matrix4f modelBindMatrix = inverseBindMatrices[i].invertLocal();
|
||||||
//TODO actually a regular node or a geometry can be attached to a bone, we have to handle this and attach it to the AttachementNode.
|
|
||||||
bones[i] = readNodeAsBone(boneIndex, i, index, modelBindMatrix);
|
bones[i] = readNodeAsBone(boneIndex, i, index, modelBindMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -990,10 +989,11 @@ public class GltfLoader implements AssetLoader {
|
|||||||
return bone;
|
return bone;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findChildren(int nodeIndex) {
|
private void findChildren(int nodeIndex) throws IOException {
|
||||||
BoneWrapper bw = fetchFromCache("nodes", nodeIndex, BoneWrapper.class);
|
BoneWrapper bw = fetchFromCache("nodes", nodeIndex, BoneWrapper.class);
|
||||||
JsonObject nodeData = nodes.get(nodeIndex).getAsJsonObject();
|
JsonObject nodeData = nodes.get(nodeIndex).getAsJsonObject();
|
||||||
JsonArray children = nodeData.getAsJsonArray("children");
|
JsonArray children = nodeData.getAsJsonArray("children");
|
||||||
|
|
||||||
if (children != null) {
|
if (children != null) {
|
||||||
for (JsonElement child : children) {
|
for (JsonElement child : children) {
|
||||||
int childIndex = child.getAsInt();
|
int childIndex = child.getAsInt();
|
||||||
@ -1001,15 +1001,29 @@ public class GltfLoader implements AssetLoader {
|
|||||||
if (cbw != null) {
|
if (cbw != null) {
|
||||||
bw.bone.addChild(cbw.bone);
|
bw.bone.addChild(cbw.bone);
|
||||||
bw.children.add(childIndex);
|
bw.children.add(childIndex);
|
||||||
|
} else {
|
||||||
|
JsonObject childNode = nodes.get(childIndex).getAsJsonObject();
|
||||||
|
//The child might be a Geom
|
||||||
|
if (getAsInteger(childNode, "mesh") != null) {
|
||||||
|
//this is a geometry, let's load it as a spatial
|
||||||
|
Spatial s = (Spatial) readNode(childIndex);
|
||||||
|
bw.attachedSpatial = s;
|
||||||
|
// addToCache("nodes", nodeIndex, s, nodes.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupControls() {
|
private void setupControls() {
|
||||||
for (SkinData skinData : skinnedSpatials.keySet()) {
|
for (SkinData skinData : skinnedSpatials.keySet()) {
|
||||||
List<Spatial> spatials = skinnedSpatials.get(skinData);
|
List<Spatial> spatials = skinnedSpatials.get(skinData);
|
||||||
Spatial spatial;
|
Spatial spatial;
|
||||||
|
if (spatials.isEmpty()) {
|
||||||
|
//can happen when a file contains a skin that is not used by any mesh...
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (spatials.size() >= 1) {
|
if (spatials.size() >= 1) {
|
||||||
spatial = findCommonAncestor(spatials);
|
spatial = findCommonAncestor(spatials);
|
||||||
} else {
|
} else {
|
||||||
@ -1028,9 +1042,17 @@ public class GltfLoader implements AssetLoader {
|
|||||||
|
|
||||||
if (skinData.animControl != null) {
|
if (skinData.animControl != null) {
|
||||||
spatial.addControl(skinData.animControl);
|
spatial.addControl(skinData.animControl);
|
||||||
|
}
|
||||||
spatial.addControl(skinData.skeletonControl);
|
spatial.addControl(skinData.skeletonControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < nodes.size(); i++) {
|
||||||
|
BoneWrapper bw = fetchFromCache("nodes", i, BoneWrapper.class);
|
||||||
|
if (bw == null || bw.attachedSpatial == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
SkinData skinData = fetchFromCache("skins", bw.skinIndex, SkinData.class);
|
||||||
|
skinData.skeletonControl.getAttachmentsNode(bw.bone.getName()).attachChild(bw.attachedSpatial);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1044,7 +1066,13 @@ public class GltfLoader implements AssetLoader {
|
|||||||
if (data == null) {
|
if (data == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return type.cast(data[index]);
|
try {
|
||||||
|
T ret = type.cast(data[index]);
|
||||||
|
return ret;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToCache(String name, int index, Object object, int maxLength) {
|
public void addToCache(String name, int index, Object object, int maxLength) {
|
||||||
@ -1128,6 +1156,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
Transform localTransform;
|
Transform localTransform;
|
||||||
Matrix4f modelBindMatrix;
|
Matrix4f modelBindMatrix;
|
||||||
boolean isRoot = false;
|
boolean isRoot = false;
|
||||||
|
Spatial attachedSpatial;
|
||||||
List<Integer> children = new ArrayList<>();
|
List<Integer> children = new ArrayList<>();
|
||||||
|
|
||||||
public BoneWrapper(Bone bone, int boneIndex, int skinIndex, Matrix4f modelBindMatrix, Transform localTransform) {
|
public BoneWrapper(Bone bone, int boneIndex, int skinIndex, Matrix4f modelBindMatrix, Transform localTransform) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user