OSDN Git Service

add jni skinning support
[mikumikustudio/MikuMikuStudio.git] / src / projectkyoto / jme3 / mmd / PMDGeometry.java
1 /*
2  * Copyright (c) 2011 Kazuhiko Kobayashi All rights reserved.
3  * <p/>
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  * 
7  * * Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  * <p/>
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.
13  * <p/>
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.
17  * <p/>
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.
29  */
30 package projectkyoto.jme3.mmd;
31
32 import com.jme3.export.InputCapsule;
33 import com.jme3.export.JmeExporter;
34 import com.jme3.export.JmeImporter;
35 import com.jme3.export.OutputCapsule;
36 import com.jme3.material.Material;
37 import com.jme3.math.Matrix4f;
38 import com.jme3.scene.Geometry;
39 import com.jme3.scene.Mesh;
40 import com.jme3.scene.VertexBuffer.Type;
41 import java.io.IOException;
42 import projectkyoto.mmd.file.PMDMaterial;
43
44 /**
45  *
46  * @author kobayasi
47  */
48 public class PMDGeometry extends Geometry {
49
50     PMDMaterial pmdMaterial;
51     Material glslSkinningMaterial;
52     Material noSkinningMaterial;
53
54     public PMDGeometry(String name, Mesh mesh) {
55         super(name, mesh);
56     }
57
58     public PMDGeometry(String name) {
59         super(name);
60     }
61
62     public PMDGeometry() {
63     }
64
65     public PMDMaterial getPmdMaterial() {
66         return pmdMaterial;
67     }
68
69     public void setPmdMaterial(PMDMaterial pmdMaterial) {
70         this.pmdMaterial = pmdMaterial;
71     }
72
73     public Material getGlslSkinningMaterial() {
74         return glslSkinningMaterial;
75     }
76
77     public void setGlslSkinningMaterial(Material glslSkinningMaterial) {
78         this.glslSkinningMaterial = glslSkinningMaterial;
79     }
80
81     public Material getNoSkinningMaterial() {
82         return noSkinningMaterial;
83     }
84
85     public void setNoSkinningMaterial(Material noSkinningMaterial) {
86         this.noSkinningMaterial = noSkinningMaterial;
87     }
88
89     @Override
90     public PMDGeometry clone() {
91         Mesh meshBackup = mesh;
92         mesh = new Mesh();
93         PMDGeometry newPMDGeometry = (PMDGeometry)super.clone(false);
94         mesh = meshBackup;
95 //        newPMDGeometry.setMesh(getMesh().clone());
96         if (mesh instanceof PMDSkinMesh) {
97             PMDSkinMesh oldMesh = (PMDSkinMesh)mesh;
98             PMDSkinMesh newMesh = new PMDSkinMesh();
99             newMesh.setBuffer(oldMesh.getBuffer(Type.Position));
100             newMesh.setBuffer(oldMesh.getBuffer(Type.Normal));
101             newMesh.setBuffer(oldMesh.getBuffer(Type.BoneIndex));
102             newMesh.setBuffer(oldMesh.getBuffer(Type.BoneWeight));
103             newMesh.boneIndexArray = oldMesh.boneIndexArray;
104             newMesh.boneMatrixArray = new Matrix4f[oldMesh.boneMatrixArray.length];
105             if (oldMesh.getBuffer(Type.TexCoord) != null) {
106                 newMesh.setBuffer(oldMesh.getBuffer(Type.TexCoord));
107             }
108 //            for(int i=0;i<mesh.boneMatrixArray.length;i++) {
109 //                newMesh.boneMatrixArray[i] = new Matrix4f();
110 //                newMesh.boneMatrixArray[i].loadIdentity();
111 //            }
112             newMesh.bound = oldMesh.bound.clone();
113             newMesh.setBuffer(oldMesh.getBuffer(Type.Index));
114             newPMDGeometry.setMesh(newMesh);
115         } else {
116             PMDMesh oldMesh = (PMDMesh)mesh;
117             PMDMesh newMesh = new PMDMesh();
118             newMesh.boneIndexArray = oldMesh.boneIndexArray;
119             newMesh.boneMatrixArray = new Matrix4f[oldMesh.boneMatrixArray.length];
120             for (int i = 0; i < newMesh.boneMatrixArray.length; i++) {
121                 newMesh.boneMatrixArray[i] = new Matrix4f();
122                 newMesh.boneMatrixArray[i].set(oldMesh.boneMatrixArray[i]);
123             }
124             newMesh.setMode(Mesh.Mode.Triangles);
125             newMesh.setVbBackup(oldMesh.getVbBackup());
126             newMesh.setNbBackup(oldMesh.getNbBackup());
127             newMesh.setBuffer(oldMesh.getVbBackup());
128             newMesh.setBuffer(oldMesh.getNbBackup());
129             newMesh.setBuffer(oldMesh.getBuffer(Type.Index));
130             if (oldMesh.getBuffer(Type.TexCoord) != null) {
131                 newMesh.setBuffer(oldMesh.getBuffer(Type.TexCoord));
132             }
133             newMesh.setBuffer(oldMesh.getBuffer(Type.BoneIndex));
134             newMesh.setBuffer(oldMesh.getBuffer(Type.BoneWeight));
135             if (oldMesh.getBuffer(Type.InterleavedData) != null)
136             newMesh.setBuffer(oldMesh.getBuffer(Type.InterleavedData));
137             newPMDGeometry.setMesh(newMesh);
138 //            newMesh.setInterleaved();
139         }
140         newPMDGeometry.glslSkinningMaterial = glslSkinningMaterial.clone();
141         newPMDGeometry.noSkinningMaterial = noSkinningMaterial.clone();
142         return newPMDGeometry;
143     }
144
145     @Override
146     public PMDGeometry clone(boolean cloneMaterial) {
147         return clone();
148     }
149
150 //    @Override
151 //    public void setMesh(Mesh mesh) {
152 //        super.setMesh(mesh);
153 //        if (mesh instanceof PMDMesh) {
154 //            pmdMesh = (PMDMesh)mesh;
155 //        }
156 //    }
157
158     @Override
159     public void setMaterial(Material material) {
160         super.setMaterial(material);
161         if (mesh instanceof PMDMesh) {
162             PMDMesh pmdMesh = (PMDMesh)mesh;
163             pmdMesh.boneMatricesParamIndex = -1;
164         }
165     }
166
167     @Override
168     public void read(JmeImporter im) throws IOException {
169         super.read(im);
170         InputCapsule c = im.getCapsule(this);
171         glslSkinningMaterial = (Material)c.readSavable("glslSkinningMaterial", null);
172         noSkinningMaterial = (Material)c.readSavable("noSkinningMaterial", null);
173     }
174
175     @Override
176     public void write(JmeExporter ex) throws IOException {
177         super.write(ex);
178         OutputCapsule c = ex.getCapsule(this);
179         c.write(glslSkinningMaterial, "glslSkinningMaterial", null);
180         c.write(noSkinningMaterial, "noSkinningMaterial", null);
181     }
182     
183 }