2 * Copyright (c) 2011 Kazuhiko Kobayashi All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of 'MMDLoaderJME' nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
30 package projectkyoto.jme3.mmd;
32 import com.jme3.animation.Bone;
33 import com.jme3.animation.Skeleton;
34 import com.jme3.asset.AssetInfo;
35 import com.jme3.asset.AssetLoader;
36 import com.jme3.asset.AssetManager;
37 import com.jme3.asset.AssetNotFoundException;
38 import com.jme3.material.Material;
39 import com.jme3.material.RenderState.BlendMode;
40 import com.jme3.material.RenderState.FaceCullMode;
41 import com.jme3.math.ColorRGBA;
42 import com.jme3.math.Matrix4f;
43 import com.jme3.math.Quaternion;
44 import com.jme3.math.Vector3f;
45 import com.jme3.renderer.queue.RenderQueue.Bucket;
46 import com.jme3.scene.Mesh;
47 import com.jme3.scene.Node;
48 import com.jme3.scene.Spatial;
49 import com.jme3.scene.VertexBuffer;
50 import com.jme3.scene.debug.SkeletonPoints;
51 import com.jme3.scene.debug.SkeletonWire;
52 import com.jme3.scene.shape.Box;
53 import com.jme3.shader.VarType;
54 import com.jme3.system.JmeSystem;
55 import com.jme3.texture.Texture;
56 import com.jme3.util.BufferUtils;
57 import com.jme3.util.TempVars;
58 import java.io.IOException;
59 import java.nio.FloatBuffer;
60 import java.nio.ShortBuffer;
61 import java.util.ArrayList;
62 import java.util.List;
63 import java.util.StringTokenizer;
64 import org.lwjgl.opengl.GL11;
65 import projectkyoto.mmd.file.*;
66 import projectkyoto.mmd.file.util2.MeshConverter;
67 import projectkyoto.mmd.file.util2.MeshData;
73 public class PMDLoaderGLSLSkinning2 implements AssetLoader{
77 MeshConverter meshConverter;
79 AssetManager assetManager;
81 List<PMDMesh> meshList = new ArrayList<PMDMesh>();
82 List<PMDSkinMesh> skinMeshList = new ArrayList<PMDSkinMesh>();
89 SkeletonControl skeletonControl;
91 public PMDLoaderGLSLSkinning2() {
93 public PMDLoaderGLSLSkinning2(AssetManager assetManager, PMDModel model) {
94 this.assetManager = assetManager;
96 folderName = "/Model/";
97 // System.out.println("vertexCount = " + model.getVertCount());
98 // System.out.println("faceVertCount = " + model.getFaceVertCount());
99 // assetManager.registerLoader(com.jme3.texture.plugins.AWTLoader.class, "sph", "spa");
104 meshConverter = new MeshConverter(model);
106 // assetManager = null;
107 // folderName = null;
109 skinMeshList.clear();
115 skeletonControl = null;
119 public PMDNode createNode(String name) {
121 node = new PMDNode(name, model, assetManager);
123 meshConverter.convertMesh();
124 // System.out.println("child size = "+node.getChildren().size()+" "+meshList.size()+" "+skinMeshList.size());
125 node.pmdGeometryArray = new PMDGeometry[meshConverter.getMeshDataList().size()];
126 int pmdGeometryIndex = 0;
127 for (MeshData md : meshConverter.getMeshDataList()) {
128 PMDMesh mesh = createMesh(md);
129 PMDGeometry geom = new PMDGeometry("geom" + meshCount++);
131 PMDMaterial pmdMaterial = md.getMaterial();
132 setupMaterial(pmdMaterial, geom);
133 System.out.println(node.attachChild(geom));
135 node.pmdGeometryArray[pmdGeometryIndex++] = geom;
137 createSkinCommonVertData();
138 for (PMDMaterial pmdMaterial : meshConverter.getSkinMeshData().getIndexMap().keySet()) {
139 PMDSkinMesh mesh = createSkinMesh(pmdMaterial);
140 PMDGeometry geom = new PMDGeometry("geom" + meshCount++);
142 setupMaterial(pmdMaterial, geom);
143 System.out.println(node.attachChild(geom));
144 skinMeshList.add(mesh);
146 System.out.println("child size = "+node.getChildren().size()+" "+meshList.size()+" "+skinMeshList.size());
149 node.setSkinData(skinMeshList.toArray(new PMDSkinMesh[skinMeshList.size()]), meshConverter.getSkinMeshData().getVertexList(), skinArray);
150 node.targets = meshList.toArray(new PMDMesh[meshList.size()]);
152 node.calcOffsetMatrices();
157 void createSkinCommonVertData() {
158 skinvb = new VertexBuffer(VertexBuffer.Type.Position);
159 FloatBuffer skinvfb = BufferUtils.createFloatBuffer(meshConverter.getSkinMeshData().getVertexList().size() * 3);
160 skinvb.setupData(VertexBuffer.Usage.Dynamic, 3, VertexBuffer.Format.Float, skinvfb);
162 skinvb2 = new VertexBuffer(VertexBuffer.Type.Position);
163 FloatBuffer skinvfb2 = BufferUtils.createFloatBuffer(meshConverter.getSkinMeshData().getVertexList().size() * 3);
164 skinvb2.setupData(VertexBuffer.Usage.Dynamic, 3, VertexBuffer.Format.Float, skinvfb2);
166 skinnb = new VertexBuffer(VertexBuffer.Type.Normal);
167 FloatBuffer skinnfb = BufferUtils.createFloatBuffer(meshConverter.getSkinMeshData().getVertexList().size() * 3);
168 skinnb.setupData(VertexBuffer.Usage.Dynamic, 3, VertexBuffer.Format.Float, skinnfb);
170 skinnb2 = new VertexBuffer(VertexBuffer.Type.Normal);
171 FloatBuffer skinnfb2 = BufferUtils.createFloatBuffer(meshConverter.getSkinMeshData().getVertexList().size() * 3);
172 skinnb2.setupData(VertexBuffer.Usage.Dynamic, 3, VertexBuffer.Format.Float, skinnfb2);
174 skintb = new VertexBuffer(VertexBuffer.Type.TexCoord);
175 FloatBuffer skintfb = BufferUtils.createFloatBuffer(meshConverter.getSkinMeshData().getVertexList().size() * 2);
176 skintb.setupData(VertexBuffer.Usage.Static, 2, VertexBuffer.Format.Float, skintfb);
177 for (PMDVertex v : meshConverter.getSkinMeshData().getVertexList()) {
178 skinvfb.put(v.getPos().x).put(v.getPos().y).put(v.getPos().z);
179 skinnfb.put(v.getNormal().x).put(v.getNormal().y).put(v.getNormal().z);
180 skintfb.put(v.getUv().getU()).put(1f - v.getUv().getV());
182 skintb.setUpdateNeeded();
185 PMDSkinMesh createSkinMesh(PMDMaterial pmdMaterial) {
186 PMDSkinMesh mesh = new PMDSkinMesh();
187 List<Integer> indexList = meshConverter.getSkinMeshData().getIndexMap().get(pmdMaterial);
188 mesh.setMode(Mesh.Mode.Triangles);
189 mesh.setBuffer(skinvb);
190 mesh.setSkinvb2(skinvb2);
191 mesh.setBuffer(skinnb);
192 mesh.setSkinnb2(skinnb2);
193 mesh.setBuffer(skintb);
194 VertexBuffer ib = new VertexBuffer(VertexBuffer.Type.Index);
195 ShortBuffer isb = BufferUtils.createShortBuffer(indexList.size());
196 for (Integer index : indexList) {
197 isb.put(index.shortValue());
199 ib.setupData(VertexBuffer.Usage.Static, 1, VertexBuffer.Format.UnsignedShort, isb);
204 PMDMesh createMesh(MeshData md) {
205 PMDMesh mesh = new PMDMesh();
206 mesh.setMode(Mesh.Mode.Triangles);
207 VertexBuffer vb = new VertexBuffer(VertexBuffer.Type.Position);
208 FloatBuffer vfb = BufferUtils.createFloatBuffer(md.getVertexList().size() * 3);
209 VertexBuffer nb = new VertexBuffer(VertexBuffer.Type.Normal);
210 FloatBuffer nfb = BufferUtils.createFloatBuffer(md.getVertexList().size() * 3);
212 // VertexBuffer bvb = new VertexBuffer(VertexBuffer.Type.BindPosePosition);
213 // FloatBuffer bvfb = BufferUtils.createFloatBuffer(md.getVertexList().size() * 3);
214 // VertexBuffer bnb = new VertexBuffer(VertexBuffer.Type.BindPoseNormal);
215 // FloatBuffer bnfb = BufferUtils.createFloatBuffer(md.getVertexList().size() * 3);
217 VertexBuffer tb = new VertexBuffer(VertexBuffer.Type.TexCoord);
219 FloatBuffer tfb = BufferUtils.createFloatBuffer(md.getVertexList().size() * 2);
220 VertexBuffer wb = new VertexBuffer(VertexBuffer.Type.BoneWeight);
221 FloatBuffer wfb = BufferUtils.createFloatBuffer(md.getVertexList().size() * 4);
222 VertexBuffer ib = new VertexBuffer(VertexBuffer.Type.Index);
223 ShortBuffer isb = BufferUtils.createShortBuffer(md.getIndexList().size());
224 VertexBuffer bib = new VertexBuffer(VertexBuffer.Type.BoneIndex);
225 ShortBuffer bisb = BufferUtils.createShortBuffer(md.getIndexList().size() * 4);
226 for (PMDVertex v : md.getVertexList()) {
227 vfb.put(v.getPos().x).put(v.getPos().y).put(v.getPos().z);
228 nfb.put(v.getNormal().x).put(v.getNormal().y).put(v.getNormal().z);
230 // bvfb.put(v.getPos().x).put(v.getPos().y).put(v.getPos().z);
231 // bnfb.put(v.getNormal().x).put(v.getNormal().y).put(v.getNormal().z);
233 tfb.put(v.getUv().getU()).put(1f - v.getUv().getV());
234 float weight = (float) v.getBoneWeight() / 100.0f;
235 wfb.put(weight).put(1f - weight).put(0).put(0);
236 bisb.put((short) md.getBoneList().indexOf(v.getBoneNum1())).put((short) md.getBoneList().indexOf(v.getBoneNum2())).put((short) 0).put((short) 0);
238 for (Integer index : md.getIndexList()) {
239 isb.put(index.shortValue());
240 // System.out.println("index = "+index);
242 // System.out.println("isb.capacity() = " + isb.capacity());
243 // System.out.println("isb.capacity() = " + md.getIndexList().size());
244 vb.setupData(VertexBuffer.Usage.Dynamic, 3, VertexBuffer.Format.Float, vfb);
245 nb.setupData(VertexBuffer.Usage.Dynamic, 3, VertexBuffer.Format.Float, nfb);
247 // bvb.setupData(VertexBuffer.Usage.CpuOnly, 3, VertexBuffer.Format.Float, bvfb);
248 // bnb.setupData(VertexBuffer.Usage.CpuOnly, 3, VertexBuffer.Format.Float, bnfb);
250 tb.setupData(VertexBuffer.Usage.Static, 2, VertexBuffer.Format.Float, tfb);
251 wb.setupData(VertexBuffer.Usage.Static, 4, VertexBuffer.Format.Float, wfb);
252 ib.setupData(VertexBuffer.Usage.Static, 1, VertexBuffer.Format.UnsignedShort, isb);
253 bib.setupData(VertexBuffer.Usage.Static, 4, VertexBuffer.Format.Short, bisb);
257 mesh.setVbBackup(vb);
258 mesh.setNbBackup(nb);
260 // mesh.setBuffer(bvb);
261 // mesh.setBuffer(bnb);
267 int[] indexArray = new int[meshConverter.getMaxBoneSize()];
268 for (int i = 0; i < indexArray.length; i++) {
269 if (i < md.getBoneList().size()) {
270 indexArray[i] = md.getBoneList().get(i).shortValue();
275 mesh.setBoneIndexArray(indexArray);
276 mesh.setBoneMatrixArray(new Matrix4f[indexArray.length]);
277 for (int i = 0; i < mesh.getBoneMatrixArray().length; i++) {
278 mesh.getBoneMatrixArray()[i] = new Matrix4f();
279 mesh.getBoneMatrixArray()[i].loadIdentity();
284 void setupMaterial(PMDMaterial m, PMDGeometry geom) {
286 if (geom.getMesh() instanceof PMDSkinMesh) {
287 // mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
288 mat = createMaterial(m, false);
289 geom.setMaterial(mat);
290 geom.setGlslSkinningMaterial(mat);
291 geom.setNoSkinningMaterial(mat);
293 mat = createMaterial(m, true);
294 geom.setMaterial(mat);
295 geom.setGlslSkinningMaterial(mat);
296 mat = createMaterial(m, false);
297 geom.setNoSkinningMaterial(mat);
299 geom.setPmdMaterial(m);
300 if (m.getMaterial().getFaceColor().getAlpha() < 1f) {
301 geom.setQueueBucket(Bucket.Transparent);
303 geom.setQueueBucket(Bucket.Inherit);
307 Material createMaterial(PMDMaterial m, boolean skinning) {
309 if (m.getMaterial().getFaceColor().getAlpha() < 1f) {
311 mat = new Material(assetManager, "MatDefs/pmd/pmd_no_skinning_alpha.j3md");
313 mat = new Material(assetManager, "MatDefs/pmd/pmd_alpha.j3md");
317 mat = new Material(assetManager, "MatDefs/pmd/pmd_no_skinning.j3md");
319 mat = new Material(assetManager, "MatDefs/pmd/pmd.j3md");
322 float alpha = m.getMaterial().getFaceColor().getAlpha();
326 ColorRGBA ambientColor = new ColorRGBA(m.getMaterial().getAmbientColor().getRed(),
327 m.getMaterial().getAmbientColor().getGreen(), m.getMaterial().getAmbientColor().getBlue(), alpha);
328 ColorRGBA diffuseColor = new ColorRGBA(m.getMaterial().getFaceColor().getRed(),
329 m.getMaterial().getFaceColor().getGreen(), m.getMaterial().getFaceColor().getBlue(), alpha);
330 ColorRGBA ambientAndDiffuseColor = ambientColor.add(diffuseColor);
331 ambientAndDiffuseColor.multLocal(0.5f);
332 ambientAndDiffuseColor.a = alpha;
333 mat.setBoolean("UseMaterialColors", true);
334 mat.setColor("Ambient", ambientAndDiffuseColor);
335 mat.setColor("Specular", new ColorRGBA(m.getMaterial().getSpecularColor().getRed(),
336 m.getMaterial().getSpecularColor().getGreen(), m.getMaterial().getSpecularColor().getBlue(), alpha));
337 mat.setColor("Diffuse", ambientAndDiffuseColor);
338 mat.setFloat("Shininess", m.getMaterial().getPower());
339 if (m.getTextureFileName().length() > 0) {
340 StringTokenizer st = new StringTokenizer(m.getTextureFileName(), "*");
341 System.out.println("m.getTextureFileName() = " + m.getTextureFileName());
342 while (st.hasMoreElements()) {
343 String fileName = st.nextToken();
344 System.out.println("fileName = " + fileName);
345 String s = fileName.substring(fileName.indexOf('.') + 1);
346 Texture texture = assetManager.loadTexture(folderName + fileName /*
347 * m.getTextureFileName()
350 if (s.equals("spa")) {
351 texture.setMinFilter(Texture.MinFilter.BilinearNoMipMaps);
352 mat.setTexture("SphereMap_A", texture);
353 } else if (s.equals("sph")) {
354 texture.setMinFilter(Texture.MinFilter.BilinearNoMipMaps);
355 mat.setTexture("SphereMap_H", texture);
357 // texture.setWrap(Texture.WrapMode.Repeat);
358 mat.setTexture("DiffuseMap", texture);
362 int toonIndex = m.getToonIndex();
363 Texture toonTexture = null;
364 if (toonIndex >= 0) {
365 String extToonName = model.getToonTextureList().getToonFileName()[toonIndex];
367 toonTexture = assetManager.loadTexture(folderName + extToonName);
368 } catch (AssetNotFoundException ex) {
369 String toonname = null;
372 toonname = "toon01.bmp";
375 toonname = "toon02.bmp";
378 toonname = "toon03.bmp";
381 toonname = "toon04.bmp";
384 toonname = "toon05.bmp";
387 toonname = "toon06.bmp";
390 toonname = "toon07.bmp";
393 toonname = "toon08.bmp";
396 toonname = "toon09.bmp";
399 toonname = "toon10.bmp";
402 if (toonname != null) {
403 toonTexture = assetManager.loadTexture("toon/" + toonname);
407 if (toonTexture != null) {
408 toonTexture.setWrap(Texture.WrapAxis.S, Texture.WrapMode.EdgeClamp);
409 toonTexture.setWrap(Texture.WrapAxis.T, Texture.WrapMode.EdgeClamp);
410 toonTexture.setMinFilter(Texture.MinFilter.BilinearNoMipMaps);
411 mat.setTexture("ColorRamp", toonTexture);
413 if (m.getEdgeFlag() != 0 /*
414 * && !(geom.getMesh() instanceof PMDSkinMesh)
416 // mat.setFloat("EdgeSize", 0.02f);
417 mat.setFloat("EdgeSize", 0.01f);
419 mat.setFloat("EdgeSize", 0f);
421 // mat.setParam("VertexLighting", VarType.Int, new Integer(1));
422 // geom.setMaterial(mat);
423 // geom.setPmdMaterial(m);
424 // mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Back);
425 // mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Back);
426 // mat.getAdditionalRenderState().setWireframe(true);
427 if (m.getMaterial().getFaceColor().getAlpha() < 1f) {
428 mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
429 mat.getAdditionalRenderState().setAlphaTest(true);
430 // mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Back);
432 mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
433 // mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Back);
434 // mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
435 mat.getAdditionalRenderState().setAlphaTest(true);
440 void createSkeleton() {
441 TempVars temp = TempVars.get();
442 Bone[] boneArray = new Bone[model.getBoneList().getBoneCount()];
444 for (PMDBone pmdBone : model.getBoneList().getBones()) {
445 Bone bone = new Bone(pmdBone.getBoneName());
446 bone.setUserControl(true);
447 Vector3f translation = new Vector3f(pmdBone.getBoneHeadPos().x, pmdBone.getBoneHeadPos().y, pmdBone.getBoneHeadPos().z);
448 Quaternion rotation = new Quaternion();
449 boneArray[boneIndex++] = bone;
452 for (PMDBone pmdBone : model.getBoneList().getBones()) {
453 Bone bone = boneArray[boneIndex];
454 if (pmdBone.getParentBoneIndex() < boneArray.length) {
455 Bone parent = boneArray[pmdBone.getParentBoneIndex()];
456 PMDBone parentPMDBone = model.getBoneList().getBones()[pmdBone.getParentBoneIndex()];
457 parent.addChild(bone);
458 Vector3f v1 = temp.vect1; // new Vector3f();
459 Vector3f v2 = temp.vect2; //new Vector3f();
460 v1.set(pmdBone.getBoneHeadPos().x, pmdBone.getBoneHeadPos().y, pmdBone.getBoneHeadPos().z);
461 v2.set(parentPMDBone.getBoneHeadPos().x, parentPMDBone.getBoneHeadPos().y, parentPMDBone.getBoneHeadPos().z);
462 v1.subtractLocal(v2);
464 bone.setBindTransforms(v1, Quaternion.IDENTITY, new Vector3f(1, 1, 1));
466 Vector3f v1 = temp.vect1; //new Vector3f();
467 v1.set(pmdBone.getBoneHeadPos().x, pmdBone.getBoneHeadPos().y, pmdBone.getBoneHeadPos().z);
468 bone.setBindTransforms(v1, Quaternion.IDENTITY, new Vector3f(1, 1, 1));
474 Skeleton skeleton = new Skeleton(boneArray);
475 PMDMesh meshes[] = meshList.toArray(new PMDMesh[meshList.size()]);
477 Quaternion q = new Quaternion();
478 q = q.fromAngleNormalAxis((float) Math.PI / 8, new Vector3f(0, 0, 1));
479 node.skeleton = skeleton;
483 void createSkinArray() {
484 List<Skin> skinList = new ArrayList<Skin>();
485 for (int i = 0; i < model.getSkinCount(); i++) {
486 PMDSkinData pmdSkinData = model.getSkinData()[i];
487 if (pmdSkinData.getSkinType() != 0) {
488 Skin skin = new Skin(node, pmdSkinData.getSkinName());
489 skin.setSkinData(pmdSkinData);
493 skinArray = skinList.toArray(new Skin[skinList.size()]);
496 public Node createBoneNode() {
497 Node boneNode = new Node("boneMarks");
498 Spatial boneMarkArray[] = new Spatial[model.getBoneList().getBoneCount()];
499 for (int i = 0; i < model.getBoneList().getBoneCount(); i++) {
500 PMDBone bone = model.getBoneList().getBones()[i];
501 PMDGeometry boneMark = new PMDGeometry(bone.getBoneName());
502 Node boneMarkNode = new Node();
503 boneMark.setMesh(new Box(4f, 4f, 0.1f));
504 // boneMark.setLocalTranslation(bone.getBoneHeadPos().x,
505 // bone.getBoneHeadPos().y, bone.getBoneHeadPos().z);
506 // boneMark.move(bone.getBoneHeadPos().x,
507 // bone.getBoneHeadPos().y, bone.getBoneHeadPos().z);
508 boneMarkArray[i] = boneMarkNode;
509 Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
510 mat.setColor("Color", ColorRGBA.Blue);
511 boneMark.setMaterial(mat);
512 boneMarkNode.attachChild(boneMark);
513 // if (bone.getBoneName().contains("目")) {
514 boneNode.attachChild(boneMarkNode);
517 PMDBoneMarkControl bmc = new PMDBoneMarkControl(skeletonControl, boneMarkArray, model.getBoneList().getBones());
518 node.addControl(bmc);
519 PMDGeometry skeletonGeom = new PMDGeometry();
520 SkeletonPoints sp = new SkeletonPoints(skeletonControl.skeleton);
521 skeletonGeom.setMesh(sp);
522 Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
523 mat.setColor("Color", ColorRGBA.Green);
524 mat.getAdditionalRenderState().setDepthTest(false);
525 skeletonGeom.setMaterial(mat);
526 node.attachChild(skeletonGeom);
528 SkeletonWire sw = new SkeletonWire(skeletonControl.skeleton);
529 PMDGeometry skeletonWireGeom = new PMDGeometry("skeletonWire", sw);
530 node.attachChild(skeletonWireGeom);
531 skeletonWireGeom.setMaterial(mat);
541 public Object load(AssetInfo ai) throws IOException {
542 boolean errFlag = false;
545 this.assetManager = ai.getManager();
546 model = new PMDModel(ai.openStream());
547 folderName = ai.getKey().getFolder();
548 meshConverter = new MeshConverter(model);
549 PMDNode pmdNode = createNode(ai.getKey().getName());
550 if (JmeSystem.getFullName().indexOf("Android") == -1) {
552 String vendor = GL11.glGetString(GL11.GL_VENDOR);
553 if (vendor != null && vendor.toLowerCase().contains("intel")) {
554 pmdNode.setGlslSkinning(false);
556 pmdNode.setGlslSkinning(true);
558 } catch(Exception ex) {
559 pmdNode.setGlslSkinning(false);
563 }catch(OutOfMemoryError ex) {
565 throw new RuntimeException(ex);