import com.jme3.animation.Bone;
import com.jme3.animation.Skeleton;
+import com.jme3.asset.AssetInfo;
+import com.jme3.asset.AssetLoader;
import com.jme3.asset.AssetManager;
import com.jme3.asset.AssetNotFoundException;
import com.jme3.material.Material;
import com.jme3.texture.Texture;
import com.jme3.util.BufferUtils;
import com.jme3.util.TempVars;
+import java.io.IOException;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.ArrayList;
*
* @author kobayasi
*/
-public class PMDLoaderGLSLSkinning2 {
+public class PMDLoaderGLSLSkinning2 implements AssetLoader{
PMDModel model;
PMDNode node;
MeshConverter meshConverter;
int meshCount = 1;
AssetManager assetManager;
+ String folderName;
List<PMDMesh> meshList = new ArrayList<PMDMesh>();
List<PMDSkinMesh> skinMeshList = new ArrayList<PMDSkinMesh>();
VertexBuffer skinvb;
Skin skinArray[];
SkeletonControl skeletonControl;
+ public PMDLoaderGLSLSkinning2() {
+ }
+
public PMDLoaderGLSLSkinning2(AssetManager assetManager, PMDModel model) {
this.assetManager = assetManager;
this.model = model;
+ folderName = "/Model/";
// System.out.println("vertexCount = " + model.getVertCount());
// System.out.println("faceVertCount = " + model.getFaceVertCount());
meshConverter = new MeshConverter(model);
}
// System.out.println("isb.capacity() = " + isb.capacity());
// System.out.println("isb.capacity() = " + md.getIndexList().size());
- vb.setupData(VertexBuffer.Usage.Static, 3, VertexBuffer.Format.Float, vfb);
- nb.setupData(VertexBuffer.Usage.Static, 3, VertexBuffer.Format.Float, nfb);
+ vb.setupData(VertexBuffer.Usage.Dynamic, 3, VertexBuffer.Format.Float, vfb);
+ nb.setupData(VertexBuffer.Usage.Dynamic, 3, VertexBuffer.Format.Float, nfb);
bvb.setupData(VertexBuffer.Usage.CpuOnly, 3, VertexBuffer.Format.Float, bvfb);
bnb.setupData(VertexBuffer.Usage.CpuOnly, 3, VertexBuffer.Format.Float, bnfb);
String fileName = st.nextToken();
System.out.println("fileName = " + fileName);
String s = fileName.substring(fileName.indexOf('.') + 1);
- Texture texture = assetManager.loadTexture("Model/" + fileName /*
+ Texture texture = assetManager.loadTexture(folderName + fileName /*
* m.getTextureFileName()
*/);
s = s.toLowerCase();
if (toonIndex >= 0) {
String extToonName = model.getToonTextureList().getToonFileName()[toonIndex];
try {
- toonTexture = assetManager.loadTexture("/Model/" + extToonName);
+ toonTexture = assetManager.loadTexture(folderName + extToonName);
} catch (AssetNotFoundException ex) {
String toonname = null;
switch (toonIndex) {
return boneNode;
}
+
+ @Override
+ public Object load(AssetInfo ai) throws IOException {
+ this.assetManager = ai.getManager();
+ model = new PMDModel(ai.openStream());
+ folderName = ai.getKey().getFolder();
+ meshConverter = new MeshConverter(model);
+ return createNode(ai.getKey().getName());
+ }
}
--- /dev/null
+// Copyright (c) 2011 Kazuhiko Kobayashi
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// * Neither the name of 'MMDLoaderJME' nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package projectkyoto.jme3.mmd;
+
+import com.jme3.asset.ModelKey;
+
+/**
+ *
+ * @author kobayasi
+ */
+public class PMDModelKey extends ModelKey{
+
+ public PMDModelKey() {
+ super();
+ }
+
+ public PMDModelKey(String name) {
+ super(name);
+ }
+
+}
}
private void swapSkinMesh() {
VertexBuffer vb = skinTargets[0].getBuffer(VertexBuffer.Type.Position);
- vb.setUsage(Usage.CpuOnly);
VertexBuffer nb = skinTargets[0].getBuffer(VertexBuffer.Type.Normal);
- nb.setUsage(Usage.CpuOnly);
skinTargets[0].skinvb2.setUpdateNeeded();
- skinTargets[0].skinvb2.setUsage(Usage.Static);
skinTargets[0].skinnb2.setUpdateNeeded();
- skinTargets[0].skinnb2.setUsage(Usage.Static);
for(PMDSkinMesh skinMesh : skinTargets) {
skinMesh.clearBuffer(Type.Position);
skinMesh.clearBuffer(Type.Normal);
vb.setUpdateNeeded();
nb.setUpdateNeeded();
}
- private void softwareSkinUpdate(PMDMesh mesh) {
+ private void softwareSkinUpdate(PMDMesh mesh){
int maxWeightsPerVert = 2;//mesh.getMaxNumWeights();
int fourMinusMaxWeights = 4 - maxWeightsPerVert;
// Matrix4f[] offsetMatrices = mesh.getBoneMatrixArray();
float[] posBuf = vars.skinPositions;
float[] normBuf = vars.skinNormals;
- int iterations = (int) FastMath.ceil(fvb.capacity() / ((float) posBuf.length));
+ int iterations = (int) FastMath.ceil(fvb.capacity() / ((float)posBuf.length));
int bufLength = posBuf.length * 3;
- for (int i = iterations - 1; i >= 0; i--) {
+ for (int i = iterations-1; i >= 0; i--){
// read next set of positions and normals from native buffer
bufLength = Math.min(posBuf.length, fvb.remaining());
fvb.get(posBuf, 0, bufLength);
int idxPositions = 0;
// iterate vertices and apply skinning transform for each effecting bone
- for (int vert = verts - 1; vert >= 0; vert--) {
+ for (int vert = verts - 1; vert >= 0; vert--){
float nmx = normBuf[idxPositions];
float vtx = posBuf[idxPositions++];
float nmy = normBuf[idxPositions];
float nmz = normBuf[idxPositions];
float vtz = posBuf[idxPositions++];
- float rx = 0, ry = 0, rz = 0, rnx = 0, rny = 0, rnz = 0;
+ float rx=0, ry=0, rz=0, rnx=0, rny=0, rnz=0;
- for (int w = maxWeightsPerVert - 1; w >= 0; w--) {
+ for (int w = maxWeightsPerVert - 1; w >= 0; w--){
float weight = wb.get(idxWeights); //weights[idxWeights];
Matrix4f mat = mesh.getBoneMatrixArray()[ib.get(idxWeights++)];//offsetMatrices[indices[idxWeights++]];
}
- fvb.position(fvb.position() - bufLength);
+ fvb.position(fvb.position()-bufLength);
fvb.put(posBuf, 0, bufLength);
- fnb.position(fnb.position() - bufLength);
+ fnb.position(fnb.position()-bufLength);
fnb.put(normBuf, 0, bufLength);
}
-
- vb.updateData(fvb);
- nb.updateData(fnb);
+ vb.setUpdateNeeded();
+ nb.setUpdateNeeded();
vars.release();
+
// mesh.updateBound();
}
public void updateSkinBackData() {
Mesh mesh = ((PMDGeometry) sp).getMesh();
if (mesh instanceof PMDMesh) {
resetToBind((PMDMesh) mesh);
+ if (glslSkinning) {
+ mesh.getBuffer(Type.Position).setUsage(Usage.Static);
+ mesh.getBuffer(Type.Normal).setUsage(Usage.Static);
+ } else {
+ mesh.getBuffer(Type.Position).setUsage(Usage.Dynamic);
+ mesh.getBuffer(Type.Normal).setUsage(Usage.Dynamic);
+ }
}
}
}
public int hashCode() {
return pmdModel.getModelName().hashCode();
}
+
+ @Override
+ public Spatial clone() {
+ return super.clone();
+ }
+
}
--- /dev/null
+// Copyright (c) 2011 Kazuhiko Kobayashi
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// * Neither the name of 'MMDLoaderJME' nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+package projectkyoto.jme3.mmd;
+
+import com.jme3.asset.AssetInfo;
+import com.jme3.asset.AssetLoader;
+import java.io.IOException;
+import projectkyoto.mmd.file.VMDFile;
+
+/**
+ *
+ * @author kobayasi
+ */
+public class VMDLoader implements AssetLoader {
+
+ public VMDLoader() {
+ }
+
+ @Override
+ public Object load(AssetInfo ai) throws IOException {
+ return new VMDFile(ai.openStream());
+ }
+}
* @author Kazuhiko Kobayashi
*/
public class DataInputStreamLittleEndian extends FilterInputStream {
- public URL url;
+// public URL url;
private DataInputStream dis;
byte[] buf;
}
public DataInputStreamLittleEndian(URL url) throws IOException {
super(new BufferedInputStream(url.openStream()));
- this.url = url;
+// this.url = url;
dis = new DataInputStream(this);
}
final byte[] getBuf(int size) {
private byte edgeFlag;
private int faceVertCount;
private String textureFileName; // 20文字
- private byte[] textureData;
+// private byte[] textureData;
public PMDMaterial() {
}
// if (textureFileName.length() != 0) {
// texture = TextureIO.newTexture(new URL(is.url ,textureFileName), true,"bmp");
// }
- if ( false && !textureFileName.isEmpty()) {
- InputStream textureIs = null;
- try {
- textureIs = new URL(is.url ,textureFileName).openStream();
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- byte[] buf = new byte[4096];
- for(;;) {
- int size = textureIs.read(buf);
- if (size <= 0) {
- break;
- }
- os.write(buf,0,size);
- }
- os.close();
- textureData = os.toByteArray();
- } catch(IOException ex) {
- ex.printStackTrace();
- } finally {
- if (textureIs != null) {
- textureIs.close();
- textureIs = null;
- }
- }
- }
+// if ( false && !textureFileName.isEmpty()) {
+// InputStream textureIs = null;
+// try {
+// textureIs = new URL(is.url ,textureFileName).openStream();
+// ByteArrayOutputStream os = new ByteArrayOutputStream();
+// byte[] buf = new byte[4096];
+// for(;;) {
+// int size = textureIs.read(buf);
+// if (size <= 0) {
+// break;
+// }
+// os.write(buf,0,size);
+// }
+// os.close();
+// textureData = os.toByteArray();
+// } catch(IOException ex) {
+// ex.printStackTrace();
+// } finally {
+// if (textureIs != null) {
+// textureIs.close();
+// textureIs = null;
+// }
+// }
+// }
}
public byte getEdgeFlag() {
this.toonIndex = toonIndex;
}
- public byte[] getTextureData() {
- return textureData;
- }
-
- public void setTextureData(byte[] textureData) {
- this.textureData = textureData;
- }
+// public byte[] getTextureData() {
+// return textureData;
+// }
+//
+// public void setTextureData(byte[] textureData) {
+// this.textureData = textureData;
+// }
@Override
public String toString() {
*/
package projectkyoto.mmd.file;
+import java.io.BufferedInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
/**
private PMDToonTextureList toonTextureList;
private PMDRigidBodyList rigidBodyList;
private PMDJointList jointList;
- private URL url;
public PMDModel() {
}
public PMDModel(URL url) throws IOException {
- readFromFile(url);
+ readFromFile(url.openStream());
}
-
- public void readFromFile(URL url) throws IOException {
- DataInputStreamLittleEndian is = null;
+ public PMDModel(InputStream is) throws IOException {
+ readFromFile(is);
+ }
+ public void readFromFile(InputStream is) throws IOException {
+ DataInputStreamLittleEndian dis = null;
try {
// is = new DataInputStreamLittleEndian(new BufferedInputStream(
// new FileInputStream(
// file)));
- is = new DataInputStreamLittleEndian(url);
- readFromStream(is);
- is.close();
- this.url = url;
+ dis = new DataInputStreamLittleEndian(new BufferedInputStream(is));
+ readFromStream(dis);
+ dis.close();
+// this.url = url;
} finally {
- if (is != null) {
- is.close();
- is = null;
+ if (dis != null) {
+ dis.close();
+ dis = null;
}
}
// System.out.println(toString());
package projectkyoto.mmd.file;
+import java.io.BufferedInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
/**
private VMDMotion motionArray[];
private int skinCount;
private VMDSkin skinArray[];
+
+ public VMDFile() {
+ }
+
public VMDFile(URL url) throws IOException {
+ read(url.openStream());
+ }
+ public VMDFile(InputStream is2) throws IOException {
+ read(is2);
+ }
+ public void read(InputStream is2) throws IOException{
DataInputStreamLittleEndian is = null;
try {
- is = new DataInputStreamLittleEndian(url);
+ is = new DataInputStreamLittleEndian(new BufferedInputStream(is2));
vmdHeader = is.readString(30);
if (!"Vocaloid Motion Data 0002".equals(vmdHeader)) {
- throw new InvalidVMDFileException(url.toString());
+ throw new InvalidVMDFileException();
}
vmdModelName = is.readString(20);
motionCount = is.readInt();
int faceVertNo = 0;
for (int materialNo = 0; materialNo < model.getMaterialCount(); materialNo++) {
PMDMaterial material = model.getMaterial()[materialNo];
+ if (material.getFaceVertCount() == 0) {
+ continue;
+ }
MeshData meshData = new MeshData(model, maxBoneSize, material);
meshDataList.add(meshData);
for (int materialFaceVertNo = 0; materialFaceVertNo < material.getFaceVertCount(); materialFaceVertNo += 3) {
}
}
}
+ if (meshData.getVertexList().size() == 0) {
+ meshDataList.remove(meshDataList.size()-1);
+ }
}
int vertSizeSum = 0;
int boneSizeSum = 0;
boneSizeSum += meshData.getBoneList().size();
indexSizeSum += meshData.getIndexList().size();
// printMeshData(meshData);
+// System.out.println("mesh size = "+meshData.vertexList.size());
}
// System.out.println("-----------------------skin");
// System.out.println("index " + model.getFaceVertCount() + " " + indexSizeSum