修訂 | ac64e0b6f749220f046fc958de56c9c2fedb80cf (tree) |
---|---|
時間 | 2012-06-13 07:34:56 |
作者 | Kazuhiko Kobayashi <chototsu_ <moushinp@yaho...> |
Commiter | Kazuhiko Kobayashi <chototsu_ |
Some improvement of bone matrix calculation.
@@ -38,7 +38,9 @@ | ||
38 | 38 | import com.jme3.scene.Geometry; |
39 | 39 | import com.jme3.scene.Mesh; |
40 | 40 | import com.jme3.scene.VertexBuffer.Type; |
41 | +import com.jme3.util.BufferUtils; | |
41 | 42 | import java.io.IOException; |
43 | +import java.nio.FloatBuffer; | |
42 | 44 | import projectkyoto.mmd.file.PMDMaterial; |
43 | 45 | |
44 | 46 | /** |
@@ -112,6 +114,10 @@ | ||
112 | 114 | newMesh.bound = oldMesh.bound.clone(); |
113 | 115 | newMesh.setBuffer(oldMesh.getBuffer(Type.Index)); |
114 | 116 | newPMDGeometry.setMesh(newMesh); |
117 | + | |
118 | + newMesh.setBoneIndexBuffer(oldMesh.getBoneIndexBuffer()); | |
119 | + FloatBuffer fb = BufferUtils.createFloatBuffer(oldMesh.getBoneMatrixBuffer().capacity()); | |
120 | + newMesh.setBoneMatrixBuffer(fb); | |
115 | 121 | } else { |
116 | 122 | PMDMesh oldMesh = (PMDMesh)mesh; |
117 | 123 | PMDMesh newMesh = new PMDMesh(); |
@@ -135,6 +141,10 @@ | ||
135 | 141 | if (oldMesh.getBuffer(Type.InterleavedData) != null) |
136 | 142 | newMesh.setBuffer(oldMesh.getBuffer(Type.InterleavedData)); |
137 | 143 | newPMDGeometry.setMesh(newMesh); |
144 | + | |
145 | + newMesh.setBoneIndexBuffer(oldMesh.getBoneIndexBuffer()); | |
146 | + FloatBuffer fb = BufferUtils.createFloatBuffer(oldMesh.getBoneMatrixBuffer().capacity()); | |
147 | + newMesh.setBoneMatrixBuffer(fb); | |
138 | 148 | // newMesh.setInterleaved(); |
139 | 149 | } |
140 | 150 | newPMDGeometry.glslSkinningMaterial = glslSkinningMaterial.clone(); |
@@ -312,11 +312,18 @@ | ||
312 | 312 | ib.setupData(VertexBuffer.Usage.Static, 1, VertexBuffer.Format.UnsignedShort, isb); |
313 | 313 | mesh.setBuffer(ib); |
314 | 314 | mesh.setBoneIndexArray(skinIndexArray); |
315 | + ShortBuffer boneIndexBuffer = BufferUtils.createShortBuffer(skinIndexArray.length); | |
316 | + for(int i=0;i<skinIndexArray.length;i++) { | |
317 | + boneIndexBuffer.put((short)skinIndexArray[i]); | |
318 | + } | |
319 | + mesh.setBoneIndexBuffer(boneIndexBuffer); | |
315 | 320 | mesh.setBoneMatrixArray(new Matrix4f[skinIndexArray.length]); |
316 | 321 | for (int i = 0; i < mesh.getBoneMatrixArray().length; i++) { |
317 | 322 | mesh.getBoneMatrixArray()[i] = new Matrix4f(); |
318 | 323 | mesh.getBoneMatrixArray()[i].loadIdentity(); |
319 | 324 | } |
325 | + FloatBuffer boneMatrixBuffer = BufferUtils.createFloatBuffer(skinIndexArray.length * 16); | |
326 | + mesh.setBoneMatrixBuffer(boneMatrixBuffer); | |
320 | 327 | return mesh; |
321 | 328 | } |
322 | 329 |
@@ -413,19 +420,26 @@ | ||
413 | 420 | mesh.setBuffer(ib); |
414 | 421 | mesh.setBuffer(bib); |
415 | 422 | int[] indexArray = new int[md.getBoneList().size()]; |
423 | + ShortBuffer indexBuffer = BufferUtils.createShortBuffer(md.getBoneList().size()); | |
416 | 424 | for (int i = 0; i < indexArray.length; i++) { |
417 | 425 | if (i < md.getBoneList().size()) { |
418 | 426 | indexArray[i] = md.getBoneList().get(i).shortValue(); |
419 | 427 | } else { |
420 | 428 | indexArray[i] = 0; |
421 | 429 | } |
430 | + indexBuffer.put((short)indexArray[i]); | |
422 | 431 | } |
423 | 432 | mesh.setBoneIndexArray(indexArray); |
433 | + mesh.setBoneIndexBuffer(indexBuffer); | |
434 | + FloatBuffer boneMatrixBuffer = BufferUtils.createFloatBuffer(16 * indexArray.length); | |
424 | 435 | mesh.setBoneMatrixArray(new Matrix4f[indexArray.length]); |
436 | + mesh.setBoneMatrixBuffer(boneMatrixBuffer); | |
425 | 437 | for (int i = 0; i < mesh.getBoneMatrixArray().length; i++) { |
426 | 438 | mesh.getBoneMatrixArray()[i] = new Matrix4f(); |
427 | 439 | mesh.getBoneMatrixArray()[i].loadIdentity(); |
440 | + mesh.getBoneMatrixArray()[i].fillFloatBuffer(boneMatrixBuffer, true); | |
428 | 441 | } |
442 | + boneMatrixBuffer.position(0); | |
429 | 443 | return mesh; |
430 | 444 | } |
431 | 445 |
@@ -42,6 +42,7 @@ | ||
42 | 42 | import com.jme3.util.BufferUtils; |
43 | 43 | import java.io.IOException; |
44 | 44 | import java.nio.FloatBuffer; |
45 | +import java.nio.ShortBuffer; | |
45 | 46 | |
46 | 47 | /** |
47 | 48 | * |
@@ -53,6 +54,8 @@ | ||
53 | 54 | Matrix4f boneMatrixArray[]; |
54 | 55 | VertexBuffer vbBackup; |
55 | 56 | VertexBuffer nbBackup; |
57 | + ShortBuffer boneIndexBuffer; | |
58 | + FloatBuffer boneMatrixBuffer; | |
56 | 59 | |
57 | 60 | int boneMatricesParamIndex = -1; |
58 | 61 |
@@ -178,5 +181,21 @@ | ||
178 | 181 | OutputCapsule c = ex.getCapsule(this); |
179 | 182 | c.write(boneIndexArray, "boneIndexArray", null); |
180 | 183 | } |
184 | + | |
185 | + public ShortBuffer getBoneIndexBuffer() { | |
186 | + return boneIndexBuffer; | |
187 | + } | |
188 | + | |
189 | + public void setBoneIndexBuffer(ShortBuffer boneIndexBuffer) { | |
190 | + this.boneIndexBuffer = boneIndexBuffer; | |
191 | + } | |
192 | + | |
193 | + public FloatBuffer getBoneMatrixBuffer() { | |
194 | + return boneMatrixBuffer; | |
195 | + } | |
196 | + | |
197 | + public void setBoneMatrixBuffer(FloatBuffer boneMatrixBuffer) { | |
198 | + this.boneMatrixBuffer = boneMatrixBuffer; | |
199 | + } | |
181 | 200 | |
182 | 201 | } |
@@ -58,6 +58,7 @@ | ||
58 | 58 | import com.jme3.scene.debug.SkeletonWire; |
59 | 59 | import com.jme3.scene.shape.Box; |
60 | 60 | import com.jme3.shader.VarType; |
61 | +import com.jme3.util.BufferUtils; | |
61 | 62 | import java.nio.ShortBuffer; |
62 | 63 | import java.util.Arrays; |
63 | 64 | import java.util.HashMap; |
@@ -95,6 +96,7 @@ | ||
95 | 96 | // int skinBoneArray[]; |
96 | 97 | AssetManager assetManager; |
97 | 98 | Matrix4f[] offsetMatrices; |
99 | + FloatBuffer offsetMatrixbuffer; | |
98 | 100 | boolean updateNeeded = true; |
99 | 101 | boolean skinUpdateNeeded = true; |
100 | 102 | boolean wireFrame = false; |
@@ -270,6 +272,13 @@ | ||
270 | 272 | |
271 | 273 | public Matrix4f[] calcOffsetMatrices() { |
272 | 274 | offsetMatrices = skeleton.computeSkinningMatrices(); |
275 | + if (offsetMatrixbuffer == null) { | |
276 | + offsetMatrixbuffer = BufferUtils.createFloatBuffer(offsetMatrices.length * 16); | |
277 | + } | |
278 | + offsetMatrixbuffer.position(0); | |
279 | + for(Matrix4f m : offsetMatrices) { | |
280 | + m.fillFloatBuffer(offsetMatrixbuffer, true); | |
281 | + } | |
273 | 282 | return offsetMatrices; |
274 | 283 | } |
275 | 284 | boolean setBoneMatricesFlag = true; |
@@ -289,18 +298,35 @@ | ||
289 | 298 | PMDMesh pmdMesh = (PMDMesh)g.getMesh(); |
290 | 299 | int boneIndexArray[] = pmdMesh.getBoneIndexArray(); |
291 | 300 | Matrix4f[] boneMatrixArray = pmdMesh.getBoneMatrixArray(); |
292 | - for (int i = pmdMesh.getBoneIndexArray().length-1; i >=0; i--) { | |
293 | - boneMatrixArray[i] = (offsetMatrices[boneIndexArray[i]]); | |
294 | - } | |
301 | +// for (int i = pmdMesh.getBoneIndexArray().length-1; i >=0; i--) { | |
302 | +// boneMatrixArray[i] = (offsetMatrices[boneIndexArray[i]]); | |
303 | +// } | |
304 | + | |
295 | 305 | if (glslSkinning) { |
306 | +// if (pmdMesh.boneMatricesParamIndex < 0) { | |
307 | +// m.setParam("BoneMatrices", VarType.Matrix4Array, pmdMesh.getBoneMatrixArray()); | |
308 | +// pmdMesh.boneMatricesParamIndex = g.getMaterial().getParamIndex("BoneMatrices"); | |
309 | +// } else { | |
310 | +// m.setParam(pmdMesh.boneMatricesParamIndex, VarType.Matrix4Array, pmdMesh.getBoneMatrixArray()); | |
311 | +// } | |
312 | + FloatBuffer fb = pmdMesh.getBoneMatrixBuffer(); | |
313 | + fb.position(0); | |
314 | +// for(int i=0;i<pmdMesh.getBoneIndexArray().length;i++) { | |
315 | +// offsetMatrices[pmdMesh.getBoneIndexBuffer().get(i)].fillFloatBuffer(fb, true); | |
316 | +//// pmdMesh.getBoneMatrixArray()[i].fillFloatBuffer(fb, true); | |
317 | +// } | |
318 | + projectkyoto.jme3.mmd.nativelib.SkinUtil.copyBoneMatrix(offsetMatrixbuffer, fb, pmdMesh.getBoneIndexBuffer()); | |
319 | + | |
320 | +// fb.position(0); | |
296 | 321 | if (pmdMesh.boneMatricesParamIndex < 0) { |
297 | - m.setParam("BoneMatrices", VarType.Matrix4Array, pmdMesh.getBoneMatrixArray()); | |
322 | + m.setParam("BoneMatrices", VarType.Matrix4Array, pmdMesh.getBoneMatrixBuffer()); | |
298 | 323 | pmdMesh.boneMatricesParamIndex = g.getMaterial().getParamIndex("BoneMatrices"); |
299 | 324 | } else { |
300 | - m.setParam(pmdMesh.boneMatricesParamIndex, VarType.Matrix4Array, pmdMesh.getBoneMatrixArray()); | |
325 | + m.setParam(pmdMesh.boneMatricesParamIndex, VarType.Matrix4Array, pmdMesh.getBoneMatrixBuffer()); | |
301 | 326 | } |
302 | 327 | } |
303 | 328 | } |
329 | + FloatBuffer fb = null; | |
304 | 330 | for(int i=getChildren().size()-1;i>=0;i--) { |
305 | 331 | Spatial sp = getChild(i); |
306 | 332 | if (sp instanceof PMDGeometry) { |
@@ -310,16 +336,21 @@ | ||
310 | 336 | PMDSkinMesh skinMesh = (PMDSkinMesh)mesh; |
311 | 337 | Material m = g.getMaterial(); |
312 | 338 | int boneIndexArray[] = skinMesh.getBoneIndexArray(); |
313 | - Matrix4f[] boneMatrixArray = skinMesh.getBoneMatrixArray(); | |
314 | - for (int i2 = skinMesh.getBoneIndexArray().length-1; i2 >=0; i2--) { | |
315 | - boneMatrixArray[i2] = (offsetMatrices[boneIndexArray[i2]]); | |
339 | +// Matrix4f[] boneMatrixArray = skinMesh.getBoneMatrixArray(); | |
340 | +// for (int i2 = skinMesh.getBoneIndexArray().length-1; i2 >=0; i2--) { | |
341 | +// boneMatrixArray[i2] = (offsetMatrices[boneIndexArray[i2]]); | |
342 | +// } | |
343 | + if (fb == null) { | |
344 | + fb = skinMesh.getBoneMatrixBuffer(); | |
345 | + fb.position(0); | |
346 | + projectkyoto.jme3.mmd.nativelib.SkinUtil.copyBoneMatrix(offsetMatrixbuffer, fb, skinMesh.getBoneIndexBuffer()); | |
316 | 347 | } |
317 | 348 | if (glslSkinning) { |
318 | 349 | if (skinMesh.boneMatricesParamIndex < 0) { |
319 | - m.setParam("BoneMatrices", VarType.Matrix4Array, skinMesh.getBoneMatrixArray()); | |
350 | + m.setParam("BoneMatrices", VarType.Matrix4Array, fb); | |
320 | 351 | skinMesh.boneMatricesParamIndex = g.getMaterial().getParamIndex("BoneMatrices"); |
321 | 352 | } else { |
322 | - m.setParam(skinMesh.boneMatricesParamIndex, VarType.Matrix4Array, skinMesh.getBoneMatrixArray()); | |
353 | + m.setParam(skinMesh.boneMatricesParamIndex, VarType.Matrix4Array, fb); | |
323 | 354 | } |
324 | 355 | } |
325 | 356 | } |
@@ -41,6 +41,7 @@ | ||
41 | 41 | import com.jme3.util.BufferUtils; |
42 | 42 | import java.io.IOException; |
43 | 43 | import java.nio.FloatBuffer; |
44 | +import java.nio.ShortBuffer; | |
44 | 45 | |
45 | 46 | /** |
46 | 47 | * |
@@ -53,6 +54,8 @@ | ||
53 | 54 | VertexBuffer skinvb2; |
54 | 55 | VertexBuffer skinnb2; |
55 | 56 | int boneMatricesParamIndex = -1; |
57 | + ShortBuffer boneIndexBuffer; | |
58 | + FloatBuffer boneMatrixBuffer; | |
56 | 59 | public PMDSkinMesh() { |
57 | 60 | super(); |
58 | 61 | } |
@@ -88,6 +91,22 @@ | ||
88 | 91 | public void setSkinvb2(VertexBuffer skinvb2) { |
89 | 92 | this.skinvb2 = skinvb2; |
90 | 93 | } |
94 | + | |
95 | + public ShortBuffer getBoneIndexBuffer() { | |
96 | + return boneIndexBuffer; | |
97 | + } | |
98 | + | |
99 | + public void setBoneIndexBuffer(ShortBuffer boneIndexBuffer) { | |
100 | + this.boneIndexBuffer = boneIndexBuffer; | |
101 | + } | |
102 | + | |
103 | + public FloatBuffer getBoneMatrixBuffer() { | |
104 | + return boneMatrixBuffer; | |
105 | + } | |
106 | + | |
107 | + public void setBoneMatrixBuffer(FloatBuffer boneMatrixBuffer) { | |
108 | + this.boneMatrixBuffer = boneMatrixBuffer; | |
109 | + } | |
91 | 110 | |
92 | 111 | BoundingVolume bound = new BoundingBox(Vector3f.ZERO, 20, 20, 20); |
93 | 112 |