OSDN Git Service

fix material.
[meshio/meshio.git] / swig / blender24 / pmd_export.py
index 9ce8df2..d70361b 100644 (file)
@@ -172,6 +172,17 @@ class Morph(object):
         self.indices=[]
         self.offsets=[]
 
+
+class IKSolver(object):
+    __slots__=['target', 'effector', 'length', 'iterations', 'weight']
+    def __init__(self, target, effector, length, iterations, weight):
+        self.target=target
+        self.effector=effector
+        self.length=length
+        self.iterations=iterations
+        self.weight=weight
+
+
 class OneSkinMesh(object):
     __slots__=['armatureObj', 'vertexArray', 'morphList']
     def __init__(self, root):
@@ -423,26 +434,45 @@ class BoneBuilder(object):
                     self.__getBone(bone, b)
 
         pose = armatureObj.getPose()
+        cSetting=Blender.Constraint.Settings
         for b in pose.bones.values():
             for c in b.constraints:
                 if c.type==Blender.Constraint.Type.IKSOLVER:
+                    ####################
                     # IK effector
-                    e=b
-                    for i in range(c[Blender.Constraint.Settings.CHAINLEN]):
-                        # IK影響下
-                        self.__boneByName(e.name).type=4
-                        e=e.parent
-                    # IK target
-                    assert(c[Blender.Constraint.Settings.TARGET]==armatureObj)
-                    self.__boneByName(
-                            c[Blender.Constraint.Settings.BONE]).type=2
+                    ####################
                     # IK 接続先
                     link=self.__boneByName(b.name)
                     link_tail=self.bones[link.tail_index]
                     if link_tail.type==7:
-                        # IK接続先
+                        # replace ...先 to IK接続先
                         link_tail.type=6
-                        
+
+                    # IK chain
+                    e=b
+                    chainLength=c[cSetting.CHAINLEN]
+                    for i in range(chainLength):
+                        # IK影響下
+                        self.__boneByName(e.name).type=4
+                        e=e.parent
+
+                    ####################
+                    # IK target
+                    ####################
+                    assert(c[cSetting.TARGET]==armatureObj)
+                    target=self.__boneByName(
+                            c[Blender.Constraint.Settings.BONE])
+                    target.type=2
+
+                    self.ik_list.append(
+                            IKSolver(target, link_tail, chainLength, 
+                                c[cSetting.ITERATIONS], c.influence))
+
+    def getIndex(self, bone):
+        for i, b in enumerate(self.bones):
+            if b==bone:
+                return i
+        assert(false)
 
     def __boneByName(self, name):
         return self.bones[self.boneMap[name]]
@@ -454,7 +484,7 @@ class BoneBuilder(object):
 
         if len(b.children)==0:
             # 末端の非表示ボーン
-            bone=Bone(b.name+'_tail', b.tail['ARMATURESPACE'])
+            bone=Bone(b.name+'_t', b.tail['ARMATURESPACE'])
             bone.type=7
             self.__addBone(bone)
             assert(parent)
@@ -501,21 +531,9 @@ class PmdExporter(object):
         io.comment="blender export"
         io.version=1.0
 
-        # bones
+        # skeleton
         builder=BoneBuilder()
         builder.build(self.oneSkinMesh.armatureObj)
-        for b in builder.bones:
-            bone=io.addBone()
-            bone.name=b.name
-            bone.type=b.type
-            bone.parent_index=b.parent_index if b.parent_index!=None else 0xFFFF
-            bone.tail_index=b.tail_index if b.tail_index!=None else 0
-            # ToDo
-            bone.ik_index=0xFFFF
-            # convert right-handed z-up to left-handed y-up
-            bone.pos.x=b.pos[0]
-            bone.pos.y=b.pos[2]
-            bone.pos.z=b.pos[1]
 
         # 頂点
         for pos, normal, uv, b0, b1, weight in self.oneSkinMesh.vertexArray.zip():
@@ -544,15 +562,16 @@ class PmdExporter(object):
             material.diffuse.g=m.G
             material.diffuse.b=m.B
             material.diffuse.a=m.alpha
-            material.sinness=m.spec
+            material.sinness=0 if m.spec<1e-5 else m.spec*10
             material.specular.r=m.specR
             material.specular.g=m.specG
             material.specular.b=m.specB
-            material.ambient.r=m.amb
-            material.ambient.g=m.amb
-            material.ambient.b=m.amb
+            material.ambient.r=m.mirR
+            material.ambient.g=m.mirG
+            material.ambient.b=m.mirB
             material.vertex_count=len(indices)
             material.toon_index=0
+            material.flag=1 if m.enableSSS else 0
             # ToDo
             material.texture=""
             # 面
@@ -568,17 +587,85 @@ class PmdExporter(object):
                 #io.indices.append(indices[i+1])
                 #io.indices.append(indices[i+2])
 
+        # bones
+        for b in builder.bones:
+            bone=io.addBone()
+
+            unicode=englishmap.getUnicodeBoneName(b.name)
+            if unicode:
+                cp932=unicode.encode('cp932')
+            else:
+                cp932=b.name
+            bone_name="%s\n" % cp932
+            assert(len(bone_name)<20)
+            bone.name=bone_name
+
+            bone_english_name="%s\n" % b.name
+            assert(len(bone_english_name)<20)
+            bone.english_name=bone_english_name
+
+            bone.type=b.type
+            bone.parent_index=b.parent_index if b.parent_index!=None else 0xFFFF
+            bone.tail_index=b.tail_index if b.tail_index!=None else 0
+            # ToDo
+            bone.ik_index=0xFFFF
+            # convert right-handed z-up to left-handed y-up
+            bone.pos.x=b.pos[0]
+            bone.pos.y=b.pos[2]
+            bone.pos.z=b.pos[1]
+
+        # IK
+        for ik in builder.ik_list:
+            solver=io.addIK()
+            solver.index=builder.getIndex(ik.target)
+            solver.target=builder.getIndex(ik.effector)
+            solver.length=ik.length
+            b=builder.bones[ik.effector.parent_index]
+            for i in xrange(solver.length):
+                solver.children.append(builder.getIndex(b))
+                b=builder.bones[b.parent_index]
+            solver.iterations=ik.iterations
+            solver.weight=ik.weight
+
         # 表情
-        for m in self.oneSkinMesh.morphList:
+        for i, m in enumerate(self.oneSkinMesh.morphList):
             # morph
             morph=io.addMorph()
-            morph.name=m.name
+
+            unicode=englishmap.getUnicodeSkinName(m.name)
+            if unicode:
+                cp932=unicode.encode('cp932')
+            else:
+                cp932=m.name
+            morph.name="%s\n" % cp932
+
+            morph.english_name="%s\n" % m.name
             morph.type=m.type
             for index, offset in zip(m.indices, m.offsets):
                 # convert right-handed z-up to left-handed y-up
                 morph.append(index, offset[0], offset[2], offset[1])
             morph.vertex_count=len(m.indices)
 
+            # 表情枠
+            if i>0:
+                io.face_list.append(i)
+
+        # ボーン表示枠
+        boneDisplayName=io.addBoneDisplayName()
+        boneDisplayName.name="bones\n"
+        boneDisplayName.english_name="bones\n"
+        displayIndex=1
+        for i, b in enumerate(builder.bones):
+            if b.type in [6, 7]:
+                io.addBoneDisplay(i, displayIndex)
+
+        # English
+        io.english_name="blender export model"
+        io.english_coment="blender export"
+
+        for i in range(10):
+            io.getToonTexture(i).name="toon%02d.bmp" % i
+
         # 書き込み
         return io.write(path.encode(FS_ENCODING))