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 b1f3d02df5..a6d168f868 100644
--- a/jme3-core/src/main/java/com/jme3/animation/SkeletonControl.java
+++ b/jme3-core/src/main/java/com/jme3/animation/SkeletonControl.java
@@ -124,7 +124,7 @@ private void switchToHardware() {
}
for (Mesh mesh : targets) {
if (mesh.isAnimated()) {
- mesh.prepareForAnim(false);
+ mesh.prepareForAnimHardware();
}
}
}
@@ -137,7 +137,7 @@ private void switchToSoftware() {
}
for (Mesh mesh : targets) {
if (mesh.isAnimated()) {
- mesh.prepareForAnim(true);
+ mesh.prepareForAnimSoftware();
}
}
}
@@ -312,7 +312,7 @@ void resetToBind() {
Buffer bwBuff = mesh.getBuffer(Type.BoneWeight).getData();
Buffer biBuff = mesh.getBuffer(Type.BoneIndex).getData();
if (!biBuff.hasArray() || !bwBuff.hasArray()) {
- mesh.prepareForAnim(true); // prepare for software animation
+ mesh.prepareForAnimSoftware(); // prepare for software animation
}
VertexBuffer bindPos = mesh.getBuffer(Type.BindPosePosition);
VertexBuffer bindNorm = mesh.getBuffer(Type.BindPoseNormal);
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 a0f8e1fe6e..01677a6a44 100644
--- a/jme3-core/src/main/java/com/jme3/scene/Mesh.java
+++ b/jme3-core/src/main/java/com/jme3/scene/Mesh.java
@@ -354,91 +354,93 @@ public void generateBindPose(boolean forSoftwareAnim){
/**
* Prepares the mesh for software skinning by converting the bone index
- * and weight buffers to heap buffers.
- *
- * @param forSoftwareAnim Should be true to enable the conversion.
+ * and weight buffers to heap buffers.
*/
- public void prepareForAnim(boolean forSoftwareAnim){
- if (forSoftwareAnim) {
- // convert indices to ubytes on the heap
- VertexBuffer indices = getBuffer(Type.BoneIndex);
- if (!indices.getData().hasArray()) {
- ByteBuffer originalIndex = (ByteBuffer) indices.getData();
- ByteBuffer arrayIndex = ByteBuffer.allocate(originalIndex.capacity());
- originalIndex.clear();
- arrayIndex.put(originalIndex);
- indices.updateData(arrayIndex);
- }
- indices.setUsage(Usage.CpuOnly);
-
- // convert weights on the heap
- VertexBuffer weights = getBuffer(Type.BoneWeight);
- if (!weights.getData().hasArray()) {
- FloatBuffer originalWeight = (FloatBuffer) weights.getData();
- FloatBuffer arrayWeight = FloatBuffer.allocate(originalWeight.capacity());
- originalWeight.clear();
- arrayWeight.put(originalWeight);
- weights.updateData(arrayWeight);
- }
- weights.setUsage(Usage.CpuOnly);
- // position, normal, and tanget buffers to be in "Stream" mode
- VertexBuffer positions = getBuffer(Type.Position);
- VertexBuffer normals = getBuffer(Type.Normal);
- VertexBuffer tangents = getBuffer(Type.Tangent);
- positions.setUsage(Usage.Stream);
- if (normals != null) {
- normals.setUsage(Usage.Stream);
- }
- if (tangents != null) {
- tangents.setUsage(Usage.Stream);
- }
- } else {
- //if HWBoneIndex and HWBoneWeight are empty, we setup them as direct
- //buffers with software anim buffers data
- VertexBuffer indicesHW = getBuffer(Type.HWBoneIndex);
- if (indicesHW.getData() == null) {
- VertexBuffer indices = getBuffer(Type.BoneIndex);
- ByteBuffer originalIndex = (ByteBuffer) indices.getData();
- ByteBuffer directIndex = BufferUtils.createByteBuffer(originalIndex.capacity());
- originalIndex.clear();
- directIndex.put(originalIndex);
- indicesHW.setupData(Usage.Static, indices.getNumComponents(), indices.getFormat(), directIndex);
- }
-
- VertexBuffer weightsHW = getBuffer(Type.HWBoneWeight);
- if (weightsHW.getData() == null) {
- VertexBuffer weights = getBuffer(Type.BoneWeight);
- FloatBuffer originalWeight = (FloatBuffer) weights.getData();
- FloatBuffer directWeight = BufferUtils.createFloatBuffer(originalWeight.capacity());
- originalWeight.clear();
- directWeight.put(originalWeight);
- weightsHW.setupData(Usage.Static, weights.getNumComponents(), weights.getFormat(), directWeight);
- }
-
- // position, normal, and tanget buffers to be in "Static" mode
- VertexBuffer positions = getBuffer(Type.Position);
- VertexBuffer normals = getBuffer(Type.Normal);
- VertexBuffer tangents = getBuffer(Type.Tangent);
-
- VertexBuffer positionsBP = getBuffer(Type.BindPosePosition);
- VertexBuffer normalsBP = getBuffer(Type.BindPoseNormal);
- VertexBuffer tangentsBP = getBuffer(Type.BindPoseTangent);
-
- positions.setUsage(Usage.Static);
- positionsBP.copyElements(0, positions, 0, positionsBP.getNumElements());
- positions.setUpdateNeeded();
-
- if (normals != null) {
- normals.setUsage(Usage.Static);
- normalsBP.copyElements(0, normals, 0, normalsBP.getNumElements());
- normals.setUpdateNeeded();
- }
-
- if (tangents != null) {
- tangents.setUsage(Usage.Static);
- tangentsBP.copyElements(0, tangents, 0, tangentsBP.getNumElements());
- tangents.setUpdateNeeded();
- }
+ public void prepareForAnimSoftware(){
+ // convert indices to ubytes on the heap
+ VertexBuffer indices = getBuffer(Type.BoneIndex);
+ if (!indices.getData().hasArray()) {
+ ByteBuffer originalIndex = (ByteBuffer) indices.getData();
+ ByteBuffer arrayIndex = ByteBuffer.allocate(originalIndex.capacity());
+ originalIndex.clear();
+ arrayIndex.put(originalIndex);
+ indices.updateData(arrayIndex);
+ }
+ indices.setUsage(Usage.CpuOnly);
+
+ // convert weights on the heap
+ VertexBuffer weights = getBuffer(Type.BoneWeight);
+ if (!weights.getData().hasArray()) {
+ FloatBuffer originalWeight = (FloatBuffer) weights.getData();
+ FloatBuffer arrayWeight = FloatBuffer.allocate(originalWeight.capacity());
+ originalWeight.clear();
+ arrayWeight.put(originalWeight);
+ weights.updateData(arrayWeight);
+ }
+ weights.setUsage(Usage.CpuOnly);
+ // position, normal, and tanget buffers to be in "Stream" mode
+ VertexBuffer positions = getBuffer(Type.Position);
+ VertexBuffer normals = getBuffer(Type.Normal);
+ VertexBuffer tangents = getBuffer(Type.Tangent);
+ positions.setUsage(Usage.Stream);
+ if (normals != null) {
+ normals.setUsage(Usage.Stream);
+ }
+ if (tangents != null) {
+ tangents.setUsage(Usage.Stream);
+ }
+ }
+
+ /**
+ * Prepares the mesh for hardware skinning by converting the bone index
+ * and weight buffers to heap buffers.
+ */
+ public void prepareForAnimHardware(){
+ //if HWBoneIndex and HWBoneWeight are empty, we setup them as direct
+ //buffers with software anim buffers data
+ VertexBuffer indicesHW = getBuffer(Type.HWBoneIndex);
+ if (indicesHW.getData() == null) {
+ VertexBuffer indices = getBuffer(Type.BoneIndex);
+ ByteBuffer originalIndex = (ByteBuffer) indices.getData();
+ ByteBuffer directIndex = BufferUtils.createByteBuffer(originalIndex.capacity());
+ originalIndex.clear();
+ directIndex.put(originalIndex);
+ indicesHW.setupData(Usage.Static, indices.getNumComponents(), indices.getFormat(), directIndex);
+ }
+
+ VertexBuffer weightsHW = getBuffer(Type.HWBoneWeight);
+ if (weightsHW.getData() == null) {
+ VertexBuffer weights = getBuffer(Type.BoneWeight);
+ FloatBuffer originalWeight = (FloatBuffer) weights.getData();
+ FloatBuffer directWeight = BufferUtils.createFloatBuffer(originalWeight.capacity());
+ originalWeight.clear();
+ directWeight.put(originalWeight);
+ weightsHW.setupData(Usage.Static, weights.getNumComponents(), weights.getFormat(), directWeight);
+ }
+
+ // position, normal, and tanget buffers to be in "Static" mode
+ VertexBuffer positions = getBuffer(Type.Position);
+ VertexBuffer normals = getBuffer(Type.Normal);
+ VertexBuffer tangents = getBuffer(Type.Tangent);
+
+ VertexBuffer positionsBP = getBuffer(Type.BindPosePosition);
+ VertexBuffer normalsBP = getBuffer(Type.BindPoseNormal);
+ VertexBuffer tangentsBP = getBuffer(Type.BindPoseTangent);
+
+ positions.setUsage(Usage.Static);
+ positionsBP.copyElements(0, positions, 0, positionsBP.getNumElements());
+ positions.setUpdateNeeded();
+
+ if (normals != null) {
+ normals.setUsage(Usage.Static);
+ normalsBP.copyElements(0, normals, 0, normalsBP.getNumElements());
+ normals.setUpdateNeeded();
+ }
+
+ if (tangents != null) {
+ tangents.setUsage(Usage.Static);
+ tangentsBP.copyElements(0, tangents, 0, tangentsBP.getNumElements());
+ tangents.setUpdateNeeded();
}
}
@@ -632,92 +634,6 @@ public void setStreamed(){
}
}
- /**
- * Interleaves the data in this mesh. This operation cannot be reversed.
- * Some GPUs may prefer the data in this format, however it is a good idea
- * to avoid using this method as it disables some engine features.
- */
- @Deprecated
- public void setInterleaved(){
- ArrayList vbs = new ArrayList();
- vbs.addAll(buffersList);
-
-// ArrayList vbs = new ArrayList(buffers.values());
- // index buffer not included when interleaving
- vbs.remove(getBuffer(Type.Index));
-
- int stride = 0; // aka bytes per vertex
- for (int i = 0; i < vbs.size(); i++){
- VertexBuffer vb = vbs.get(i);
-// if (vb.getFormat() != Format.Float){
-// throw new UnsupportedOperationException("Cannot interleave vertex buffer.\n" +
-// "Contains not-float data.");
-// }
- stride += vb.componentsLength;
- vb.getData().clear(); // reset position & limit (used later)
- }
-
- VertexBuffer allData = new VertexBuffer(Type.InterleavedData);
- ByteBuffer dataBuf = BufferUtils.createByteBuffer(stride * getVertexCount());
- allData.setupData(Usage.Static, 1, Format.UnsignedByte, dataBuf);
-
- // adding buffer directly so that no update counts is forced
- buffers.put(Type.InterleavedData.ordinal(), allData);
- buffersList.add(allData);
-
- for (int vert = 0; vert < getVertexCount(); vert++){
- for (int i = 0; i < vbs.size(); i++){
- VertexBuffer vb = vbs.get(i);
- switch (vb.getFormat()){
- case Float:
- FloatBuffer fb = (FloatBuffer) vb.getData();
- for (int comp = 0; comp < vb.components; comp++){
- dataBuf.putFloat(fb.get());
- }
- break;
- case Byte:
- case UnsignedByte:
- ByteBuffer bb = (ByteBuffer) vb.getData();
- for (int comp = 0; comp < vb.components; comp++){
- dataBuf.put(bb.get());
- }
- break;
- case Half:
- case Short:
- case UnsignedShort:
- ShortBuffer sb = (ShortBuffer) vb.getData();
- for (int comp = 0; comp < vb.components; comp++){
- dataBuf.putShort(sb.get());
- }
- break;
- case Int:
- case UnsignedInt:
- IntBuffer ib = (IntBuffer) vb.getData();
- for (int comp = 0; comp < vb.components; comp++){
- dataBuf.putInt(ib.get());
- }
- break;
- case Double:
- DoubleBuffer db = (DoubleBuffer) vb.getData();
- for (int comp = 0; comp < vb.components; comp++){
- dataBuf.putDouble(db.get());
- }
- break;
- }
- }
- }
-
- int offset = 0;
- for (VertexBuffer vb : vbs){
- vb.setOffset(offset);
- vb.setStride(stride);
-
- vb.updateData(null);
- //vb.setupData(vb.usage, vb.components, vb.format, null);
- offset += vb.componentsLength;
- }
- }
-
private int computeNumElements(int bufSize){
switch (mode){
case Triangles:
@@ -757,9 +673,6 @@ private int computeInstanceCount() {
* based on the current data. This method should be called
* after the {@link Buffer#capacity() capacities} of the mesh's
* {@link VertexBuffer vertex buffers} has been altered.
- *
- * @throws IllegalStateException If this mesh is in
- * {@link #setInterleaved() interleaved} format.
*/
public void updateCounts(){
if (getBuffer(Type.InterleavedData) != null)
@@ -1188,29 +1101,7 @@ public void extractVertexData(Mesh other) {
throw new AssertionError();
}
- // Create the new index buffer.
- // Do not overwrite the old one because we might be able to
- // convert from int index buffer to short index buffer
- IndexBuffer newIndexBuf;
- if (newNumVerts >= 65536) {
- newIndexBuf = new IndexIntBuffer(BufferUtils.createIntBuffer(numIndices));
- } else {
- newIndexBuf = new IndexShortBuffer(BufferUtils.createShortBuffer(numIndices));
- }
-
- for (int i = 0; i < numIndices; i++) {
- // Map the old indices to the new indices
- int oldIndex = indexBuf.get(i);
- newIndex = oldIndicesToNewIndices.get(oldIndex);
-
- newIndexBuf.put(i, newIndex);
- }
-
- VertexBuffer newIdxBuf = new VertexBuffer(Type.Index);
- newIdxBuf.setupData(oldIdxBuf.getUsage(),
- oldIdxBuf.getNumComponents(),
- newIndexBuf instanceof IndexIntBuffer ? Format.UnsignedInt : Format.UnsignedShort,
- newIndexBuf.getBuffer());
+ VertexBuffer newIdxBuf = createIndexBuffer(oldIdxBuf, indexBuf, newIndicesToOldIndices);
clearBuffer(Type.Index);
setBuffer(newIdxBuf);
@@ -1222,26 +1113,7 @@ public void extractVertexData(Mesh other) {
continue;
}
- VertexBuffer newVb = new VertexBuffer(oldVb.getBufferType());
- newVb.setNormalized(oldVb.isNormalized());
- //check for data before copying, some buffers are just empty shells
- //for caching purpose (HW skinning buffers), and will be filled when
- //needed
- if(oldVb.getData()!=null){
- // Create a new vertex buffer with similar configuration, but
- // with the capacity of number of unique vertices
- Buffer buffer = VertexBuffer.createBuffer(oldVb.getFormat(), oldVb.getNumComponents(), newNumVerts);
- newVb.setupData(oldVb.getUsage(), oldVb.getNumComponents(), oldVb.getFormat(), buffer);
-
- // Copy the vertex data from the old buffer into the new buffer
- for (int i = 0; i < newNumVerts; i++) {
- int oldIndex = newIndicesToOldIndices.get(i);
-
- // Copy the vertex attribute from the old index
- // to the new index
- oldVb.copyElement(oldIndex, newVb, i);
- }
- }
+ VertexBuffer newVb = createVertexBuffer(oldVb,newIndicesToOldIndices);
// Set the buffer on the mesh
clearBuffer(newVb.getBufferType());
@@ -1255,6 +1127,62 @@ public void extractVertexData(Mesh other) {
updateCounts();
updateBound();
}
+
+ public VertexBuffer createIndexBuffer(VertexBuffer vertexBuf, IndexBuffer indexBuf, ArrayList indices){
+ // Create the new index buffer.
+ // Do not overwrite the old one because we might be able to
+ // convert from int index buffer to short index buffer
+
+ int numIndices = indexBuf.size();
+ int numIndex = indices.size();
+
+ IndexBuffer newIndexBuf;
+ if (numIndex >= 65536) {
+ newIndexBuf = new IndexIntBuffer(BufferUtils.createIntBuffer(numIndices));
+ } else {
+ newIndexBuf = new IndexShortBuffer(BufferUtils.createShortBuffer(numIndices));
+ }
+
+ for (int i = 0; i < numIndices; i++) {
+ // Map the old indices to the new indices
+ int oldIndex = indexBuf.get(i);
+ numIndex = indices.get(oldIndex);
+
+ newIndexBuf.put(i, numIndex);
+ }
+
+ VertexBuffer newIdxBuf = new VertexBuffer(Type.Index);
+ newIdxBuf.setupData(vertexBuf.getUsage(),
+ vertexBuf.getNumComponents(),
+ newIndexBuf instanceof IndexIntBuffer ? Format.UnsignedInt : Format.UnsignedShort,
+ newIndexBuf.getBuffer());
+
+ return newIdxBuf;
+ }
+
+ public VertexBuffer createVertexBuffer(VertexBuffer oldVb, ArrayList indices) {
+ VertexBuffer newVb = new VertexBuffer(oldVb.getBufferType());
+ newVb.setNormalized(oldVb.isNormalized());
+ //check for data before copying, some buffers are just empty shells
+ //for caching purpose (HW skinning buffers), and will be filled when
+ //needed
+ if(oldVb.getData()!=null){
+ // Create a new vertex buffer with similar configuration, but
+ // with the capacity of number of unique vertices
+ Buffer buffer = VertexBuffer.createBuffer(oldVb.getFormat(), oldVb.getNumComponents(), indices.size());
+ newVb.setupData(oldVb.getUsage(), oldVb.getNumComponents(), oldVb.getFormat(), buffer);
+
+ // Copy the vertex data from the old buffer into the new buffer
+ for (int i = 0; i < indices.size(); i++) {
+ int oldIndex = indices.get(i);
+
+ // Copy the vertex attribute from the old index
+ // to the new index
+ oldVb.copyElement(oldIndex, newVb, i);
+ }
+ }
+ return newVb;
+ }
/**
* Scales the texture coordinate buffer on this mesh by the given
diff --git a/jme3-core/src/test/java/com/jme3/scene/MeshTest.java b/jme3-core/src/test/java/com/jme3/scene/MeshTest.java
new file mode 100644
index 0000000000..6c41d40fba
--- /dev/null
+++ b/jme3-core/src/test/java/com/jme3/scene/MeshTest.java
@@ -0,0 +1,44 @@
+package com.jme3.scene;
+
+import com.jme3.scene.shape.Box;
+import org.junit.Test;
+
+/**
+ * Created by arkkadhiratara on 3/22/16.
+ */
+public class MeshTest {
+ @Test
+ public void extractVertexDataTest() {
+ Box m = new Box(10,10,10);
+ Box m2 = new Box(20,20,20);
+
+ // Extract Vertex Data m into m2
+ m2.extractVertexData(m);
+
+ // Check does the new extracted m2 have the same value with m1.
+
+ // Have the same mode
+ assert m.getMode() == m2.getMode();
+
+ // Have the same Instance Count
+ assert m.getInstanceCount() == m2.getInstanceCount();
+
+ // Have the same point size
+ assert m.getPointSize() == m2.getPointSize();
+
+ // Have the same buffer in general
+ assert m.getBufferList().size() == m2.getBufferList().size();
+ assert m.getIndexBuffer().size() == m2.getIndexBuffer().size();
+ assert m.getBuffer(VertexBuffer.Type.Index).getUniqueId() == m2.getBuffer(VertexBuffer.Type.Index).getUniqueId();
+ assert m.getBuffer(VertexBuffer.Type.Index).getNumElements() == m2.getBuffer(VertexBuffer.Type.Index).getNumElements();
+
+ assert m.getBuffer(VertexBuffer.Type.Position).getUniqueId() == m2.getBuffer(VertexBuffer.Type.Position).getUniqueId();
+ assert m.getBuffer(VertexBuffer.Type.Position).getNumElements() == m2.getBuffer(VertexBuffer.Type.Position).getNumElements();
+
+ assert m.getBuffer(VertexBuffer.Type.Normal).getUniqueId() == m2.getBuffer(VertexBuffer.Type.Normal).getUniqueId();
+ assert m.getBuffer(VertexBuffer.Type.Normal).getNumElements() == m2.getBuffer(VertexBuffer.Type.Normal).getNumElements();
+
+ assert m.getBuffer(VertexBuffer.Type.TexCoord).getUniqueId() == m2.getBuffer(VertexBuffer.Type.TexCoord).getUniqueId();
+ assert m.getBuffer(VertexBuffer.Type.TexCoord).getNumElements() == m2.getBuffer(VertexBuffer.Type.TexCoord).getNumElements();
+ }
+}