Move VMDMotion to bytebuffer.
public PMDGeometry clone() {
Mesh meshBackup = mesh;
mesh = new Mesh();
- PMDGeometry newPMDGeometry = (PMDGeometry)super.clone(false);
+ PMDGeometry newPMDGeometry = (PMDGeometry)super.clone(true);
mesh = meshBackup;
// newPMDGeometry.setMesh(getMesh().clone());
if (mesh instanceof PMDSkinMesh) {
throw ex;
}
errFlag = true;
- if (ai.getManager() instanceof DesktopAssetManager) {
- ((DesktopAssetManager)ai.getManager()).clearCache();
- }
+// if (ai.getManager() instanceof DesktopAssetManager) {
+// ((DesktopAssetManager)ai.getManager()).clearCache();
+// }
System.gc();
System.runFinalization();
}
}
@Override
- public PMDMesh clone() {
+ public synchronized PMDMesh clone() {
PMDMesh newMesh = (PMDMesh) super.clone();
boneMatricesParamIndex = -1;
newMesh.boneMatrixArray = new Matrix4f[boneMatrixArray.length];
newMesh.setBuffer(getBuffer(VertexBuffer.Type.BoneIndex));
newMesh.setBuffer(getBuffer(VertexBuffer.Type.TexCoord));
releaseSoftwareSkinningBufferes();
+ FloatBuffer newBoneMatrixBuffer = BufferUtils.createFloatBuffer(boneMatrixBuffer.capacity());
+ boneMatrixBuffer.position(0);
+ newBoneMatrixBuffer.put(boneMatrixBuffer);
+ newBoneMatrixBuffer.position(0);
+ newMesh.setBoneMatrixBuffer(newBoneMatrixBuffer);
return newMesh;
}
@Override
public boolean shouldCache() {
- return false;
+ return true;
}
}
Node rigidBodyNode;
Node jointNode;
boolean glslSkinning = true;
+ private PMDNode original = null;
@Override
public void read(JmeImporter e) throws IOException {
// newPMDNode.offsetMatrices = new Matrix4f[offsetMatrices.length];
// newPMDNode.setGlslSkinning(newPMDNode.glslSkinning);
newPMDNode.skeleton.updateWorldVectors();
+ newPMDNode.offsetMatrixbuffer = null;
newPMDNode.calcOffsetMatrices();
newPMDNode.updateSkinBackData();
newPMDNode.update();
newPMDNode.updateSkinBackData();
newPMDNode.update();
+ if (original != null) {
+ newPMDNode.original = original;
+ } else {
+ newPMDNode.original = this;
+ }
return newPMDNode;
} catch(CloneNotSupportedException ex) {
throw new PMDException(ex);
return bound;
}
@Override
- public PMDSkinMesh clone() {
+ public synchronized PMDSkinMesh clone() {
PMDSkinMesh newMesh = (PMDSkinMesh)super.clone();
// newMesh.boneMatrixArray = new Matrix4f[boneMatrixArray.length];
newMesh.skinvb2 = new VertexBuffer(VertexBuffer.Type.Position);
// skinnb1.setupData(VertexBuffer.Usage.Stream, 3, VertexBuffer.Format.Float, skinnfb1);
// newMesh.clearBuffer(VertexBuffer.Type.Normal);
// newMesh.setBuffer(skinnb1);
+ FloatBuffer newBoneMatrixBuffer = BufferUtils.createFloatBuffer(boneMatrixBuffer.capacity());
+ boneMatrixBuffer.position(0);
+ newBoneMatrixBuffer.put(boneMatrixBuffer);
+ newBoneMatrixBuffer.position(0);
+ newMesh.setBoneMatrixBuffer(newBoneMatrixBuffer);
return newMesh;
}
import com.jme3.asset.AssetInfo;
import com.jme3.asset.AssetLoader;
import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import projectkyoto.mmd.file.VMDFile;
/**
* @author kobayasi
*/
public class VMDLoader implements AssetLoader {
-
+ private static final Logger logger = Logger.getLogger(VMDLoader.class.getName());
public VMDLoader() {
}
@Override
public Object load(AssetInfo ai) throws IOException {
+ logger.log(Level.INFO, "load {0}", ai.getKey().getName());
return new VMDFile(ai.openStream());
}
}
return ((3 + 9 * p1 - 9 * p2) * t * t + (6 * p2 - 12 * p1) * t + 3 * p1);
}
- static float calcIp(final BoneMotionList bml, float x, int offset) {
+ static float calcIp(final VMDControl.BoneMotionList bml, float x, int offset) {
if (x <= 0) {
return 0f;
}
SkinList[] skinListArray;
int lastFrameNo = 0;
boolean pause = false;
- static final VMDMotionComparator vmc = new VMDMotionComparator();
+ final VMDMotionComparator vmc = new VMDMotionComparator();
static final VMDSkinComparator vmsc = new VMDSkinComparator();
final PhysicsControl physicsControl;
int boneEnabled[];
}
private void initMotionMap() {
- for (VMDMotion m : vmdFile.getMotionArray()) {
+ VMDMotion m = new VMDMotion();
+ for(int motionNo = 0;motionNo < vmdFile.getMotionCount();motionNo++) {
+ vmdFile.getMotion(m, motionNo);
+// }
+// for (VMDMotion m : vmdFile.getMotionArray()) {
BoneMotionList motionList = motionMap.get(m.getBoneName());
if (motionList == null) {
motionList = new BoneMotionList();
motionList.boneIndex = pmdNode.getSkeleton().getBoneIndex(motionList.bone);
motionMap.put(m.getBoneName(), motionList);
}
- motionList.add(m);
+ motionList.add(motionNo);
if (m.getFrameNo() > lastFrameNo) {
lastFrameNo = m.getFrameNo();
}
for (BoneMotionList ml : motionMap.values()) {
Collections.sort(ml, vmc);
ml.setCurrentCount(0);
+// for(int i=0;i<ml.size();i++) {
+// System.out.print(ml.getVMDMotion(tmpMotion, i).getFrameNo());
+// System.out.print(" ");
+// }
}
+ System.out.println();
for (VMDSkin skin : vmdFile.getSkinArray()) {
SkinList skinList = skinMap.get(skin.getSkinName());
if (skinList == null) {
Bone bone = bml.bone;
if (bone != null && boneEnabled[bml.boneIndex] == 1) {
if (bml.size() - 1 < bml.currentCount) {
- VMDMotion m1 = bml.get(bml.size() - 1);
+ VMDMotion m1 = bml.getVMDMotion(tmpMotion2, bml.size() - 1);
Quat4f q = m1.getRotation();
if (true || bml.boneType == 0 || bml.boneType == 2 || bml.boneType == 1 || bml.boneType == 4) {
bone.getLocalRotation().set(q.x, q.y, q.z, q.w);
bone.getLocalPosition().set(v.x + p.x, v.y + p.y, v.z + p.z);
}
} else {
- VMDMotion m1, m2;
+ VMDMotion m1 = tmpMotion2, m2 = tmpMotion3;
int count = bml.currentCount;
for (;;) {
- VMDMotion m = bml.m2;
+ VMDMotion m = tmpMotion.set(bml.m2);
if (m.getFrameNo() > currentFrameNo) {
- m1 = bml.m1;
- m2 = bml.m2;
+ m1.set(bml.m1);
+ m2.set(bml.m2);
break;
}
if (count >= bml.size()) {
- m1 = bml.m1;
- m2 = bml.m2;
+ m1.set(bml.m1);
+ m2.set(bml.m2);
break;
}
count++;
for (BoneMotionList bml : boneMotionListArray) {
int count = bml.size() - 1;
for (int i = 0; i < bml.size(); i++) {
- VMDMotion m = bml.get(i);
+ VMDMotion m = bml.getVMDMotion(tmpMotion, i);
if (m.getFrameNo() > frameNo) {
count = i;
break;
this.accuracy = accuracy;
physicsControl.getWorld().setAccuracy(accuracy);
}
-
-}
-class BoneMotionList extends ArrayList<VMDMotion> {
+ private final VMDMotion tmpMotion = new VMDMotion();
+ private final VMDMotion tmpMotion2 = new VMDMotion();
+ private final VMDMotion tmpMotion3 = new VMDMotion();
+ class BoneMotionList extends ArrayList<Integer> {
- static final int IPTABLESIZE = 16;
- String boneName;
- Bone bone;
- int boneIndex;
- int currentCount;
- VMDMotion m1,m2;
- int boneType;
- final float ipTable[][][] = new float[4][IPTABLESIZE][2];
- int ipTableIndex = 0;
- int frame1, frame2;
- final float val1[] = new float[4];
- final float val2[] = new float[4];
-
- void setCurrentCount(int newCount) {
- if (currentCount != newCount) {
- currentCount = newCount;
- if (newCount >= 0 && newCount < size()) {
- IPUtil.createInterpolationTable(get(currentCount).getInterpolation(), ipTable);
+ static final int IPTABLESIZE = 16;
+ String boneName;
+ Bone bone;
+ int boneIndex;
+ int currentCount;
+ final VMDMotion m1 = new VMDMotion();
+ final VMDMotion m2 = new VMDMotion();
+ int boneType;
+ final float ipTable[][][] = new float[4][IPTABLESIZE][2];
+ int ipTableIndex = 0;
+ int frame1, frame2;
+ final float val1[] = new float[4];
+ final float val2[] = new float[4];
+ VMDMotion getVMDMotion(VMDMotion m, int i) {
+ vmdFile.getMotion(m, get(i));
+ return m;
+ }
+ void setCurrentCount(int newCount) {
+ if (currentCount != newCount) {
+ currentCount = newCount;
+ if (newCount >= 0 && newCount < size()) {
+ IPUtil.createInterpolationTable(getVMDMotion(tmpMotion, currentCount).getInterpolation(), ipTable);
+ }
+ }
+ ipTableIndex = 0;
+ if (newCount == 0) {
+ getVMDMotion(m1, 0);
+ m2.set(m1);
+ } else if (newCount < size()) {
+ getVMDMotion(m1, newCount-1);
+ getVMDMotion(m2, newCount);
+ } else if (size() > 0) {
+ getVMDMotion(m1, size()-1);
+ m2.set(m1);
+ } else {
+// m1 = null;
+// m2 = null;
}
- }
- ipTableIndex = 0;
- if (newCount == 0) {
- m1 = get(0);
- m2 = m1;
- } else if (newCount < size()) {
- m1 = get(newCount-1);
- m2 = get(newCount);
- } else if (size() > 0) {
- m1 = get(size()-1);
- m2 = m1;
- } else {
- m1 = null;
- m2 = null;
}
}
-}
-
-class VMDMotionComparator implements Comparator<VMDMotion> {
-
- @Override
- public int compare(VMDMotion o1, VMDMotion o2) {
- if (o1.getFrameNo() < o2.getFrameNo()) {
- return -1;
- } else if (o1.getFrameNo() < o2.getFrameNo()) {
- return 0;
- } else {
- return 1;
+ class VMDMotionComparator implements Comparator<Integer> {
+ final VMDMotion o1 = new VMDMotion();
+ final VMDMotion o2 = new VMDMotion();
+ @Override
+ public int compare(Integer i1, Integer i2) {
+ vmdFile.getMotion(o1, i1);
+ vmdFile.getMotion(o2, i2);
+ if (o1.getFrameNo() < o2.getFrameNo()) {
+ return -1;
+ } else if (o1.getFrameNo() == o2.getFrameNo()) {
+ return 0;
+ } else {
+ return 1;
+ }
}
}
}
+
class SkinList extends ArrayList<VMDSkin> {
String skinName;
for (int i = 0; i < boneNameEnglish.length; i++) {
boneNameEnglish[i] = is.readString(20);
}
- skinNameEnglish = new String[model.getSkinCount() - 1];
- for (int i = 0; i < skinNameEnglish.length; i++) {
- skinNameEnglish[i] = is.readString(20);
+ if (model.getSkinCount() > 0) {
+ skinNameEnglish = new String[model.getSkinCount() - 1];
+ for (int i = 0; i < skinNameEnglish.length; i++) {
+ skinNameEnglish[i] = is.readString(20);
+ }
}
-
dispNameEnglish = new String[model.getBoneDispNameList().getBoneDispNameCount()];
for (int i = 0; i < dispNameEnglish.length; i++) {
dispNameEnglish[i] = is.readString(50);
import java.io.InputStream;
import java.io.Serializable;
import java.net.URL;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import projectkyoto.mmd.file.util2.BufferUtil;
/**
*
private String vmdHeader; // char[30] Vocaloid Motion Data 0002
private String vmdModelName; // char[20]
private int motionCount;
- private VMDMotion motionArray[];
+// private VMDMotion motionArray[];
private int skinCount;
private VMDSkin skinArray[];
-
+ protected final ArrayList<String> boneNames = new ArrayList<String>();
+// protected final ArrayList<String> skinNames = new ArrayList<String>();
+ private ByteBuffer bb1;
+// private ByteBuffer bb2;
public VMDFile() {
- motionArray = new VMDMotion[0];
+// motionArray = new VMDMotion[0];
skinArray = new VMDSkin[0];
}
}
vmdModelName = is.readString(20);
motionCount = is.readInt();
- motionArray = new VMDMotion[motionCount];
+// motionArray = new VMDMotion[motionCount];
+ bb1 = BufferUtil.createByteBuffer(98 * motionCount);
+ VMDMotion motion = new VMDMotion();
+ motion.vmdFile = this;
+ Integer indexes[] = new Integer[motionCount];
+ for(int i=0;i<motionCount;i++) {
+ motion.readFromStream(is);
+ motion.writeToBuffer(bb1);
+ indexes[i] = i;
+ }
+ Arrays.sort(indexes, new VMDComparator());
+ ByteBuffer bb2 = BufferUtil.createByteBuffer(98 * motionCount);
for(int i=0;i<motionCount;i++) {
- motionArray[i] = new VMDMotion(is);
+ getMotion(motion, indexes[i]);
+ bb2.position(98 * i);
+ motion.writeToBuffer(bb2);
}
+ bb1 = bb2;
skinCount = is.readInt();
+// bb2 = BufferUtil.createByteBuffer(98 * skinCount);
skinArray = new VMDSkin[skinCount];
for(int i=0;i<skinCount;i++) {
skinArray[i] = new VMDSkin(is);
sb.append("vmdModelName = ").append(vmdModelName).append("\n");
sb.append("motionCount = ").append(motionCount).append("\n");
sb.append("motionArray = {\n");
- for(VMDMotion m : motionArray) {
+ VMDMotion m = new VMDMotion();
+ for(int i=0;i<motionCount;i++) {
+ m.readFromBuffer(bb1);
sb.append(m).append("\n");
}
sb.append("}\n");
return sb.toString();
}
- public VMDMotion[] getMotionArray() {
- return motionArray;
- }
+// public VMDMotion[] getMotionArray() {
+// return motionArray;
+// }
- public void setMotionArray(VMDMotion[] motionArray) {
- this.motionArray = motionArray;
+// public void setMotionArray(VMDMotion[] motionArray) {
+// this.motionArray = motionArray;
+// }
+ public synchronized VMDMotion getMotion(VMDMotion m, int i) {
+ m.vmdFile = this;
+ bb1.position(98 * i);
+ m.readFromBuffer(bb1);
+ return m;
}
-
public int getMotionCount() {
return motionCount;
}
public void setVmdModelName(String vmdModelName) {
this.vmdModelName = vmdModelName;
}
-
+ class VMDComparator implements Comparator<Integer> {
+ VMDMotion m1 = new VMDMotion();
+ VMDMotion m2 = new VMDMotion();
+ @Override
+ public int compare(Integer t, Integer t1) {
+ getMotion(m1, t);
+ getMotion(m2, t1);
+ if (m1.getFrameNo() < m2.getFrameNo()) {
+ return -1;
+ } else if (m1.getFrameNo() == m2.getFrameNo()) {
+ return 0;
+ }
+ return 1;
+ }
+
+ }
}
* @author kobayasi
*/
public class VMDMotion implements Serializable{
-
+ protected VMDFile vmdFile;
private String boneName; // char[15]
+ private short boneIndex;
private int frameNo;
private Point3f location;
private Quat4f rotation;
location = new Point3f();
rotation = new Quat4f();
}
- public VMDMotion(DataInputStreamLittleEndian is) throws IOException {
+ public VMDMotion(VMDFile vmdFile, DataInputStreamLittleEndian is) throws IOException {
+ this.vmdFile = vmdFile;
+ readFromStream(is);
+ }
+ public final void readFromStream(DataInputStreamLittleEndian is) throws IOException {
boneName = is.readString(15);
-// System.out.println("boneName = "+boneName);
+ boneIndex = -1;
+// for(int i=0;i<vmdFile.boneNames.size();i++) {
+// if (boneName.equals(vmdFile.boneNames.get(i))) {
+// boneIndex = (short)i;
+// break;
+// }
+// }
+ boneIndex = (short)vmdFile.boneNames.indexOf(boneName);
+ if (boneIndex < 0) {
+ vmdFile.boneNames.add(boneName);
+// boneIndex = (short)(vmdFile.boneNames.size() - 1);
+ boneIndex = (short)vmdFile.boneNames.indexOf(boneName);
+ }
frameNo = is.readInt();
location = new Point3f();
location.x = is.readFloat();
pos += is.read(interpolation, pos, 64 - pos);
}
}
-// public VMDMotion readFromBuffer(ByteBuffer bb) {
+ public VMDMotion readFromBuffer(ByteBuffer bb) {
// boneName = BufferUtil.readString(bb, 15);
-// frameNo = bb.getInt();
-// BufferUtil.readPoint3f(bb, location);
-// BufferUtil.readQuat4f(bb, rotation);
-// bb.get(interpolation);
-// return this;
-// }
-// public VMDMotion writeToBuffer(ByteBuffer bb) {
+ boneIndex = bb.getShort();
+ frameNo = bb.getInt();
+ BufferUtil.readPoint3f(bb, location);
+ BufferUtil.readQuat4f(bb, rotation);
+ bb.get(interpolation);
+ return this;
+ }
+ public VMDMotion writeToBuffer(ByteBuffer bb) {
+ int startPos = bb.position();
// BufferUtil.writeString(bb, boneName, 15);
-// bb.putInt(frameNo);
-//
-// return this;
-// }
+ bb.putShort(boneIndex);
+ bb.putInt(frameNo);
+ BufferUtil.writePoint3f(bb, location);
+ BufferUtil.writeQuat4f(bb, rotation);
+ bb.put(interpolation);
+ int endPos = bb.position();
+ if (endPos - startPos != 98) {
+ throw new RuntimeException("size = "+(endPos - startPos));
+ }
+ return this;
+ }
+ public VMDMotion set(VMDMotion m) {
+ boneIndex = m.boneIndex;
+ frameNo = m.frameNo;
+ location.set(m.location);
+ rotation.set(m.rotation);
+ System.arraycopy(m.interpolation, 0, interpolation, 0, 64);
+ vmdFile = m.vmdFile;
+ return m;
+ }
@Override
public String toString() {
}
public String getBoneName() {
- return boneName;
+ return vmdFile.boneNames.get(boneIndex);
}
public void setBoneName(String boneName) {
private float weight;
public VMDSkin(DataInputStreamLittleEndian is) throws IOException {
+ readFromStream(is);
+ }
+ public final void readFromStream(DataInputStreamLittleEndian is) throws IOException {
skinName = is.readString(15);
flameNo = is.readInt();
weight = is.readFloat();
*/
public class BufferUtil {
public static File tmpDir = null;
+ public static boolean useTempFile = false;
private static final Logger logger = Logger.getLogger(BufferUtil.class.getName());
- public static ByteBuffer createByteBuffer2(int size) {
+ public static ByteBuffer createByteBuffer(int size) {
+ if (useTempFile && tmpDir != null) {
+ return createByteBufferFile(size);
+ } else {
+ return createByteBufferHeap(size);
+ }
+ }
+ private static ByteBuffer createByteBufferHeap(int size) {
ByteBuffer bb = ByteBuffer.allocateDirect(size);
bb.order(ByteOrder.nativeOrder());
return bb;
}
- public static ByteBuffer createByteBuffer(int size) {
+ private static ByteBuffer createByteBufferFile(int size) {
try {
if (tmpDir != null && logger.isLoggable(Level.INFO)) {
logger.log(Level.INFO, "tmpDir = {0}", tmpDir.getAbsoluteFile());