From 1f1ed79e74643d198e4a444c0e76edaa215d54ee Mon Sep 17 00:00:00 2001 From: Kazuhiko Kobayashi Date: Thu, 2 Feb 2012 15:59:52 +0900 Subject: [PATCH] add Savable support fix clone bug fix MeshConverter bug add vertex lighting support add unified physcs world support --- nbproject/project.properties | 2 + src/MatDefs/pmd/pmd.frag | 36 +-- src/MatDefs/pmd/pmd.j3md | 4 +- src/MatDefs/pmd/pmd.vert | 8 +- src/MatDefs/pmd/pmd_alpha.j3md | 2 +- src/MatDefs/pmd/pmd_cartoon.vert | 6 +- src/MatDefs/pmd/pmd_no_skinning.j3md | 2 +- src/MatDefs/pmd/pmd_non_adero.frag | 255 +++++++++++++++++++++ src/projectkyoto/jme3/mmd/PMDGeometry.java | 76 +++++- .../jme3/mmd/PMDLoaderGLSLSkinning2.java | 83 +++++-- src/projectkyoto/jme3/mmd/PMDMesh.java | 29 +++ src/projectkyoto/jme3/mmd/PMDNode.java | 168 +++++++++++++- src/projectkyoto/jme3/mmd/PMDSkinMesh.java | 28 ++- src/projectkyoto/jme3/mmd/PmdUtil.java | 59 +++++ src/projectkyoto/jme3/mmd/Skin.java | 24 +- src/projectkyoto/jme3/mmd/ik/IKControl.java | 8 +- .../jme3/mmd/nativebullet/PMDPhysicsWorld.java | 13 +- .../jme3/mmd/nativebullet/PMDRigidBody.java | 22 ++ .../jme3/mmd/nativebullet/PhysicsControl.java | 6 +- src/projectkyoto/jme3/mmd/vmd/VMDCallable.java | 5 + src/projectkyoto/jme3/mmd/vmd/VMDControl.java | 69 +++++- src/projectkyoto/jme3/mmd/vmd/VMDControlMT.java | 35 ++- src/projectkyoto/mmd/file/Coords2d.java | 3 +- src/projectkyoto/mmd/file/PMDBone.java | 3 +- src/projectkyoto/mmd/file/PMDBoneDisp.java | 3 +- src/projectkyoto/mmd/file/PMDBoneDispList.java | 3 +- src/projectkyoto/mmd/file/PMDBoneDispNameList.java | 3 +- src/projectkyoto/mmd/file/PMDBoneList.java | 3 +- src/projectkyoto/mmd/file/PMDHeaderEnglish.java | 3 +- src/projectkyoto/mmd/file/PMDIKData.java | 3 +- src/projectkyoto/mmd/file/PMDIKList.java | 3 +- src/projectkyoto/mmd/file/PMDJoint.java | 3 +- src/projectkyoto/mmd/file/PMDJointList.java | 8 +- src/projectkyoto/mmd/file/PMDMaterial.java | 3 +- src/projectkyoto/mmd/file/PMDModel.java | 7 +- src/projectkyoto/mmd/file/PMDRigidBody.java | 3 +- src/projectkyoto/mmd/file/PMDRigidBodyList.java | 8 +- src/projectkyoto/mmd/file/PMDSkinData.java | 3 +- src/projectkyoto/mmd/file/PMDSkinDispList.java | 3 +- src/projectkyoto/mmd/file/PMDSkinVertData.java | 3 +- src/projectkyoto/mmd/file/PMDToonTextureList.java | 10 +- src/projectkyoto/mmd/file/PMDVertex.java | 3 +- src/projectkyoto/mmd/file/VMDFile.java | 3 +- src/projectkyoto/mmd/file/VMDMotion.java | 3 +- src/projectkyoto/mmd/file/VMDSkin.java | 3 +- src/projectkyoto/mmd/file/XColorRGB.java | 3 +- src/projectkyoto/mmd/file/XColorRGBA.java | 3 +- src/projectkyoto/mmd/file/XMaterial.java | 3 +- src/projectkyoto/mmd/file/util2/MeshConverter.java | 31 +-- src/projectkyoto/mmd/file/util2/SavableUtil.java | 49 ++++ src/projectkyoto/mmd/file/util2/SkinMeshData.java | 3 +- 51 files changed, 991 insertions(+), 131 deletions(-) create mode 100644 src/MatDefs/pmd/pmd_non_adero.frag create mode 100644 src/projectkyoto/jme3/mmd/PmdUtil.java create mode 100644 src/projectkyoto/mmd/file/util2/SavableUtil.java diff --git a/nbproject/project.properties b/nbproject/project.properties index 28ed4e691..296a540fd 100755 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -26,9 +26,11 @@ dist.jar=${dist.dir}/MMDLoaderJME3-lib.jar dist.javadoc.dir=${dist.dir}/javadoc endorsed.classpath= excludes= +file.reference.jMonkeyEngine3.jar=/Users/kobayasi/NetBeansProjects/MMD/MikuMikuStudio/mikumikustudio/engine/dist/jMonkeyEngine3.jar includes=** jar.compress=false javac.classpath=\ + ${file.reference.jMonkeyEngine3.jar}:\ ${libs.jme3-libraries.classpath}:\ ${libs.jme3.classpath} # Space-separated list of extra javac options diff --git a/src/MatDefs/pmd/pmd.frag b/src/MatDefs/pmd/pmd.frag index ddd449b92..6e93cc6a6 100755 --- a/src/MatDefs/pmd/pmd.frag +++ b/src/MatDefs/pmd/pmd.frag @@ -65,7 +65,6 @@ varying vec3 lightVec; uniform ENVMAP m_EnvMap; #endif - varying vec4 refVec; float tangDot(in vec3 v1, in vec3 v2){ float d = dot(v1,v2); @@ -123,6 +122,7 @@ vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec3 w return vec2(diffuseFactor, specularFactor) * vec2(att); } #endif + varying vec4 refVec; vec2 Optics_SphereCoord2(in vec3 dir){ float dzplus1 = dir.z + 1.0; float m = 2.0 * sqrt(dir.x * dir.x + dir.y * dir.y + dzplus1 * dzplus1); @@ -158,7 +158,7 @@ void main(){ #ifdef ALPHAMAP alpha = alpha * texture2D(m_AlphaMap, newTexCoord).r; #endif - if(alpha < m_AlphaDiscardThreshold){ + if(alpha < 0.1 /*m_AlphaDiscardThreshold*/){ discard; } @@ -190,18 +190,16 @@ void main(){ #ifdef COLORRAMP // light.x = texture2D(m_ColorRamp, vec2(light.x, 0.0)).r; // light.y = texture2D(m_ColorRamp, vec2(light.y, 0.0)).r; - light.x = texture2D(m_ColorRamp, vec2(0.0,light.x)).r; - light.y = texture2D(m_ColorRamp, vec2(0.0,light.y)).r; + diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light. x)).rgb; + //specularColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light. y)).rgb; #endif +// adero200 + //if (light.y != light.y) { + // light.y = 0.0; + //} + vec4 output_color = (((AmbientSum + DiffuseSum) * diffuseColor) + + SpecularSum * specularColor * light.y ); - gl_FragColor = AmbientSum * diffuseColor + - DiffuseSum * diffuseColor * light.x + - SpecularSum * specularColor * light.y; - diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light.x)).rgb; - specularColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light.y)).rgb; - gl_FragColor = AmbientSum * diffuseColor + - DiffuseSum * diffuseColor + - SpecularSum * specularColor ; #else vec4 lightDir = vLightDir; lightDir.xyz = normalize(lightDir.xyz); @@ -249,9 +247,17 @@ void main(){ #endif #endif +#ifdef SPHERE_MAP_A + vec2 v2 = Optics_SphereCoord(normalize(refVec.xyz)); + v2.y = 1.0 - v2.y; + output_color.xyz += (texture2D(m_SphereMap_A, v2).xyz); + // output_color.xyz = vec3(normalize(refVec.xyz).x); +#endif +#ifdef SPHERE_MAP_H + vec2 v2 = Optics_SphereCoord(normalize(refVec.xyz)); + v2.y = 1.0 - v2.y; + output_color.xyz *= (texture2D(m_SphereMap_H, v2).xyz); +#endif output_color.a = alpha; - // output_color.a = diffuseColor.a; - - // gl_FragColor = 0.5 + 0.5 * light.x;//output_color; gl_FragColor = output_color; } diff --git a/src/MatDefs/pmd/pmd.j3md b/src/MatDefs/pmd/pmd.j3md index 0136f6374..8d44a18c0 100755 --- a/src/MatDefs/pmd/pmd.j3md +++ b/src/MatDefs/pmd/pmd.j3md @@ -137,7 +137,7 @@ MaterialDef pmd { USE_REFLECTION : EnvMap SPHERE_MAP : SphereMap - // NUM_BONES : NumBones + NUM_BONES : NumBones USE_HWSKINNING SPHERE_MAP_A : SphereMap_A SPHERE_MAP_H : SphereMap_H @@ -188,7 +188,7 @@ MaterialDef pmd { USE_REFLECTION : EnvMap SPHERE_MAP : SphereMap - // NUM_BONES : NumBones + NUM_BONES : NumBones USE_HWSKINNING } RenderState { diff --git a/src/MatDefs/pmd/pmd.vert b/src/MatDefs/pmd/pmd.vert index 3d479096f..63104b3eb 100755 --- a/src/MatDefs/pmd/pmd.vert +++ b/src/MatDefs/pmd/pmd.vert @@ -1,6 +1,6 @@ // #import "MatDefs/pmd/Skinning.glsllib" #ifdef USE_HWSKINNING -uniform mat4 m_BoneMatrices[20]; +uniform mat4 m_BoneMatrices[NUM_BONES]; #endif #define ATTENUATION // #define HQ_ATTENUATION @@ -129,8 +129,8 @@ void Skinning_Compute(inout vec4 position, inout vec4 normal){ vec4 index = inBoneIndex; vec4 weight = inBoneWeight; - vec4 newPos = vec4(0.0); - vec4 newNormal = vec4(0.0); + vec4 newPos = vec4(0.0,0.0,0.0,0.0); + vec4 newNormal = vec4(0.0,0.0,0.0,0.0); //for (float i = 1.0; i < 2.0; i += 1.0){ mat4 skinMat = m_BoneMatrices[int(index.x)]; @@ -218,7 +218,7 @@ void main(){ vec2 light = computeLighting(wvPosition, wvNormal, viewDir, wvLightPos); AmbientSum.a = light.x; - SpecularSum.a = light.y; + SpecularSum.a = light.y * 0.3; #endif #if defined(USE_REFLECTION) || defined(SPHERE_MAP_A) || defined(SPHERE_MAP_H) diff --git a/src/MatDefs/pmd/pmd_alpha.j3md b/src/MatDefs/pmd/pmd_alpha.j3md index 14cca0be9..85132c3be 100755 --- a/src/MatDefs/pmd/pmd_alpha.j3md +++ b/src/MatDefs/pmd/pmd_alpha.j3md @@ -137,7 +137,7 @@ MaterialDef pmd { USE_REFLECTION : EnvMap SPHERE_MAP : SphereMap - // NUM_BONES : NumBones + NUM_BONES : NumBones USE_HWSKINNING SPHERE_MAP_A : SphereMap_A SPHERE_MAP_H : SphereMap_H diff --git a/src/MatDefs/pmd/pmd_cartoon.vert b/src/MatDefs/pmd/pmd_cartoon.vert index 64a414675..f3853689f 100755 --- a/src/MatDefs/pmd/pmd_cartoon.vert +++ b/src/MatDefs/pmd/pmd_cartoon.vert @@ -1,5 +1,5 @@ #ifdef USE_HWSKINNING -uniform mat4 m_BoneMatrices[20]; +uniform mat4 m_BoneMatrices[NUM_BONES]; #endif uniform float m_EdgeSize; // #import "MatDefs/pmd/Skinning.glsllib" @@ -26,8 +26,8 @@ void Skinning_Compute(inout vec4 position, inout vec4 normal){ vec4 index = inBoneIndex; vec4 weight = inBoneWeight; - vec4 newPos = vec4(0.0); - vec4 newNormal = vec4(0.0); + vec4 newPos = vec4(0.0,0.0,0.0,0.0); + vec4 newNormal = vec4(0.0,0.0,0.0,0.0); //for (float i = 1.0; i < 2.0; i += 1.0){ mat4 skinMat = m_BoneMatrices[int(index.x)]; diff --git a/src/MatDefs/pmd/pmd_no_skinning.j3md b/src/MatDefs/pmd/pmd_no_skinning.j3md index 322d56d76..1b29e3c26 100755 --- a/src/MatDefs/pmd/pmd_no_skinning.j3md +++ b/src/MatDefs/pmd/pmd_no_skinning.j3md @@ -35,7 +35,7 @@ MaterialDef pmd { Boolean WardIso // Use vertex color as an additional diffuse color. - Boolean UseVertexColor + Boolean UseVertexColor : false // Ambient color Color Ambient (MaterialAmbient) diff --git a/src/MatDefs/pmd/pmd_non_adero.frag b/src/MatDefs/pmd/pmd_non_adero.frag new file mode 100644 index 000000000..2c3181f40 --- /dev/null +++ b/src/MatDefs/pmd/pmd_non_adero.frag @@ -0,0 +1,255 @@ +#import "Common/ShaderLib/Optics.glsllib" + +#ifdef SPHERE_MAP_A + uniform sampler2D m_SphereMap_A; +#endif +#ifdef SPHERE_MAP_H + uniform sampler2D m_SphereMap_H; +#endif + + +#define ATTENUATION +//#define HQ_ATTENUATION + + +varying vec2 texCoord; + +varying vec4 AmbientSum; +varying vec4 DiffuseSum; +varying vec4 SpecularSum; + +#ifndef VERTEX_LIGHTING + varying vec3 vPosition; + varying vec3 vViewDir; + varying vec4 vLightDir; +#endif + +#ifdef DIFFUSEMAP + uniform sampler2D m_DiffuseMap; +#endif + +#ifdef SPECULARMAP + uniform sampler2D m_SpecularMap; +#endif + +#ifdef PARALLAXMAP + uniform sampler2D m_ParallaxMap; +#endif + +#ifdef NORMALMAP + uniform sampler2D m_NormalMap; +#else + varying vec3 vNormal; +#endif + +#ifdef ALPHAMAP + uniform sampler2D m_AlphaMap; +#endif + +#ifdef COLORRAMP + uniform sampler2D m_ColorRamp; +#endif +uniform float m_AlphaDiscardThreshold; +#ifndef VERTEX_LIGHTING +uniform float m_Shininess; + +#ifdef HQ_ATTENUATION +uniform vec4 g_LightPosition; +varying vec3 lightVec; +#endif + +#ifdef USE_REFLECTION + uniform float m_ReflectionPower; + uniform float m_ReflectionIntensity; +// varying vec4 refVec; + + uniform ENVMAP m_EnvMap; +#endif + varying vec4 refVec; + +float tangDot(in vec3 v1, in vec3 v2){ + float d = dot(v1,v2); + #ifdef V_TANGENT + d = 1.0 - d*d; + return step(0.0, d) * sqrt(d); + #else + return d; + #endif +} + +float lightComputeDiffuse(in vec3 norm, in vec3 lightdir, in vec3 viewdir){ + #ifdef MINNAERT + float NdotL = max(0.0, dot(norm, lightdir)); + float NdotV = max(0.0, dot(norm, viewdir)); + return NdotL * pow(max(NdotL * NdotV, 0.1), -1.0) * 0.5; + #else + return max(0.0, dot(norm, lightdir)); + #endif +} + +float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){ + #ifdef LOW_QUALITY + // Blinn-Phong + // Note: preferably, H should be computed in the vertex shader + vec3 H = (viewdir + lightdir) * vec3(0.5); + return pow(max(tangDot(H, norm), 0.0), shiny); + #elif defined(WARDISO) + // Isotropic Ward + vec3 halfVec = normalize(viewdir + lightdir); + float NdotH = max(0.001, tangDot(norm, halfVec)); + float NdotV = max(0.001, tangDot(norm, viewdir)); + float NdotL = max(0.001, tangDot(norm, lightdir)); + float a = tan(acos(NdotH)); + float p = max(shiny/128.0, 0.001); + return NdotL * (1.0 / (4.0*3.14159265*p*p)) * (exp(-(a*a)/(p*p)) / (sqrt(NdotV * NdotL))); + #else + // Standard Phong + vec3 R = reflect(-lightdir, norm); + return pow(max(tangDot(R, viewdir), 0.0), shiny); + #endif +} + +vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec3 wvLightDir){ + float diffuseFactor = lightComputeDiffuse(wvNorm, wvLightDir, wvViewDir); + float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, wvLightDir, m_Shininess); + specularFactor *= step(1.0, m_Shininess); + + #ifdef HQ_ATTENUATION + float att = clamp(1.0 - g_LightPosition.w * length(lightVec), 0.0, 1.0); + #else + float att = vLightDir.w; + #endif + + return vec2(diffuseFactor, specularFactor) * vec2(att); +} +#endif +vec2 Optics_SphereCoord2(in vec3 dir){ + float dzplus1 = dir.z + 1.0; + float m = 2.0 * sqrt(dir.x * dir.x + dir.y * dir.y + dzplus1 * dzplus1); + return vec2(dir.x / m + 0.5, dir.y / m + 0.5); +} + +void main(){ + vec2 newTexCoord; + + #if defined(PARALLAXMAP) || defined(NORMALMAP_PARALLAX) + float h; + #ifdef PARALLAXMAP + h = texture2D(m_ParallaxMap, texCoord).r; + #else + h = texture2D(m_NormalMap, texCoord).a; + #endif + float heightScale = 0.05; + float heightBias = heightScale * -0.5; + vec3 normView = normalize(vViewDir); + h = (h * heightScale + heightBias) * normView.z; + newTexCoord = texCoord + (h * -normView.xy); + #else + newTexCoord = texCoord; + #endif + + #ifdef DIFFUSEMAP + vec4 diffuseColor = texture2D(m_DiffuseMap, newTexCoord); + #else + vec4 diffuseColor = vec4(1.0); + #endif + float alpha = DiffuseSum.a * diffuseColor.a; + //float alpha = (DiffuseSum.a + diffuseColor.a)/2; + #ifdef ALPHAMAP + alpha = alpha * texture2D(m_AlphaMap, newTexCoord).r; + #endif + if(alpha < m_AlphaDiscardThreshold){ + discard; + } + + // *********************** + // Read from textures + // *********************** + #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING) + vec4 normalHeight = texture2D(m_NormalMap, newTexCoord); + vec3 normal = (normalHeight.xyz * vec3(2.0) - vec3(1.0)); + #ifdef LATC + normal.z = sqrt(1.0 - (normal.x * normal.x) - (normal.y * normal.y)); + #endif + normal.y = -normal.y; + #elif !defined(VERTEX_LIGHTING) + vec3 normal = vNormal; + #if !defined(LOW_QUALITY) && !defined(V_TANGENT) + normal = normalize(normal); + #endif + #endif + + #ifdef SPECULARMAP + vec4 specularColor = texture2D(m_SpecularMap, newTexCoord); + #else + vec4 specularColor = vec4(1.0); + #endif + + #ifdef VERTEX_LIGHTING + vec2 light = vec2(AmbientSum.a, SpecularSum.a); + #ifdef COLORRAMP + // light.x = texture2D(m_ColorRamp, vec2(light.x, 0.0)).r; + // light.y = texture2D(m_ColorRamp, vec2(light.y, 0.0)).r; + diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light. x)).rgb; + //specularColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light. y)).rgb; + #endif +// adero200 + //if (light.y != light.y) { + // light.y = 0.0; + //} + gl_FragColor = (((AmbientSum + DiffuseSum) * diffuseColor) + + SpecularSum * specularColor * light.y ); + + #else + vec4 lightDir = vLightDir; + lightDir.xyz = normalize(lightDir.xyz); + + vec2 light = computeLighting(vPosition, normal, vViewDir.xyz, lightDir.xyz); + #ifdef COLORRAMP + // diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(light.x, 0.0)).rgb; + // specularColor.rgb *= texture2D(m_ColorRamp, vec2(light.y, 0.0)).rgb; + diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light. x)).rgb; + specularColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light. y)).rgb; + #endif + + // Workaround, since it is not possible to modify varying variables + vec4 SpecularSum2 = SpecularSum; + #ifdef USE_REFLECTION + vec4 refColor = Optics_GetEnvColor(m_EnvMap, refVec.xyz); + + // Interpolate light specularity toward reflection color + // Multiply result by specular map + specularColor = mix(SpecularSum2 * light.y, refColor, refVec.w) * specularColor; + + SpecularSum2 = vec4(1.0); + light.y = 1.0; + #endif +// if (isnan(light.y)) { + if (light.y != light.y) { + light.y = 0.0; + } +// gl_FragColor = (AmbientSum * diffuseColor + +// DiffuseSum * diffuseColor + //* light.x + +// SpecularSum2 * specularColor * light.y ) * 0.8; + vec4 output_color = (((AmbientSum + DiffuseSum) * diffuseColor) + + SpecularSum2 * specularColor * light.y ); +// output_color=vec4(0); +#ifdef SPHERE_MAP_A + vec2 v2 = Optics_SphereCoord(normalize(refVec.xyz)); + v2.y = 1.0 - v2.y; + output_color.xyz += (texture2D(m_SphereMap_A, v2).xyz); + // output_color.xyz = vec3(normalize(refVec.xyz).x); +#endif +#ifdef SPHERE_MAP_H + vec2 v2 = Optics_SphereCoord(normalize(refVec.xyz)); + v2.y = 1.0 - v2.y; + output_color.xyz *= (texture2D(m_SphereMap_H, v2).xyz); +#endif + + #endif + //output_color.a = alpha; + // output_color.a = diffuseColor.a; + + // gl_FragColor = 0.5 + 0.5 * light.x;//output_color; + //gl_FragColor = output_color; +} diff --git a/src/projectkyoto/jme3/mmd/PMDGeometry.java b/src/projectkyoto/jme3/mmd/PMDGeometry.java index 8ae2aaeb9..6995dbc9d 100755 --- a/src/projectkyoto/jme3/mmd/PMDGeometry.java +++ b/src/projectkyoto/jme3/mmd/PMDGeometry.java @@ -29,9 +29,16 @@ */ package projectkyoto.jme3.mmd; +import com.jme3.export.InputCapsule; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.export.OutputCapsule; import com.jme3.material.Material; +import com.jme3.math.Matrix4f; import com.jme3.scene.Geometry; import com.jme3.scene.Mesh; +import com.jme3.scene.VertexBuffer.Type; +import java.io.IOException; import projectkyoto.mmd.file.PMDMaterial; /** @@ -43,7 +50,6 @@ public class PMDGeometry extends Geometry { PMDMaterial pmdMaterial; Material glslSkinningMaterial; Material noSkinningMaterial; - PMDMesh pmdMesh; public PMDGeometry(String name, Mesh mesh) { super(name, mesh); @@ -82,8 +88,43 @@ public class PMDGeometry extends Geometry { @Override public PMDGeometry clone() { + Mesh meshBackup = mesh; + mesh = new Mesh(); PMDGeometry newPMDGeometry = (PMDGeometry)super.clone(false); - newPMDGeometry.setMesh(getMesh().clone()); + mesh = meshBackup; +// newPMDGeometry.setMesh(getMesh().clone()); + if (mesh instanceof PMDSkinMesh) { + PMDSkinMesh oldMesh = (PMDSkinMesh)mesh; + PMDSkinMesh newMesh = new PMDSkinMesh(); + newMesh.boneIndexArray = oldMesh.boneIndexArray; +// newMesh.boneMatrixArray = new Matrix4f[mesh.boneMatrixArray.length]; +// for(int i=0;i 0.99f) { alpha = 1f; @@ -365,7 +382,7 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{ String extToonName = model.getToonTextureList().getToonFileName()[toonIndex]; try { toonTexture = assetManager.loadTexture(folderName + extToonName); - } catch (AssetNotFoundException ex) { + } catch (Exception ex) { String toonname = null; switch (toonIndex) { case 0: @@ -418,7 +435,7 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{ } else { mat.setFloat("EdgeSize", 0f); } -// mat.setParam("VertexLighting", VarType.Int, new Integer(1)); + mat.setParam("VertexLighting", VarType.Boolean, true); // geom.setMaterial(mat); // geom.setPmdMaterial(m); // mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Back); @@ -542,31 +559,51 @@ public class PMDLoaderGLSLSkinning2 implements AssetLoader{ boolean errFlag = false; for(;;) { try { - this.assetManager = ai.getManager(); - model = new PMDModel(ai.openStream()); - folderName = ai.getKey().getFolder(); - meshConverter = new MeshConverter(model); - PMDNode pmdNode = createNode(ai.getKey().getName()); - if (JmeSystem.getFullName().indexOf("Android") == -1) { - try { - String vendor = GL11.glGetString(GL11.GL_VENDOR); - if (vendor != null && vendor.toLowerCase().contains("intel")) { - pmdNode.setGlslSkinning(false); - } else { - pmdNode.setGlslSkinning(true); - } - } catch(Exception ex) { - pmdNode.setGlslSkinning(false); - } - } - return pmdNode; + PMDLoaderGLSLSkinning2 loader = new PMDLoaderGLSLSkinning2(); + return loader.load2(ai); }catch(OutOfMemoryError ex) { if (errFlag) { throw new RuntimeException(ex); } errFlag = true; + if (ai.getManager() instanceof DesktopAssetManager) { + ((DesktopAssetManager)ai.getManager()).clearCache(); + } System.gc(); + System.runFinalization(); } } } + private Object load2(AssetInfo ai) throws IOException { + this.assetManager = ai.getManager(); + model = new PMDModel(ai.openStream()); + folderName = ai.getKey().getFolder(); + meshConverter = new MeshConverter(model); + meshConverter.convertMesh(); + model.setVertexList(null); + model.setFaceVertIndex(null); + PMDNode pmdNode = createNode(ai.getKey().getName()); + if (JmeSystem.getFullName().indexOf("Android") == -1) { + try { + String vendor = GL11.glGetString(GL11.GL_VENDOR); + if (vendor != null && vendor.toLowerCase().contains("intel")) { + pmdNode.setGlslSkinning(false); + } else { + pmdNode.setGlslSkinning(true); + } + } catch(Exception ex) { + pmdNode.setGlslSkinning(false); + } + } + return pmdNode; + } + + public void setFolderName(String folderName) { + this.folderName = folderName; + } + + public String getFolderName() { + return folderName; + } + } diff --git a/src/projectkyoto/jme3/mmd/PMDMesh.java b/src/projectkyoto/jme3/mmd/PMDMesh.java index 8a76d5c35..7b93ec971 100755 --- a/src/projectkyoto/jme3/mmd/PMDMesh.java +++ b/src/projectkyoto/jme3/mmd/PMDMesh.java @@ -31,11 +31,16 @@ package projectkyoto.jme3.mmd; import com.jme3.bounding.BoundingBox; import com.jme3.bounding.BoundingVolume; +import com.jme3.export.InputCapsule; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.export.OutputCapsule; import com.jme3.math.Matrix4f; import com.jme3.math.Vector3f; import com.jme3.scene.Mesh; import com.jme3.scene.VertexBuffer; import com.jme3.util.BufferUtils; +import java.io.IOException; import java.nio.FloatBuffer; /** @@ -80,10 +85,14 @@ public class PMDMesh extends Mesh { @Override public PMDMesh clone() { PMDMesh newMesh = (PMDMesh) super.clone(); + boneMatricesParamIndex = -1; newMesh.boneMatrixArray = new Matrix4f[boneMatrixArray.length]; for (int i = 0; i < newMesh.boneMatrixArray.length; i++) { newMesh.boneMatrixArray[i] = new Matrix4f(); } + newMesh.setBuffer(getBuffer(VertexBuffer.Type.BoneIndex)); + newMesh.setBuffer(getBuffer(VertexBuffer.Type.TexCoord)); + releaseSoftwareSkinningBufferes(); return newMesh; } @@ -150,4 +159,24 @@ public class PMDMesh extends Mesh { clearBuffer(VertexBuffer.Type.Normal); setBuffer(nbBackup); } + + @Override + public void read(JmeImporter im) throws IOException { + super.read(im); + InputCapsule c = im.getCapsule(this); + boneIndexArray = c.readIntArray("boneIndexArray", null); + boneMatrixArray = new Matrix4f[boneIndexArray.length]; + for(int i=0;i)c.readStringSavableMap("skinMap", new HashMap()); + skinBoneWeightArray = c.readFloatArray("skinBoneWeightArray", new float[0]); + skinBoneArray = c.readIntArray("skinBoneArray", new int[0]); + edgeSize = c.readFloat("edgeSize", 1.0f); + int pmdGeometryArrayLength = c.readInt("pmdGeometryArrayLength", 0); + pmdGeometryArray = new PMDGeometry[pmdGeometryArrayLength]; + targets = new PMDMesh[pmdGeometryArrayLength]; + int skinTargetsLength = c.readInt("skinTargetsLength", 0); + skinTargets = new PMDSkinMesh[skinTargetsLength]; + VertexBuffer skinvb = (VertexBuffer)c.readSavable("skinvb", null); + VertexBuffer skinnb = (VertexBuffer)c.readSavable("skinnb", null); + VertexBuffer skintb = (VertexBuffer)c.readSavable("skintb", null); + VertexBuffer skinvb2 = skinvb.clone(); + VertexBuffer skinnb2 = skinnb.clone(); + int meshCount = 0; + int skinMeshCount = 0; + for(Spatial sp : getChildren()) { + Spatial newSp = sp;//.clone(); +// newPMDNode.attachChild(newSp); + if (sp instanceof PMDGeometry) { + Mesh mesh = ((Geometry)newSp).getMesh(); + if (mesh instanceof PMDMesh) { + PMDMesh pmdMesh = (PMDMesh)mesh; + pmdMesh.setVbBackup(pmdMesh.getBuffer(Type.Position)); + pmdMesh.setNbBackup(pmdMesh.getBuffer(Type.Normal)); + pmdGeometryArray[meshCount] = (PMDGeometry)sp; + targets[meshCount++] = (PMDMesh)mesh; + } else if (mesh instanceof PMDSkinMesh) { +// mesh.setMode(Mesh.Mode.Triangles); + PMDSkinMesh skinMesh = (PMDSkinMesh)mesh; + if (skinMeshCount != 0) { + skinMesh.setBuffer(skinvb); + skinMesh.setSkinvb2(skinvb2); + skinMesh.setBuffer(skinnb); + skinMesh.setSkinnb2(skinnb2); + skinMesh.setBuffer(skintb); + } else { + skinMesh.setBuffer(skinvb); + skinMesh.setSkinvb2(skinvb2); + skinMesh.setBuffer(skinnb); + skinMesh.setSkinnb2(skinnb2); + skinMesh.setBuffer(skintb); + } + skinTargets[skinMeshCount++] = (PMDSkinMesh)mesh; + } + } + } + calcOffsetMatrices(); + Savable[] sa = c.readSavableArray("skinArray", new Skin[0]); + skinArray = new Skin[sa.length]; + for(int i=0;i()); + c.write(skinBoneWeightArray, "skinBoneWeightArray", null); + c.write(skinBoneArray, "skinBoneArray", null); + c.write(edgeSize, "edgeSize", 1.0f); + c.write(pmdGeometryArray.length, "pmdGeometryArrayLength",0); + c.write(skinTargets.length, "skinTargetsLength",0); + if (skinTargets != null && skinTargets.length > 0) { + PMDSkinMesh mesh = skinTargets[0]; + c.write(mesh.getSkinvb2(),"skinvb",null); + c.write(mesh.getSkinnb2(),"skinnb",null); + c.write(mesh.getBuffer(Type.TexCoord),"skintb",null); + } + c.write(skinArray, "skinArray", null); + SavableUtil.write(c, skinPosArrayOrig,"skinPosArray"); + SavableUtil.write(c, skinNormalArrayOrig, "skinNormalArray"); + c.write(skinBoneArray, "skinBoneArray", null); + c.write(skinBoneWeightArray, "skinBoneWeightArray", null); + + } + public PMDNode(String name, PMDModel pmdModel, AssetManager assetManager) { super(name); this.pmdModel = pmdModel; @@ -163,7 +285,7 @@ boolean setBoneMatricesFlag = true; // offsetMatrices = skeleton.computeSkinningMatrices(); for(PMDGeometry g : pmdGeometryArray) { Material m = g.getMaterial(); - PMDMesh pmdMesh = g.pmdMesh; + PMDMesh pmdMesh = (PMDMesh)g.getMesh(); int boneIndexArray[] = pmdMesh.getBoneIndexArray(); Matrix4f[] boneMatrixArray = pmdMesh.getBoneMatrixArray(); for (int i = pmdMesh.getBoneIndexArray().length-1; i >=0; i--) { @@ -217,6 +339,9 @@ boolean setBoneMatricesFlag = true; } } private void swapSkinMesh() { + if (skinTargets.length == 0) { + return; + } VertexBuffer vb = skinTargets[0].getBuffer(VertexBuffer.Type.Position); VertexBuffer nb = skinTargets[0].getBuffer(VertexBuffer.Type.Normal); skinTargets[0].skinvb2.setUpdateNeeded(); @@ -328,6 +453,9 @@ boolean setBoneMatricesFlag = true; // mesh.updateBound(); } public void updateSkinBackData() { + if (skinTargets.length == 0) { + return; + } PMDSkinMesh skinMesh = skinTargets[0]; VertexBuffer vb = skinMesh.getSkinvb2(); //.getBuffer(Type.Position); FloatBuffer fvb = (FloatBuffer) vb.getData(); @@ -783,6 +911,11 @@ boolean setBoneMatricesFlag = true; @Override public PMDNode clone() { + Logger.getLogger(this.getClass().getName()).log(Level.INFO,"clone PMDNode "+pmdModel.getModelName()); +// if (true) { +// PMDNode newPMDNode = (PMDNode)super.clone(); +// return newPMDNode; +// } try { PMDNode newPMDNode = (PMDNode)super.clone(); // newPMDNode.pmdModel = pmdModel; @@ -794,6 +927,7 @@ boolean setBoneMatricesFlag = true; newBone.getLocalRotation().set(bone.getLocalRotation()); newBone.getLocalScale().set(bone.getLocalScale()); } + newPMDNode.pmdGeometryArray = new PMDGeometry[pmdGeometryArray.length]; newPMDNode.targets = new PMDMesh[targets.length]; newPMDNode.skinTargets = new PMDSkinMesh[skinTargets.length]; int meshCount=0; @@ -804,9 +938,27 @@ boolean setBoneMatricesFlag = true; if (sp instanceof PMDGeometry) { Mesh mesh = ((Geometry)newSp).getMesh(); if (mesh instanceof PMDMesh) { - pmdGeometryArray[meshCount] = (PMDGeometry)sp; + newPMDNode.pmdGeometryArray[meshCount] = (PMDGeometry)sp; newPMDNode.targets[meshCount++] = (PMDMesh)mesh; } else if (mesh instanceof PMDSkinMesh) { + mesh.setMode(Mesh.Mode.Triangles); + if (skinMeshCount != 0) { + PMDSkinMesh skinMesh = (PMDSkinMesh)mesh; + PMDSkinMesh skinMesh0 = newPMDNode.skinTargets[0]; + skinMesh.setBuffer(skinMesh0.getBuffer(Type.Position)); + skinMesh.setSkinvb2(skinMesh0.getSkinvb2()); + skinMesh.setBuffer(skinMesh0.getBuffer(Type.Normal)); + skinMesh.setSkinnb2(skinMesh0.getSkinnb2()); + skinMesh.setBuffer(skinMesh0.getBuffer(Type.TexCoord)); + } else { + PMDSkinMesh skinMesh = (PMDSkinMesh)mesh; + PMDSkinMesh skinMesh0 = skinTargets[0]; + skinMesh.setBuffer(skinMesh0.getBuffer(Type.Position).clone()); + skinMesh.setSkinvb2(skinMesh0.getSkinvb2().clone()); + skinMesh.setBuffer(skinMesh0.getBuffer(Type.Normal).clone()); + skinMesh.setSkinnb2(skinMesh0.getSkinnb2().clone()); + skinMesh.setBuffer(skinMesh0.getBuffer(Type.TexCoord).clone()); + } newPMDNode.skinTargets[skinMeshCount++] = (PMDSkinMesh)mesh; } } @@ -815,6 +967,7 @@ boolean setBoneMatricesFlag = true; for(String skinName : skinMap.keySet()) { Skin skin = skinMap.get(skinName); skin = skin.clone(); + skin.pmdNode = newPMDNode; newPMDNode.skinMap.put(skinName, skin); } newPMDNode.skinArray = newPMDNode.skinMap.values().toArray(new Skin[newPMDNode.skinMap.size()]); @@ -839,5 +992,16 @@ boolean setBoneMatricesFlag = true; throw new PMDException(ex); } } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + if (pmdModel != null) { + Logger.getLogger(this.getClass().getName()).log(Level.INFO,"finalize PMDNode "+pmdModel.getModelName()); +// System.out.println("finalize PMDNode "+pmdModel.getModelName()); + } else { + Logger.getLogger(this.getClass().getName()).log(Level.INFO,"finalize PMDNode"); + } + } } diff --git a/src/projectkyoto/jme3/mmd/PMDSkinMesh.java b/src/projectkyoto/jme3/mmd/PMDSkinMesh.java index 4e8d504b4..5b26385a1 100755 --- a/src/projectkyoto/jme3/mmd/PMDSkinMesh.java +++ b/src/projectkyoto/jme3/mmd/PMDSkinMesh.java @@ -31,11 +31,15 @@ package projectkyoto.jme3.mmd; import com.jme3.bounding.BoundingBox; import com.jme3.bounding.BoundingVolume; +import com.jme3.export.InputCapsule; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; import com.jme3.math.Matrix4f; import com.jme3.math.Vector3f; import com.jme3.scene.Mesh; import com.jme3.scene.VertexBuffer; import com.jme3.util.BufferUtils; +import java.io.IOException; import java.nio.FloatBuffer; /** @@ -44,7 +48,7 @@ import java.nio.FloatBuffer; */ public class PMDSkinMesh extends Mesh { - short boneIndexArray[]; + int boneIndexArray[]; Matrix4f boneMatrixArray[]; VertexBuffer skinvb2; VertexBuffer skinnb2; @@ -53,11 +57,11 @@ public class PMDSkinMesh extends Mesh { super(); } - public short[] getBoneIndexArray() { + public int[] getBoneIndexArray() { return boneIndexArray; } - public void setBoneIndexArray(short[] boneIndexArray) { + public void setBoneIndexArray(int[] boneIndexArray) { this.boneIndexArray = boneIndexArray; } @@ -119,4 +123,22 @@ public class PMDSkinMesh extends Mesh { return newMesh; } + + @Override + public void read(JmeImporter im) throws IOException { + super.read(im); +// InputCapsule c = im.getCapsule(this); +// boneIndexArray = c.readIntArray("boneIndexArray", null); +// boneMatrixArray = new Matrix4f[boneIndexArray.length]; +// for(int i=0;i=0) { +// System.out.println(bone.getBoneName()+" "+boneEnabled[i]); +// } + } ikControl.setBoneEnabled(boneEnabled); for(int i=pmdNode.getSkeleton().getBoneCount()-1;i>=0;i--) { if (boneEnabled[i] == 1) { @@ -109,6 +147,7 @@ public class VMDControl extends AbstractControl { bone.setUserControl(true); } } + initMotionMap(); } private void initMotionMap() { @@ -148,6 +187,11 @@ public class VMDControl extends AbstractControl { } } } + for(int i=0;i=0;i--) { - if (boneEnabled[i] == 1) { + int i2 = i; //boneEnabled.length -1 - i; + if (boneEnabled[i2] == 1) { + if (!pmdNode.getSkeleton().getBone(i).getName().equals(pmdNode.getPmdModel().getBoneList().getBones()[i2].getBoneName())) { + System.out.println("ERROR "+pmdNode.getSkeleton().getBone(i).getName()+" "+pmdNode.getPmdModel().getBoneList().getBones()[i2].getBoneName()); + } Bone bone = pmdNode.getSkeleton().getBone(i); bone.getLocalRotation().loadIdentity(); } @@ -327,11 +380,17 @@ public class VMDControl extends AbstractControl { float f2 = currentTime - m1.getFrameNo() / 30f; assert (f2 >= 0); float f3 = f2 / f; + assert (f3 >= 0 && f3 <= 1); float fx = IPUtil.calcIp(bml, f3, 0);//calcIp(m2.getInterpolation(), f3, 0); float fy = IPUtil.calcIp(bml, f3, 1); //calcIp(m2.getInterpolation(), f3, 1); float fz = IPUtil.calcIp(bml, f3, 2); //calcIp(m2.getInterpolation(), f3, 2); float fr = IPUtil.calcIp(bml, f3, 3); //calcIp(m2.getInterpolation(), f3, 3); - tmpq1.interpolate(m1.getRotation(), m2.getRotation(), fr); + tmpq4.set(m1.getRotation().x,m1.getRotation().y,m1.getRotation().z,m1.getRotation().w); + tmpq4.normalizeLocal(); + tmpq5.set(m2.getRotation().x,m2.getRotation().y,m2.getRotation().z,m2.getRotation().w); + tmpq5.normalizeLocal(); + tmpq4.slerp(tmpq5, fr); + tmpq1.set(tmpq4.getX(),tmpq4.getY(),tmpq4.getZ(),tmpq4.getW()); tmpp1.x = m1.getLocation().x + (m2.getLocation().x - m1.getLocation().x) * fx; tmpp1.y = m1.getLocation().y + (m2.getLocation().y - m1.getLocation().y) * fy; tmpp1.z = m1.getLocation().z + (m2.getLocation().z - m1.getLocation().z) * fz; diff --git a/src/projectkyoto/jme3/mmd/vmd/VMDControlMT.java b/src/projectkyoto/jme3/mmd/vmd/VMDControlMT.java index 871bd1e57..c8360de5d 100644 --- a/src/projectkyoto/jme3/mmd/vmd/VMDControlMT.java +++ b/src/projectkyoto/jme3/mmd/vmd/VMDControlMT.java @@ -15,6 +15,7 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.logging.Level; import java.util.logging.Logger; import projectkyoto.jme3.mmd.PMDNode; +import projectkyoto.jme3.mmd.nativebullet.PhysicsControl; import projectkyoto.jme3.mmd.vmd.VMDControl; import projectkyoto.mmd.file.PMDModel; import projectkyoto.mmd.file.VMDFile; @@ -35,9 +36,22 @@ public class VMDControlMT extends AbstractControl { callable = new VMDCallable(pmdNode, vmdFile); this.pmdNode = pmdNode; } + public VMDControlMT(ScheduledThreadPoolExecutor executor, PMDNode pmdNode, VMDFile vmdFile, PhysicsControl physicsControl) { + this(executor, pmdNode, vmdFile, physicsControl, true); + } + public VMDControlMT(ScheduledThreadPoolExecutor executor, PMDNode pmdNode, VMDFile vmdFile, PhysicsControl physicsControl, boolean addPmdNodeFlag) { + this.executor = executor; + callable = new VMDCallable(pmdNode, vmdFile, physicsControl, addPmdNodeFlag); + this.pmdNode = pmdNode; + } @Override protected void controlUpdate(float f) { + sync(); + callable.setTpf(f); + future = executor.submit(callable); + } + public synchronized void sync() { if (future != null) { try { future.get(); @@ -51,10 +65,7 @@ public class VMDControlMT extends AbstractControl { future = null; } } - callable.setTpf(f); - future = executor.submit(callable); } - public VMDCallable getCallable() { return callable; } @@ -66,4 +77,22 @@ public class VMDControlMT extends AbstractControl { public Control cloneForSpatial(Spatial sptl) { throw new UnsupportedOperationException("Not supported yet."); } + + @Override + public void setSpatial(Spatial spatial) { + super.setSpatial(spatial); + if (spatial == null) { + Logger.getLogger(VMDControlMT.class.getName()).log(Level.INFO,"remove"); + if (future != null) { + try { + future.get(); + } catch (InterruptedException ex) { + Logger.getLogger(VMDControlMT.class.getName()).log(Level.SEVERE, null, ex); + } catch (ExecutionException ex) { + Logger.getLogger(VMDControlMT.class.getName()).log(Level.SEVERE, null, ex); + } + } +// callable.vmdControl.getPhysicsControl().getWorld().removePMDNode(pmdNode); + } + } } diff --git a/src/projectkyoto/mmd/file/Coords2d.java b/src/projectkyoto/mmd/file/Coords2d.java index aa8b2f959..826f90570 100755 --- a/src/projectkyoto/mmd/file/Coords2d.java +++ b/src/projectkyoto/mmd/file/Coords2d.java @@ -32,12 +32,13 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author Kazuhiko Kobayashi */ -public class Coords2d { +public class Coords2d implements Serializable{ private float u; private float v; diff --git a/src/projectkyoto/mmd/file/PMDBone.java b/src/projectkyoto/mmd/file/PMDBone.java index fb79f948c..bd15c0020 100755 --- a/src/projectkyoto/mmd/file/PMDBone.java +++ b/src/projectkyoto/mmd/file/PMDBone.java @@ -32,13 +32,14 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; import javax.vecmath.Vector3f; /** * * @author Kazuhiko Kobayashi */ -public class PMDBone { +public class PMDBone implements Serializable{ private String boneName; private int parentBoneIndex; diff --git a/src/projectkyoto/mmd/file/PMDBoneDisp.java b/src/projectkyoto/mmd/file/PMDBoneDisp.java index 7fb80e3ee..b0b221d05 100755 --- a/src/projectkyoto/mmd/file/PMDBoneDisp.java +++ b/src/projectkyoto/mmd/file/PMDBoneDisp.java @@ -33,12 +33,13 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author kobayasi */ -public class PMDBoneDisp { +public class PMDBoneDisp implements Serializable{ private int boneIndex; private int boneDispFrameIndex; public PMDBoneDisp(DataInputStreamLittleEndian is) throws IOException { diff --git a/src/projectkyoto/mmd/file/PMDBoneDispList.java b/src/projectkyoto/mmd/file/PMDBoneDispList.java index 474c95623..64c4ab9c6 100755 --- a/src/projectkyoto/mmd/file/PMDBoneDispList.java +++ b/src/projectkyoto/mmd/file/PMDBoneDispList.java @@ -33,12 +33,13 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author kobayasi */ -public class PMDBoneDispList { +public class PMDBoneDispList implements Serializable{ private int boneDispCount; private PMDBoneDisp boneDispArray[]; public PMDBoneDispList(DataInputStreamLittleEndian is) throws IOException { diff --git a/src/projectkyoto/mmd/file/PMDBoneDispNameList.java b/src/projectkyoto/mmd/file/PMDBoneDispNameList.java index 65e5baee9..486a12492 100755 --- a/src/projectkyoto/mmd/file/PMDBoneDispNameList.java +++ b/src/projectkyoto/mmd/file/PMDBoneDispNameList.java @@ -33,12 +33,13 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author kobayasi */ -public class PMDBoneDispNameList { +public class PMDBoneDispNameList implements Serializable{ private int boneDispNameCount; private String[] dispNameArray; public PMDBoneDispNameList(DataInputStreamLittleEndian is) throws IOException { diff --git a/src/projectkyoto/mmd/file/PMDBoneList.java b/src/projectkyoto/mmd/file/PMDBoneList.java index d52ea33b5..2cb95442d 100755 --- a/src/projectkyoto/mmd/file/PMDBoneList.java +++ b/src/projectkyoto/mmd/file/PMDBoneList.java @@ -33,12 +33,13 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author Kazuhiko Kobayashi */ -public class PMDBoneList { +public class PMDBoneList implements Serializable{ private int boneCount; private PMDBone[] bones; public PMDBoneList(DataInputStreamLittleEndian is) throws IOException { diff --git a/src/projectkyoto/mmd/file/PMDHeaderEnglish.java b/src/projectkyoto/mmd/file/PMDHeaderEnglish.java index 17d274b5d..64c0277dc 100755 --- a/src/projectkyoto/mmd/file/PMDHeaderEnglish.java +++ b/src/projectkyoto/mmd/file/PMDHeaderEnglish.java @@ -33,12 +33,13 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author kobayasi */ -public class PMDHeaderEnglish { +public class PMDHeaderEnglish implements Serializable{ private int englishNameCompatibility; private String modelName; diff --git a/src/projectkyoto/mmd/file/PMDIKData.java b/src/projectkyoto/mmd/file/PMDIKData.java index 38ba39bf0..39ad80879 100755 --- a/src/projectkyoto/mmd/file/PMDIKData.java +++ b/src/projectkyoto/mmd/file/PMDIKData.java @@ -33,12 +33,13 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author kobayasi */ -public class PMDIKData { +public class PMDIKData implements Serializable{ private int ikBoneIndex; private int ikTargetBoneIndex; private int ikChainLength; diff --git a/src/projectkyoto/mmd/file/PMDIKList.java b/src/projectkyoto/mmd/file/PMDIKList.java index 540604ee3..a6c8a8421 100755 --- a/src/projectkyoto/mmd/file/PMDIKList.java +++ b/src/projectkyoto/mmd/file/PMDIKList.java @@ -33,12 +33,13 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author kobayasi */ -public class PMDIKList { +public class PMDIKList implements Serializable{ private int ikDataCount; private PMDIKData pmdIKData[]; public PMDIKList(DataInputStreamLittleEndian is) throws IOException { diff --git a/src/projectkyoto/mmd/file/PMDJoint.java b/src/projectkyoto/mmd/file/PMDJoint.java index fae39c54b..da276f1fd 100755 --- a/src/projectkyoto/mmd/file/PMDJoint.java +++ b/src/projectkyoto/mmd/file/PMDJoint.java @@ -32,13 +32,14 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; import javax.vecmath.Vector3f; /** * * @author kobayasi */ -public class PMDJoint { +public class PMDJoint implements Serializable{ private String jointName; private int rigidBodyA; diff --git a/src/projectkyoto/mmd/file/PMDJointList.java b/src/projectkyoto/mmd/file/PMDJointList.java index 1c0136db6..c906c0404 100755 --- a/src/projectkyoto/mmd/file/PMDJointList.java +++ b/src/projectkyoto/mmd/file/PMDJointList.java @@ -33,15 +33,21 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author kobayasi */ -public class PMDJointList { +public class PMDJointList implements Serializable{ private int jointCount; private PMDJoint jointArray[]; + public PMDJointList() { + jointCount = 0; + jointArray = new PMDJoint[0]; + } + public PMDJointList(DataInputStreamLittleEndian is) throws IOException { jointCount = is.readInt(); jointArray = new PMDJoint[jointCount]; diff --git a/src/projectkyoto/mmd/file/PMDMaterial.java b/src/projectkyoto/mmd/file/PMDMaterial.java index ed6a2dc16..42ba691bb 100755 --- a/src/projectkyoto/mmd/file/PMDMaterial.java +++ b/src/projectkyoto/mmd/file/PMDMaterial.java @@ -34,13 +34,14 @@ package projectkyoto.mmd.file; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.Serializable; import java.net.URL; /** * * @author Kazuhiko Kobayashi */ -public class PMDMaterial { +public class PMDMaterial implements Serializable{ private XMaterial material; private byte toonIndex; private byte edgeFlag; diff --git a/src/projectkyoto/mmd/file/PMDModel.java b/src/projectkyoto/mmd/file/PMDModel.java index 0782a1bf4..222ea9d1e 100755 --- a/src/projectkyoto/mmd/file/PMDModel.java +++ b/src/projectkyoto/mmd/file/PMDModel.java @@ -32,13 +32,14 @@ package projectkyoto.mmd.file; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.Serializable; import java.net.URL; /** * * @author Kazuhiko Kobayashi */ -public class PMDModel { +public class PMDModel implements Serializable{ // PMD Header private String id; // char[3] "Pmd" @@ -136,7 +137,9 @@ public class PMDModel { toonTextureList = new PMDToonTextureList(is); rigidBodyList = new PMDRigidBodyList(is); jointList = new PMDJointList(is); - +// toonTextureList = new PMDToonTextureList(); +// rigidBodyList = new PMDRigidBodyList(); +// jointList = new PMDJointList(); } @Override diff --git a/src/projectkyoto/mmd/file/PMDRigidBody.java b/src/projectkyoto/mmd/file/PMDRigidBody.java index 07cfb1d07..d9f1fdbd4 100755 --- a/src/projectkyoto/mmd/file/PMDRigidBody.java +++ b/src/projectkyoto/mmd/file/PMDRigidBody.java @@ -33,13 +33,14 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; import javax.vecmath.Vector3f; /** * * @author kobayasi */ -public class PMDRigidBody { +public class PMDRigidBody implements Serializable{ private String rigidBodyName; private int relBoneIndex; private int rigidBodyGroupIndex; diff --git a/src/projectkyoto/mmd/file/PMDRigidBodyList.java b/src/projectkyoto/mmd/file/PMDRigidBodyList.java index a9444c90c..cc9dbb7ff 100755 --- a/src/projectkyoto/mmd/file/PMDRigidBodyList.java +++ b/src/projectkyoto/mmd/file/PMDRigidBodyList.java @@ -25,16 +25,22 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author kobayasi */ -public class PMDRigidBodyList { +public class PMDRigidBodyList implements Serializable{ private int rigidBodyCount; private PMDRigidBody[] rigidBodyArray; + public PMDRigidBodyList() { + rigidBodyCount = 0; + rigidBodyArray = new PMDRigidBody[0]; + } + public PMDRigidBodyList(DataInputStreamLittleEndian is) throws IOException { rigidBodyCount = is.readInt(); rigidBodyArray = new PMDRigidBody[rigidBodyCount]; diff --git a/src/projectkyoto/mmd/file/PMDSkinData.java b/src/projectkyoto/mmd/file/PMDSkinData.java index ba97d26ea..8b8b4d83d 100755 --- a/src/projectkyoto/mmd/file/PMDSkinData.java +++ b/src/projectkyoto/mmd/file/PMDSkinData.java @@ -33,12 +33,13 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author kobayasi */ -public class PMDSkinData { +public class PMDSkinData implements Serializable{ private String skinName; //20文字 private int skinVertCount; private int skinType; // byte diff --git a/src/projectkyoto/mmd/file/PMDSkinDispList.java b/src/projectkyoto/mmd/file/PMDSkinDispList.java index 78131e1b2..ae5ce3664 100755 --- a/src/projectkyoto/mmd/file/PMDSkinDispList.java +++ b/src/projectkyoto/mmd/file/PMDSkinDispList.java @@ -33,12 +33,13 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author kobayasi */ -public class PMDSkinDispList { +public class PMDSkinDispList implements Serializable{ private int skinDispCount; private short skinIndexArray[]; public PMDSkinDispList(DataInputStreamLittleEndian is) throws IOException { diff --git a/src/projectkyoto/mmd/file/PMDSkinVertData.java b/src/projectkyoto/mmd/file/PMDSkinVertData.java index 4c5cac48b..8e5f2f611 100755 --- a/src/projectkyoto/mmd/file/PMDSkinVertData.java +++ b/src/projectkyoto/mmd/file/PMDSkinVertData.java @@ -33,13 +33,14 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; import javax.vecmath.Vector3f; /** * * @author kobayasi */ -public class PMDSkinVertData { +public class PMDSkinVertData implements Serializable{ private int skinVertIndex; private Vector3f skinVertPos; diff --git a/src/projectkyoto/mmd/file/PMDToonTextureList.java b/src/projectkyoto/mmd/file/PMDToonTextureList.java index 951258f76..6a1d4aff2 100755 --- a/src/projectkyoto/mmd/file/PMDToonTextureList.java +++ b/src/projectkyoto/mmd/file/PMDToonTextureList.java @@ -33,13 +33,21 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author kobayasi */ -public class PMDToonTextureList { +public class PMDToonTextureList implements Serializable{ private String toonFileName[] = new String[10]; + + public PMDToonTextureList() { + for(int i=0;i<10;i++) { + toonFileName[i] = ""; + } + } + public PMDToonTextureList(DataInputStreamLittleEndian is) throws IOException { for(int i=0;i<10;i++) { toonFileName[i] = is.readString(100); diff --git a/src/projectkyoto/mmd/file/PMDVertex.java b/src/projectkyoto/mmd/file/PMDVertex.java index 32f680c71..9acd8c61e 100755 --- a/src/projectkyoto/mmd/file/PMDVertex.java +++ b/src/projectkyoto/mmd/file/PMDVertex.java @@ -33,13 +33,14 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; import javax.vecmath.Vector3f; /** * * @author Kazuhiko Kobayashi */ -public class PMDVertex { +public class PMDVertex implements Serializable{ private Vector3f pos; // 位置 private Vector3f normal; // 法線 diff --git a/src/projectkyoto/mmd/file/VMDFile.java b/src/projectkyoto/mmd/file/VMDFile.java index d5da3684d..c126ba736 100755 --- a/src/projectkyoto/mmd/file/VMDFile.java +++ b/src/projectkyoto/mmd/file/VMDFile.java @@ -35,13 +35,14 @@ package projectkyoto.mmd.file; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.Serializable; import java.net.URL; /** * * @author kobayasi */ -public class VMDFile { +public class VMDFile implements Serializable{ private String vmdHeader; // char[30] Vocaloid Motion Data 0002 private String vmdModelName; // char[20] private int motionCount; diff --git a/src/projectkyoto/mmd/file/VMDMotion.java b/src/projectkyoto/mmd/file/VMDMotion.java index 23005a584..9ca0f51ea 100755 --- a/src/projectkyoto/mmd/file/VMDMotion.java +++ b/src/projectkyoto/mmd/file/VMDMotion.java @@ -33,6 +33,7 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; import javax.vecmath.Point3f; import javax.vecmath.Quat4f; @@ -40,7 +41,7 @@ import javax.vecmath.Quat4f; * * @author kobayasi */ -public class VMDMotion { +public class VMDMotion implements Serializable{ private String boneName; // char[15] private int frameNo; diff --git a/src/projectkyoto/mmd/file/VMDSkin.java b/src/projectkyoto/mmd/file/VMDSkin.java index a43352155..3c5c89f18 100755 --- a/src/projectkyoto/mmd/file/VMDSkin.java +++ b/src/projectkyoto/mmd/file/VMDSkin.java @@ -33,12 +33,13 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author kobayasi */ -public class VMDSkin { +public class VMDSkin implements Serializable{ private String skinName; // char[15] private int flameNo; diff --git a/src/projectkyoto/mmd/file/XColorRGB.java b/src/projectkyoto/mmd/file/XColorRGB.java index f08d0b760..ea020036a 100755 --- a/src/projectkyoto/mmd/file/XColorRGB.java +++ b/src/projectkyoto/mmd/file/XColorRGB.java @@ -33,6 +33,7 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /* * To change this template, choose Tools | Templates @@ -43,7 +44,7 @@ import java.io.IOException; * * @author Kazuhiko Kobayashi */ -public class XColorRGB { +public class XColorRGB implements Serializable{ private float red; private float green; private float blue; diff --git a/src/projectkyoto/mmd/file/XColorRGBA.java b/src/projectkyoto/mmd/file/XColorRGBA.java index 1dfa301bd..40774f1ff 100755 --- a/src/projectkyoto/mmd/file/XColorRGBA.java +++ b/src/projectkyoto/mmd/file/XColorRGBA.java @@ -33,12 +33,13 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author Kazuhiko Kobayashi */ -public class XColorRGBA extends XColorRGB { +public class XColorRGBA extends XColorRGB implements Serializable{ private float alpha; diff --git a/src/projectkyoto/mmd/file/XMaterial.java b/src/projectkyoto/mmd/file/XMaterial.java index 0f932ffea..97b257d3e 100755 --- a/src/projectkyoto/mmd/file/XMaterial.java +++ b/src/projectkyoto/mmd/file/XMaterial.java @@ -33,12 +33,13 @@ package projectkyoto.mmd.file; import java.io.IOException; +import java.io.Serializable; /** * * @author Kazuhiko Kobayashi */ -public class XMaterial { +public class XMaterial implements Serializable{ private XColorRGBA faceColor; private float power; private XColorRGB specularColor; diff --git a/src/projectkyoto/mmd/file/util2/MeshConverter.java b/src/projectkyoto/mmd/file/util2/MeshConverter.java index 637195864..1200470eb 100755 --- a/src/projectkyoto/mmd/file/util2/MeshConverter.java +++ b/src/projectkyoto/mmd/file/util2/MeshConverter.java @@ -32,6 +32,7 @@ package projectkyoto.mmd.file.util2; +import java.io.Serializable; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; @@ -48,10 +49,11 @@ import projectkyoto.mmd.file.PMDVertex; * * @author kobayasi */ -public class MeshConverter { +public class MeshConverter implements Serializable{ PMDModel model; - int maxBoneSize = 20; + public static int DEFAULT_MAX_BONE_SIZE = 20; + int maxBoneSize = DEFAULT_MAX_BONE_SIZE; List meshDataList = new ArrayList(); SkinMeshData skinMeshData; HashMap meshTmpVertMap = new HashMap(); @@ -92,6 +94,7 @@ public class MeshConverter { public void convertMesh() { int faceVertNo = 0; for (int materialNo = 0; materialNo < model.getMaterialCount(); materialNo++) { + meshTmpVertMap.clear(); PMDMaterial material = model.getMaterial()[materialNo]; // find same material MeshData meshData = new MeshData(model, maxBoneSize, material); @@ -131,26 +134,8 @@ public class MeshConverter { meshDataList.remove(meshDataList.size()-1); } } - int vertSizeSum = 0; - int boneSizeSum = 0; - int indexSizeSum = 0; -// System.out.println("material size " + model.getMaterialCount() + " " + meshDataList.size()); - for (MeshData meshData : meshDataList) { - vertSizeSum += meshData.getVertexList().size(); - 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 -// + " vertSizeSum = " + model.getVertCount() + " " + vertSizeSum -// + " boneSizeSum = " + model.getBoneList().getBoneCount() + " " + boneSizeSum); -// printFaceVertSize(); - for(MeshData meshData : meshDataList) { -// meshData.printTrinangles(); - } - System.out.println("meshDataCount = "+meshDataList.size()); + meshTmpVertMap = null; + skinTmpVertMap = null; } void printMeshData(MeshData meshData) { System.out.println("vertSize = " + meshData.getVertexList().size() @@ -222,7 +207,7 @@ public class MeshConverter { } } -class VertIndex { +class VertIndex implements Serializable{ int index; public VertIndex(int index) { diff --git a/src/projectkyoto/mmd/file/util2/SavableUtil.java b/src/projectkyoto/mmd/file/util2/SavableUtil.java new file mode 100644 index 000000000..d59033026 --- /dev/null +++ b/src/projectkyoto/mmd/file/util2/SavableUtil.java @@ -0,0 +1,49 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package projectkyoto.mmd.file.util2; + +import com.jme3.export.InputCapsule; +import com.jme3.export.OutputCapsule; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author kobayasi + */ +public class SavableUtil { + + public static void write(OutputCapsule c, Serializable obj, String name) { + ObjectOutputStream oos = null; + try { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + oos = new ObjectOutputStream(os); + oos.writeObject(obj); + oos.close(); + byte buf[] = os.toByteArray(); + c.write(buf, name, null); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + public static Object read(InputCapsule c, String name, Object defVal) { + try { + byte[] buf = c.readByteArray(name, null); + if (buf != null) { + ObjectInputStream is = new ObjectInputStream(new ByteArrayInputStream(buf)); + return is.readObject(); + } + return defVal; + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/src/projectkyoto/mmd/file/util2/SkinMeshData.java b/src/projectkyoto/mmd/file/util2/SkinMeshData.java index 057579a00..2f2b4b888 100755 --- a/src/projectkyoto/mmd/file/util2/SkinMeshData.java +++ b/src/projectkyoto/mmd/file/util2/SkinMeshData.java @@ -32,6 +32,7 @@ package projectkyoto.mmd.file.util2; +import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -45,7 +46,7 @@ import projectkyoto.mmd.file.PMDVertex; * * @author kobayasi */ -public class SkinMeshData { +public class SkinMeshData implements Serializable{ PMDModel model; List boneList = new ArrayList(); -- 2.11.0