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
\r
uniform ENVMAP m_EnvMap;\r
#endif\r
- varying vec4 refVec;\r
\r
float tangDot(in vec3 v1, in vec3 v2){\r
float d = dot(v1,v2);\r
return vec2(diffuseFactor, specularFactor) * vec2(att);\r
}\r
#endif\r
+ varying vec4 refVec;\r
vec2 Optics_SphereCoord2(in vec3 dir){\r
float dzplus1 = dir.z + 1.0;\r
float m = 2.0 * sqrt(dir.x * dir.x + dir.y * dir.y + dzplus1 * dzplus1);\r
#ifdef ALPHAMAP\r
alpha = alpha * texture2D(m_AlphaMap, newTexCoord).r;\r
#endif\r
- if(alpha < m_AlphaDiscardThreshold){\r
+ if(alpha < 0.1 /*m_AlphaDiscardThreshold*/){\r
discard;\r
}\r
\r
#ifdef COLORRAMP\r
// light.x = texture2D(m_ColorRamp, vec2(light.x, 0.0)).r;\r
// light.y = texture2D(m_ColorRamp, vec2(light.y, 0.0)).r;\r
- light.x = texture2D(m_ColorRamp, vec2(0.0,light.x)).r;\r
- light.y = texture2D(m_ColorRamp, vec2(0.0,light.y)).r;\r
+ diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light. x)).rgb;\r
+ //specularColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light. y)).rgb;\r
#endif\r
+// adero200\r
+ //if (light.y != light.y) {\r
+ // light.y = 0.0;\r
+ //}\r
+ vec4 output_color = (((AmbientSum + DiffuseSum) * diffuseColor)\r
+ + SpecularSum * specularColor * light.y );\r
\r
- gl_FragColor = AmbientSum * diffuseColor + \r
- DiffuseSum * diffuseColor * light.x +\r
- SpecularSum * specularColor * light.y;\r
- diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light.x)).rgb;\r
- specularColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light.y)).rgb;\r
- gl_FragColor = AmbientSum * diffuseColor + \r
- DiffuseSum * diffuseColor +\r
- SpecularSum * specularColor ;\r
#else\r
vec4 lightDir = vLightDir;\r
lightDir.xyz = normalize(lightDir.xyz);\r
#endif\r
\r
#endif\r
+#ifdef SPHERE_MAP_A\r
+ vec2 v2 = Optics_SphereCoord(normalize(refVec.xyz));\r
+ v2.y = 1.0 - v2.y;\r
+ output_color.xyz += (texture2D(m_SphereMap_A, v2).xyz);\r
+ // output_color.xyz = vec3(normalize(refVec.xyz).x);\r
+#endif\r
+#ifdef SPHERE_MAP_H\r
+ vec2 v2 = Optics_SphereCoord(normalize(refVec.xyz));\r
+ v2.y = 1.0 - v2.y;\r
+ output_color.xyz *= (texture2D(m_SphereMap_H, v2).xyz);\r
+#endif\r
output_color.a = alpha;\r
- // output_color.a = diffuseColor.a;\r
-\r
- // gl_FragColor = 0.5 + 0.5 * light.x;//output_color;\r
gl_FragColor = output_color;\r
}\r
USE_REFLECTION : EnvMap\r
SPHERE_MAP : SphereMap\r
\r
- // NUM_BONES : NumBones\r
+ NUM_BONES : NumBones\r
USE_HWSKINNING\r
SPHERE_MAP_A : SphereMap_A\r
SPHERE_MAP_H : SphereMap_H\r
USE_REFLECTION : EnvMap\r
SPHERE_MAP : SphereMap\r
\r
- // NUM_BONES : NumBones\r
+ NUM_BONES : NumBones\r
USE_HWSKINNING\r
}\r
RenderState {\r
// #import "MatDefs/pmd/Skinning.glsllib"\r
#ifdef USE_HWSKINNING\r
-uniform mat4 m_BoneMatrices[20];\r
+uniform mat4 m_BoneMatrices[NUM_BONES];\r
#endif\r
#define ATTENUATION\r
// #define HQ_ATTENUATION\r
vec4 index = inBoneIndex;\r
vec4 weight = inBoneWeight;\r
\r
- vec4 newPos = vec4(0.0);\r
- vec4 newNormal = vec4(0.0);\r
+ vec4 newPos = vec4(0.0,0.0,0.0,0.0);\r
+ vec4 newNormal = vec4(0.0,0.0,0.0,0.0);\r
\r
//for (float i = 1.0; i < 2.0; i += 1.0){\r
mat4 skinMat = m_BoneMatrices[int(index.x)];\r
vec2 light = computeLighting(wvPosition, wvNormal, viewDir, wvLightPos);\r
\r
AmbientSum.a = light.x;\r
- SpecularSum.a = light.y;\r
+ SpecularSum.a = light.y * 0.3;\r
#endif\r
\r
#if defined(USE_REFLECTION) || defined(SPHERE_MAP_A) || defined(SPHERE_MAP_H)\r
USE_REFLECTION : EnvMap\r
SPHERE_MAP : SphereMap\r
\r
- // NUM_BONES : NumBones\r
+ NUM_BONES : NumBones\r
USE_HWSKINNING\r
SPHERE_MAP_A : SphereMap_A\r
SPHERE_MAP_H : SphereMap_H\r
#ifdef USE_HWSKINNING\r
-uniform mat4 m_BoneMatrices[20];\r
+uniform mat4 m_BoneMatrices[NUM_BONES];\r
#endif\r
uniform float m_EdgeSize; \r
// #import "MatDefs/pmd/Skinning.glsllib"\r
vec4 index = inBoneIndex;\r
vec4 weight = inBoneWeight;\r
\r
- vec4 newPos = vec4(0.0);\r
- vec4 newNormal = vec4(0.0);\r
+ vec4 newPos = vec4(0.0,0.0,0.0,0.0);\r
+ vec4 newNormal = vec4(0.0,0.0,0.0,0.0);\r
\r
//for (float i = 1.0; i < 2.0; i += 1.0){\r
mat4 skinMat = m_BoneMatrices[int(index.x)];\r
Boolean WardIso\r
\r
// Use vertex color as an additional diffuse color.\r
- Boolean UseVertexColor\r
+ Boolean UseVertexColor : false\r
\r
// Ambient color\r
Color Ambient (MaterialAmbient)\r
--- /dev/null
+#import "Common/ShaderLib/Optics.glsllib"\r
+\r
+#ifdef SPHERE_MAP_A\r
+ uniform sampler2D m_SphereMap_A;\r
+#endif\r
+#ifdef SPHERE_MAP_H\r
+ uniform sampler2D m_SphereMap_H;\r
+#endif\r
+\r
+\r
+#define ATTENUATION\r
+//#define HQ_ATTENUATION\r
+\r
+\r
+varying vec2 texCoord;\r
+\r
+varying vec4 AmbientSum;\r
+varying vec4 DiffuseSum;\r
+varying vec4 SpecularSum;\r
+\r
+#ifndef VERTEX_LIGHTING\r
+ varying vec3 vPosition;\r
+ varying vec3 vViewDir;\r
+ varying vec4 vLightDir;\r
+#endif\r
+\r
+#ifdef DIFFUSEMAP\r
+ uniform sampler2D m_DiffuseMap;\r
+#endif\r
+\r
+#ifdef SPECULARMAP\r
+ uniform sampler2D m_SpecularMap;\r
+#endif\r
+\r
+#ifdef PARALLAXMAP\r
+ uniform sampler2D m_ParallaxMap;\r
+#endif\r
+ \r
+#ifdef NORMALMAP\r
+ uniform sampler2D m_NormalMap;\r
+#else\r
+ varying vec3 vNormal;\r
+#endif\r
+\r
+#ifdef ALPHAMAP\r
+ uniform sampler2D m_AlphaMap;\r
+#endif\r
+\r
+#ifdef COLORRAMP\r
+ uniform sampler2D m_ColorRamp;\r
+#endif\r
+uniform float m_AlphaDiscardThreshold;\r
+#ifndef VERTEX_LIGHTING\r
+uniform float m_Shininess;\r
+\r
+#ifdef HQ_ATTENUATION\r
+uniform vec4 g_LightPosition;\r
+varying vec3 lightVec;\r
+#endif\r
+\r
+#ifdef USE_REFLECTION \r
+ uniform float m_ReflectionPower;\r
+ uniform float m_ReflectionIntensity;\r
+// varying vec4 refVec;\r
+\r
+ uniform ENVMAP m_EnvMap;\r
+#endif\r
+ varying vec4 refVec;\r
+\r
+float tangDot(in vec3 v1, in vec3 v2){\r
+ float d = dot(v1,v2);\r
+ #ifdef V_TANGENT\r
+ d = 1.0 - d*d;\r
+ return step(0.0, d) * sqrt(d);\r
+ #else\r
+ return d;\r
+ #endif\r
+}\r
+\r
+float lightComputeDiffuse(in vec3 norm, in vec3 lightdir, in vec3 viewdir){\r
+ #ifdef MINNAERT\r
+ float NdotL = max(0.0, dot(norm, lightdir));\r
+ float NdotV = max(0.0, dot(norm, viewdir));\r
+ return NdotL * pow(max(NdotL * NdotV, 0.1), -1.0) * 0.5;\r
+ #else\r
+ return max(0.0, dot(norm, lightdir));\r
+ #endif\r
+}\r
+\r
+float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){\r
+ #ifdef LOW_QUALITY\r
+ // Blinn-Phong\r
+ // Note: preferably, H should be computed in the vertex shader\r
+ vec3 H = (viewdir + lightdir) * vec3(0.5);\r
+ return pow(max(tangDot(H, norm), 0.0), shiny);\r
+ #elif defined(WARDISO)\r
+ // Isotropic Ward\r
+ vec3 halfVec = normalize(viewdir + lightdir);\r
+ float NdotH = max(0.001, tangDot(norm, halfVec));\r
+ float NdotV = max(0.001, tangDot(norm, viewdir));\r
+ float NdotL = max(0.001, tangDot(norm, lightdir));\r
+ float a = tan(acos(NdotH));\r
+ float p = max(shiny/128.0, 0.001);\r
+ return NdotL * (1.0 / (4.0*3.14159265*p*p)) * (exp(-(a*a)/(p*p)) / (sqrt(NdotV * NdotL)));\r
+ #else\r
+ // Standard Phong\r
+ vec3 R = reflect(-lightdir, norm);\r
+ return pow(max(tangDot(R, viewdir), 0.0), shiny);\r
+ #endif\r
+}\r
+\r
+vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec3 wvLightDir){\r
+ float diffuseFactor = lightComputeDiffuse(wvNorm, wvLightDir, wvViewDir);\r
+ float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, wvLightDir, m_Shininess);\r
+ specularFactor *= step(1.0, m_Shininess);\r
+\r
+ #ifdef HQ_ATTENUATION\r
+ float att = clamp(1.0 - g_LightPosition.w * length(lightVec), 0.0, 1.0);\r
+ #else\r
+ float att = vLightDir.w;\r
+ #endif\r
+\r
+ return vec2(diffuseFactor, specularFactor) * vec2(att);\r
+}\r
+#endif\r
+vec2 Optics_SphereCoord2(in vec3 dir){\r
+ float dzplus1 = dir.z + 1.0;\r
+ float m = 2.0 * sqrt(dir.x * dir.x + dir.y * dir.y + dzplus1 * dzplus1);\r
+ return vec2(dir.x / m + 0.5, dir.y / m + 0.5);\r
+}\r
+\r
+void main(){\r
+ vec2 newTexCoord;\r
+ \r
+ #if defined(PARALLAXMAP) || defined(NORMALMAP_PARALLAX)\r
+ float h;\r
+ #ifdef PARALLAXMAP\r
+ h = texture2D(m_ParallaxMap, texCoord).r;\r
+ #else\r
+ h = texture2D(m_NormalMap, texCoord).a;\r
+ #endif\r
+ float heightScale = 0.05;\r
+ float heightBias = heightScale * -0.5;\r
+ vec3 normView = normalize(vViewDir);\r
+ h = (h * heightScale + heightBias) * normView.z;\r
+ newTexCoord = texCoord + (h * -normView.xy);\r
+ #else\r
+ newTexCoord = texCoord;\r
+ #endif\r
+ \r
+ #ifdef DIFFUSEMAP\r
+ vec4 diffuseColor = texture2D(m_DiffuseMap, newTexCoord);\r
+ #else\r
+ vec4 diffuseColor = vec4(1.0);\r
+ #endif\r
+ float alpha = DiffuseSum.a * diffuseColor.a;\r
+ //float alpha = (DiffuseSum.a + diffuseColor.a)/2;\r
+ #ifdef ALPHAMAP\r
+ alpha = alpha * texture2D(m_AlphaMap, newTexCoord).r;\r
+ #endif\r
+ if(alpha < m_AlphaDiscardThreshold){\r
+ discard;\r
+ }\r
+\r
+ // ***********************\r
+ // Read from textures\r
+ // ***********************\r
+ #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)\r
+ vec4 normalHeight = texture2D(m_NormalMap, newTexCoord);\r
+ vec3 normal = (normalHeight.xyz * vec3(2.0) - vec3(1.0));\r
+ #ifdef LATC\r
+ normal.z = sqrt(1.0 - (normal.x * normal.x) - (normal.y * normal.y));\r
+ #endif\r
+ normal.y = -normal.y;\r
+ #elif !defined(VERTEX_LIGHTING)\r
+ vec3 normal = vNormal;\r
+ #if !defined(LOW_QUALITY) && !defined(V_TANGENT)\r
+ normal = normalize(normal);\r
+ #endif\r
+ #endif\r
+\r
+ #ifdef SPECULARMAP\r
+ vec4 specularColor = texture2D(m_SpecularMap, newTexCoord);\r
+ #else\r
+ vec4 specularColor = vec4(1.0);\r
+ #endif\r
+\r
+ #ifdef VERTEX_LIGHTING\r
+ vec2 light = vec2(AmbientSum.a, SpecularSum.a);\r
+ #ifdef COLORRAMP\r
+ // light.x = texture2D(m_ColorRamp, vec2(light.x, 0.0)).r;\r
+ // light.y = texture2D(m_ColorRamp, vec2(light.y, 0.0)).r;\r
+ diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light. x)).rgb;\r
+ //specularColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light. y)).rgb;\r
+ #endif\r
+// adero200\r
+ //if (light.y != light.y) {\r
+ // light.y = 0.0;\r
+ //}\r
+ gl_FragColor = (((AmbientSum + DiffuseSum) * diffuseColor)\r
+ + SpecularSum * specularColor * light.y );\r
+\r
+ #else\r
+ vec4 lightDir = vLightDir;\r
+ lightDir.xyz = normalize(lightDir.xyz);\r
+\r
+ vec2 light = computeLighting(vPosition, normal, vViewDir.xyz, lightDir.xyz);\r
+ #ifdef COLORRAMP\r
+ // diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(light.x, 0.0)).rgb;\r
+ // specularColor.rgb *= texture2D(m_ColorRamp, vec2(light.y, 0.0)).rgb;\r
+ diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light. x)).rgb;\r
+ specularColor.rgb *= texture2D(m_ColorRamp, vec2(0.0,light. y)).rgb;\r
+ #endif\r
+\r
+ // Workaround, since it is not possible to modify varying variables\r
+ vec4 SpecularSum2 = SpecularSum;\r
+ #ifdef USE_REFLECTION\r
+ vec4 refColor = Optics_GetEnvColor(m_EnvMap, refVec.xyz);\r
+\r
+ // Interpolate light specularity toward reflection color\r
+ // Multiply result by specular map\r
+ specularColor = mix(SpecularSum2 * light.y, refColor, refVec.w) * specularColor;\r
+\r
+ SpecularSum2 = vec4(1.0);\r
+ light.y = 1.0;\r
+ #endif\r
+// if (isnan(light.y)) {\r
+ if (light.y != light.y) {\r
+ light.y = 0.0;\r
+ }\r
+// gl_FragColor = (AmbientSum * diffuseColor +\r
+// DiffuseSum * diffuseColor + //* light.x +\r
+// SpecularSum2 * specularColor * light.y ) * 0.8;\r
+ vec4 output_color = (((AmbientSum + DiffuseSum) * diffuseColor) +\r
+ SpecularSum2 * specularColor * light.y );\r
+// output_color=vec4(0);\r
+#ifdef SPHERE_MAP_A\r
+ vec2 v2 = Optics_SphereCoord(normalize(refVec.xyz));\r
+ v2.y = 1.0 - v2.y;\r
+ output_color.xyz += (texture2D(m_SphereMap_A, v2).xyz);\r
+ // output_color.xyz = vec3(normalize(refVec.xyz).x);\r
+#endif\r
+#ifdef SPHERE_MAP_H\r
+ vec2 v2 = Optics_SphereCoord(normalize(refVec.xyz));\r
+ v2.y = 1.0 - v2.y;\r
+ output_color.xyz *= (texture2D(m_SphereMap_H, v2).xyz);\r
+#endif\r
+\r
+ #endif\r
+ //output_color.a = alpha;\r
+ // output_color.a = diffuseColor.a;\r
+\r
+ // gl_FragColor = 0.5 + 0.5 * light.x;//output_color;\r
+ //gl_FragColor = output_color;\r
+}\r
*/
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;
/**
PMDMaterial pmdMaterial;
Material glslSkinningMaterial;
Material noSkinningMaterial;
- PMDMesh pmdMesh;
public PMDGeometry(String name, Mesh mesh) {
super(name, mesh);
@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<mesh.boneMatrixArray.length;i++) {
+// newMesh.boneMatrixArray[i] = new Matrix4f();
+// newMesh.boneMatrixArray[i].loadIdentity();
+// }
+ newMesh.bound = oldMesh.bound.clone();
+ newMesh.setBuffer(oldMesh.getBuffer(Type.Index));
+ newPMDGeometry.setMesh(newMesh);
+ } else {
+ PMDMesh oldMesh = (PMDMesh)mesh;
+ PMDMesh newMesh = new PMDMesh();
+ newMesh.boneIndexArray = oldMesh.boneIndexArray;
+ newMesh.boneMatrixArray = new Matrix4f[oldMesh.boneMatrixArray.length];
+ for (int i = 0; i < newMesh.boneMatrixArray.length; i++) {
+ newMesh.boneMatrixArray[i] = new Matrix4f();
+ newMesh.boneMatrixArray[i].set(oldMesh.boneMatrixArray[i]);
+ }
+ newMesh.setMode(Mesh.Mode.Triangles);
+ newMesh.setVbBackup(oldMesh.getVbBackup());
+ newMesh.setNbBackup(oldMesh.getNbBackup());
+ newMesh.setBuffer(oldMesh.getVbBackup());
+ newMesh.setBuffer(oldMesh.getNbBackup());
+ newMesh.setBuffer(oldMesh.getBuffer(Type.Index));
+ newMesh.setBuffer(oldMesh.getBuffer(Type.TexCoord));
+ newMesh.setBuffer(oldMesh.getBuffer(Type.BoneIndex));
+ newMesh.setBuffer(oldMesh.getBuffer(Type.BoneWeight));
+ newPMDGeometry.setMesh(newMesh);
+ }
newPMDGeometry.glslSkinningMaterial = glslSkinningMaterial.clone();
newPMDGeometry.noSkinningMaterial = noSkinningMaterial.clone();
return newPMDGeometry;
return clone();
}
+// @Override
+// public void setMesh(Mesh mesh) {
+// super.setMesh(mesh);
+// if (mesh instanceof PMDMesh) {
+// pmdMesh = (PMDMesh)mesh;
+// }
+// }
+
@Override
- public void setMesh(Mesh mesh) {
- super.setMesh(mesh);
+ public void setMaterial(Material material) {
+ super.setMaterial(material);
if (mesh instanceof PMDMesh) {
- pmdMesh = (PMDMesh)mesh;
+ PMDMesh pmdMesh = (PMDMesh)mesh;
+ pmdMesh.boneMatricesParamIndex = -1;
}
}
+
+ @Override
+ public void read(JmeImporter im) throws IOException {
+ super.read(im);
+ InputCapsule c = im.getCapsule(this);
+ glslSkinningMaterial = (Material)c.readSavable("glslSkinningMaterial", null);
+ noSkinningMaterial = (Material)c.readSavable("noSkinningMaterial", null);
+ }
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule c = ex.getCapsule(this);
+ c.write(glslSkinningMaterial, "glslSkinningMaterial", null);
+ c.write(noSkinningMaterial, "noSkinningMaterial", null);
+ }
}
import com.jme3.asset.AssetLoader;
import com.jme3.asset.AssetManager;
import com.jme3.asset.AssetNotFoundException;
+import com.jme3.asset.DesktopAssetManager;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.material.RenderState.FaceCullMode;
// System.out.println("faceVertCount = " + model.getFaceVertCount());
// assetManager.registerLoader(com.jme3.texture.plugins.AWTLoader.class, "sph", "spa");
}
+ public PMDLoaderGLSLSkinning2(AssetManager assetManager, MeshConverter mc) {
+ this.assetManager = assetManager;
+ this.model = mc.getModel();
+ this.meshConverter = mc;
+ folderName = "/Model/";
+// System.out.println("vertexCount = " + model.getVertCount());
+// System.out.println("faceVertCount = " + model.getFaceVertCount());
+// assetManager.registerLoader(com.jme3.texture.plugins.AWTLoader.class, "sph", "spa");
+ }
public void init() {
// model = null;
node = null;
- meshConverter = new MeshConverter(model);
+ if (meshConverter == null) {
+ meshConverter = new MeshConverter(model);
+ meshConverter.convertMesh();
+ }
meshCount = 1;
// assetManager = null;
// folderName = null;
init();
node = new PMDNode(name, model, assetManager);
meshCount = 1;
- meshConverter.convertMesh();
// System.out.println("child size = "+node.getChildren().size()+" "+meshList.size()+" "+skinMeshList.size());
node.pmdGeometryArray = new PMDGeometry[meshConverter.getMeshDataList().size()];
int pmdGeometryIndex = 0;
- for (MeshData md : meshConverter.getMeshDataList()) {
+ for(int i=0;i<meshConverter.getMeshDataList().size();i++) {
+ MeshData md = meshConverter.getMeshDataList().get(i);
PMDMesh mesh = createMesh(md);
PMDGeometry geom = new PMDGeometry("geom" + meshCount++);
geom.setMesh(mesh);
System.out.println(node.attachChild(geom));
meshList.add(mesh);
node.pmdGeometryArray[pmdGeometryIndex++] = geom;
+ meshConverter.getMeshDataList().set(i, null);
}
createSkinCommonVertData();
for (PMDMaterial pmdMaterial : meshConverter.getSkinMeshData().getIndexMap().keySet()) {
mat = new Material(assetManager, "MatDefs/pmd/pmd.j3md");
}
}
+ if (skinning) {
+ mat.setInt("NumBones", meshConverter.getMaxBoneSize());
+ }
float alpha = m.getMaterial().getFaceColor().getAlpha();
if (alpha > 0.99f) {
alpha = 1f;
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:
} 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);
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;
+ }
+
}
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;
/**
@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;
}
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<boneMatrixArray.length;i++) {
+ boneMatrixArray[i] = new Matrix4f();
+ boneMatrixArray[i].loadIdentity();
+ }
+ }
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+ super.write(ex);
+ OutputCapsule c = ex.getCapsule(this);
+ c.write(boneIndexArray, "boneIndexArray", null);
+ }
+
}
import com.jme3.animation.Bone;
import com.jme3.animation.Skeleton;
import com.jme3.asset.AssetManager;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.export.Savable;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.scene.Spatial;
import com.jme3.scene.VertexBuffer;
import com.jme3.util.TempVars;
+import java.io.IOException;
import java.nio.FloatBuffer;
import projectkyoto.mmd.file.PMDModel;
import com.jme3.scene.VertexBuffer.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import projectkyoto.mmd.file.PMDBone;
import projectkyoto.mmd.file.PMDException;
+import projectkyoto.mmd.file.PMDSkinData;
import projectkyoto.mmd.file.PMDSkinVertData;
import projectkyoto.mmd.file.PMDVertex;
+import projectkyoto.mmd.file.util2.SavableUtil;
/**
*
Node jointNode;
boolean glslSkinning = true;
+ @Override
+ public void read(JmeImporter e) throws IOException {
+ super.read(e);
+ InputCapsule c = e.getCapsule(this);
+ pmdModel = (PMDModel)SavableUtil.read(c, "pmdModel", null);
+ skeleton = (Skeleton)c.readSavable("skeleton", null);
+ skinMap = (Map<String, Skin>)c.readStringSavableMap("skinMap", new HashMap<String, Savable>());
+ 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<sa.length;i++) {
+ Skin skin = (Skin)sa[i];
+ skinArray[i] = skin;
+ skin.pmdNode = this;
+ l2:
+ for(int i2=0;i2<pmdModel.getSkinCount();i2++){
+ if (pmdModel.getSkinData()[i2].getSkinName().equals(skin.getSkinName())) {
+ skin.skinData = pmdModel.getSkinData()[i2];
+ break l2;
+ }
+ }
+ skin.setWeight(0f);
+ skin.setUpdateNeeded(true);
+ skinMap.put(skin.skinName, skin);
+ }
+ skinPosArray = (javax.vecmath.Vector3f[])SavableUtil.read(c, "skinPosArray", null);
+ skinPosArrayOrig = new javax.vecmath.Vector3f[skinPosArray.length];
+ for(int i=0;i<skinPosArray.length;i++) {
+ skinPosArrayOrig[i] = new javax.vecmath.Vector3f(skinPosArray[i]);
+ }
+ skinNormalArray = (javax.vecmath.Vector3f[])SavableUtil.read(c, "skinNormalArray", null);
+ skinNormalArrayOrig = new javax.vecmath.Vector3f[skinNormalArray.length];
+ for(int i=0;i<skinNormalArray.length;i++) {
+ skinNormalArrayOrig[i] = new javax.vecmath.Vector3f(skinNormalArray[i]);
+ }
+ skinBoneArray = c.readIntArray("skinBoneArray", skinBoneArray);
+ skinBoneWeightArray = c.readFloatArray("skinBoneWeightArray", skinBoneWeightArray);
+ }
+
+ @Override
+ public void write(JmeExporter e) throws IOException {
+ super.write(e);
+ OutputCapsule c = e.getCapsule(this);
+ c.write(1, "version", 1);
+ SavableUtil.write(c, pmdModel, "pmdModel");
+ c.write(skeleton, "skeleton", new Skeleton());
+ c.writeStringSavableMap(skinMap, "skinMap", new HashMap<String, Skin>());
+ 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;
// 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--) {
}
}
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();
// 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();
@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;
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;
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;
}
}
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()]);
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");
+ }
+ }
}
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;
/**
*/
public class PMDSkinMesh extends Mesh {
- short boneIndexArray[];
+ int boneIndexArray[];
Matrix4f boneMatrixArray[];
VertexBuffer skinvb2;
VertexBuffer skinnb2;
super();
}
- public short[] getBoneIndexArray() {
+ public int[] getBoneIndexArray() {
return boneIndexArray;
}
- public void setBoneIndexArray(short[] boneIndexArray) {
+ public void setBoneIndexArray(int[] boneIndexArray) {
this.boneIndexArray = boneIndexArray;
}
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<boneMatrixArray.length;i++) {
+// boneMatrixArray[i] = new Matrix4f();
+// boneMatrixArray[i].loadIdentity();
+// }
+ }
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+
+ super.write(ex);
+ }
}
--- /dev/null
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package projectkyoto.jme3.mmd;
+
+import com.jme3.asset.AssetManager;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import projectkyoto.jme3.mmd.PMDLoaderGLSLSkinning2;
+import projectkyoto.jme3.mmd.PMDNode;
+import projectkyoto.mmd.file.PMDModel;
+import projectkyoto.mmd.file.util2.MeshConverter;
+
+/**
+ *
+ * @author kobayasi
+ */
+public class PmdUtil {
+ public static void output(MeshConverter mc) throws IOException {
+ ObjectOutputStream os = new ObjectOutputStream(
+ new BufferedOutputStream(
+ new FileOutputStream("/tmp/out.serial")));
+ os.writeObject(mc);
+ os.close();
+ }
+
+ public static MeshConverter input() throws IOException {
+ ObjectInputStream is = new ObjectInputStream(
+ new BufferedInputStream(
+ new FileInputStream("/tmp/out.serial")));
+ try {
+ return (MeshConverter) is.readObject();
+ } catch (ClassNotFoundException ex) {
+ throw new IOException("class not found.", ex);
+ } finally {
+ is.close();
+ }
+ }
+ public static PMDNode readNode(AssetManager assetManager, String folderName, ObjectInputStream is) {
+ try {
+ MeshConverter mc = (MeshConverter) is.readObject();
+ PMDLoaderGLSLSkinning2 loader = new PMDLoaderGLSLSkinning2(assetManager, mc);
+ loader.setFolderName(folderName);
+ return loader.createNode("model");
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ } catch (ClassNotFoundException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+}
*/
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.export.Savable;
+import java.io.IOException;
import projectkyoto.mmd.file.PMDSkinData;
/**
*
* @author kobayasi
*/
-public class Skin implements Cloneable{
+public class Skin implements Cloneable, Savable{
String skinName;
float weight = 0f;
protected Skin clone() throws CloneNotSupportedException {
return (Skin)super.clone();
}
-
+
+ @Override
+ public void write(JmeExporter ex) throws IOException {
+ OutputCapsule c = ex.getCapsule(this);
+ c.write(skinName, "skinName", "");
+ c.write(weight, "weight", 0f);
+
+ }
+
+ @Override
+ public void read(JmeImporter im) throws IOException {
+ InputCapsule c = im.getCapsule(this);
+ skinName = c.readString("skinName", "");
+ weight = c.readFloat("weight", 0f);
+ }
}
Vector3f targetModelPos = tmpV2.set(ikBone.getModelSpacePosition());
boolean hizaFlag = pmdModel.getBoneList().getBones()[ikData.getIkChildBoneIndex()[boneCount]].isHiza();
if (hizaFlag) {
- hizaIK(ikData);
- break l2;
+ if (ikData.getIkChainLength() < 2) {
+ pmdModel.getBoneList().getBones()[ikData.getIkChildBoneIndex()[boneCount]].setHiza(false);
+ } else {
+ hizaIK(ikData);
+ break l2;
+ }
}
// hizaFlag = false;
// if (hizaFlag)
}
public void removePMDNode(PMDNode pmdNode) {
- PMDRigidBody[] rigidBodyArray = rigidBodyMap.remove(pmdNode);
- if (rigidBodyArray != null) {
- for (PMDRigidBody rb : rigidBodyArray) {
- physicsSpace.remove(rb);
- }
- }
SixDofJoint[] constArray = constraintMap.remove(pmdNode);
if (constArray != null) {
for (SixDofJoint joint : constArray) {
physicsSpace.remove(joint);
}
}
+ PMDRigidBody[] rigidBodyArray = rigidBodyMap.remove(pmdNode);
+ if (rigidBodyArray != null) {
+ for (PMDRigidBody rb : rigidBodyArray) {
+ physicsSpace.remove(rb);
+ }
+ }
+ nodeRigidBodyArray = rigidBodyMap.values().toArray(new PMDRigidBody[rigidBodyMap.size()][]);
}
float[] buf = new float[3];
} else {
centerFlag = false;
}
+ if (bone != null) {
+ if (!isKinematic()) {
+ bone.setUseModelSpaceVectors(true);
+ }else {
+ bone.setUseModelSpaceVectors(false);
+ }
+ }
}
+ @Override
+ public void setKinematic(boolean kinematic) {
+ super.setKinematic(kinematic);
+ if (bone != null) {
+ if (!isKinematic()) {
+ bone.setUseModelSpaceVectors(true);
+ }else {
+ bone.setUseModelSpaceVectors(false);
+ }
+ }
+ }
+
public void update() {
if (isKinematic()) {
updateFromBoneMatrix();
// System.out.println("updateToBoneMatrix:tmpV = "+tmpV);
// tmpV.addLocal(invPos);
// tmpQ.multLocal(invRot);
+ bone.setUseModelSpaceVectors(false);
+ bone.updateWorldVectors();
+ bone.setUseModelSpaceVectors(true);
m2.toRotationMatrix(tmpMatrix3f);
bone.getModelSpaceRotation().fromRotationMatrix(tmpMatrix3f);
// m2.toRotationQuat(bone.getModelSpaceRotation());
PMDNode pmdNode;
PMDPhysicsWorld world;
-
+ public PhysicsControl() {
+ world = new PMDPhysicsWorld();
+ }
public PhysicsControl(PMDNode pmdNode) {
this.pmdNode = pmdNode;
world = new PMDPhysicsWorld();
-// world.init();
world.addPMDNode(pmdNode);
-// world.stepSimulation(1f);
}
@Override
import java.util.concurrent.Callable;
import projectkyoto.jme3.mmd.PMDNode;
+import projectkyoto.jme3.mmd.nativebullet.PhysicsControl;
import projectkyoto.jme3.mmd.vmd.VMDControl;
import projectkyoto.mmd.file.VMDFile;
this.pmdNode = pmdNode;
vmdControl = new VMDControl(pmdNode, vmdFile);
}
+ public VMDCallable(PMDNode pmdNode, VMDFile vmdFile, PhysicsControl physicsControl, boolean addPmdNodeFlag) {
+ this.pmdNode = pmdNode;
+ vmdControl = new VMDControl(pmdNode, vmdFile, physicsControl, addPmdNodeFlag);
+ }
public Void call() throws Exception {
vmdControl.update(tpf);
float currentTime = 0f;
public VMDControl(PMDNode pmdNode, VMDFile vmdFile) {
+ this(pmdNode, vmdFile, new PhysicsControl());
+ }
+ public VMDControl(PMDNode pmdNode, VMDFile vmdFile, PhysicsControl physicsControl) {
+ this(pmdNode, vmdFile, physicsControl,true);
+ }
+ public VMDControl(PMDNode pmdNode, VMDFile vmdFile, PhysicsControl physicsControl, boolean addPmdNodeFlag) {
this.pmdNode = pmdNode;
this.vmdFile = vmdFile;
- initMotionMap();
- physicsControl = new PhysicsControl(pmdNode);
+ this.physicsControl = physicsControl;
+ if (addPmdNodeFlag) {
+ physicsControl.getWorld().addPMDNode(pmdNode);
+ }
// physicsControl.getWorld().getPhysicsSpace().addTickListener(tl);
ikControl = new IKControl(pmdNode);
boneEnabled = new int[pmdNode.getSkeleton().getBoneCount()];
for(int i=0;i<boneEnabled.length;i++) {
boneEnabled[i] = 1;
}
+ for(projectkyoto.mmd.file.PMDRigidBody rb : pmdNode.getPmdModel().getRigidBodyList().getRigidBodyArray()) {
+ if (rb.getRigidBodyType() != 0 && rb.getRelBoneIndex() != 0xffff) {
+ boneEnabled[rb.getRelBoneIndex()] = 0;
+ }
+ }
+ for(int i=0;i<pmdNode.getPmdModel().getBoneList().getBones().length;i++) {
+ int i2 = i;
+ for(;;) {
+ PMDBone bone = pmdNode.getPmdModel().getBoneList().getBones()[i2];
+ if (bone.getParentBoneIndex() == 0xffff) {
+ break;
+ }
+ if (boneEnabled[i2] == 0) {
+// boneEnabled[i] = 0;
+ break;
+ }
+ i2 = bone.getParentBoneIndex();
+ }
+ }
for (PMDIKData ikData : pmdNode.getPmdModel().getIkList().getPmdIKData()) {
int targetBoneIndex = ikData.getIkTargetBoneIndex();
for(projectkyoto.mmd.file.PMDRigidBody rb : pmdNode.getPmdModel().getRigidBodyList().getRigidBodyArray()) {
- if (rb.getRelBoneIndex() == targetBoneIndex && rb.getRigidBodyType() != 0) {
+ if ((rb.getRelBoneIndex() == targetBoneIndex && rb.getRigidBodyType() != 0)
+ || boneEnabled[targetBoneIndex] == 0) {
boneEnabled[targetBoneIndex] = 0;
+ boneEnabled[ikData.getIkBoneIndex()] = 0;
+ for(int i:ikData.getIkChildBoneIndex()) {
+// boneEnabled[i] = 0;
+ }
break;
}
}
}
+ for(int i=0;i<pmdNode.getPmdModel().getBoneList().getBones().length;i++) {
+ PMDBone bone = pmdNode.getPmdModel().getBoneList().getBones()[i];
+// if (bone.getBoneName().indexOf("胸") >=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) {
bone.setUserControl(true);
}
}
+ initMotionMap();
}
private void initMotionMap() {
}
}
}
+ for(int i=0;i<boneEnabled.length;i++) {
+ if (boneEnabled[i] == 0) {
+ motionMap.remove(pmdNode.getPmdModel().getBoneList().getBones()[i].getBoneName());
+ }
+ }
for (BoneMotionList ml : motionMap.values()) {
Collections.sort(ml, vmc);
ml.setCurrentCount(0);
}
Quat4f tmpq1 = new Quat4f();
Quat4f tmpq2 = new Quat4f();
+ Quat4f tmpq3 = new Quat4f();
+ Quaternion tmpq4 = new Quaternion();
+ Quaternion tmpq5 = new Quaternion();
Point3f tmpp1 = new Point3f();
Point3f tmpp2 = new Point3f();
float prevTpf = 0;
physicsControl.getWorld().getPhysicsSpace().distributeEvents();
needUpdateSkin = true;
}
+// System.out.println("X = "+pmdNode.getSkeleton().getBone("前髪").getModelSpacePosition().getX());
physicsControl.getWorld().applyResultToBone();
+// pmdNode.getSkeleton().updateWorldVectors();
prevTpf = tpf;
if (needUpdateSkin) {
resetSkins();
void calcBonePosition() {
for(int i=pmdNode.getSkeleton().getBoneCount()-1;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();
}
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;
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;
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();
future = null;
}
}
- callable.setTpf(f);
- future = executor.submit(callable);
}
-
public VMDCallable getCallable() {
return callable;
}
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);
+ }
+ }
}
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;
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;
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 {
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 {
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 {
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 {
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;
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;
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 {
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;
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];
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;
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"
toonTextureList = new PMDToonTextureList(is);
rigidBodyList = new PMDRigidBodyList(is);
jointList = new PMDJointList(is);
-
+// toonTextureList = new PMDToonTextureList();
+// rigidBodyList = new PMDRigidBodyList();
+// jointList = new PMDJointList();
}
@Override
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;
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];
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
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 {
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;
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);
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; // 法線
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;
package projectkyoto.mmd.file;
import java.io.IOException;
+import java.io.Serializable;
import javax.vecmath.Point3f;
import javax.vecmath.Quat4f;
*
* @author kobayasi
*/
-public class VMDMotion {
+public class VMDMotion implements Serializable{
private String boneName; // char[15]
private int frameNo;
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;
package projectkyoto.mmd.file;
import java.io.IOException;
+import java.io.Serializable;
/*
* To change this template, choose Tools | Templates
*
* @author Kazuhiko Kobayashi
*/
-public class XColorRGB {
+public class XColorRGB implements Serializable{
private float red;
private float green;
private float blue;
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;
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;
package projectkyoto.mmd.file.util2;
+import java.io.Serializable;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
*
* @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<MeshData> meshDataList = new ArrayList<MeshData>();
SkinMeshData skinMeshData;
HashMap<PMDVertex, Integer> meshTmpVertMap = new HashMap<PMDVertex, Integer>();
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);
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()
}
}
-class VertIndex {
+class VertIndex implements Serializable{
int index;
public VertIndex(int index) {
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
package projectkyoto.mmd.file.util2;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
*
* @author kobayasi
*/
-public class SkinMeshData {
+public class SkinMeshData implements Serializable{
PMDModel model;
List<Integer> boneList = new ArrayList<Integer>();