OSDN Git Service

implement IK.
authorousttrue <ousttrue@gmail.com>
Thu, 20 May 2010 01:36:28 +0000 (10:36 +0900)
committerousttrue <ousttrue@gmail.com>
Thu, 20 May 2010 01:36:28 +0000 (10:36 +0900)
swig/blender24/pmd_export.py
swig/blender24/pmd_import.py

index 979f924..5fccc06 100644 (file)
@@ -297,7 +297,9 @@ class OneSkinMesh(object):
 
 
 class Bone(object):
+    __slots__=['index', 'name', 'pos', 'parent_index', 'tail_index', 'type']
     def __init__(self, name, pos):
+        self.index=-1
         self.name=name
         self.pos=[pos.x, pos.y, pos.z]
         self.parent_index=None
@@ -308,10 +310,11 @@ class Bone(object):
         return "<Bone %s>" % self.name
 
 class BoneBuilder(object):
-    __slots__=['bones', 'boneMap']
+    __slots__=['bones', 'boneMap', 'ik_list']
     def __init__(self):
         self.bones=[]
         self.boneMap={}
+        self.ik_list=[]
 
     def build(self, armatureObj):
         if armatureObj:
@@ -320,15 +323,37 @@ class BoneBuilder(object):
                 if not b.parent:
                     # root bone
                     bone=Bone(b.name, b.head['ARMATURESPACE'])
-                    self.addBone(bone)
-                    self.getBone(bone, b)
+                    self.__addBone(bone)
+                    self.__getBone(bone, b)
+
+        pose = armatureObj.getPose()
+        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
+
+    def __boneByName(self, name):
+        return self.bones[self.boneMap[name]]
+                    
+    def __getBone(self, parent, b):
+        if not Blender.Armature.CONNECTED in b.options:
+            #print b, b.options
+            pass
 
-    def getBone(self, parent, b):
         if len(b.children)==0:
             # 末端の非表示ボーン
             bone=Bone(b.name+'_tail', b.tail['ARMATURESPACE'])
             bone.type=7
-            self.addBone(bone)
+            self.__addBone(bone)
             assert(parent)
             bone.parent_index=parent.index
             parent.tail_index=bone.index
@@ -336,14 +361,14 @@ class BoneBuilder(object):
 
         for i, c in enumerate(b.children):
             bone=Bone(c.name, c.head['ARMATURESPACE'])
-            self.addBone(bone)
+            self.__addBone(bone)
             if parent:
                 bone.parent_index=parent.index
                 if i==0:
                     parent.tail_index=bone.index
-            self.getBone(bone, c)
+            self.__getBone(bone, c)
 
-    def addBone(self, bone):
+    def __addBone(self, bone):
         bone.index=len(self.bones)
         self.bones.append(bone)
         self.boneMap[bone.name]=bone.index
index 15efe5c..7ed34b4 100644 (file)
@@ -401,11 +401,13 @@ def importArmature(scene, l):
         if len(ik.children) >= 16:
             print 'over MAX_CHAINLEN', ik, len(ik.children)
             continue
+        # IK solver
         ik_const = p_bone.constraints.append(Blender.Constraint.Type.IKSOLVER)
         ik_const[cSetting.CHAINLEN] = len(ik.children)
         ik_const[cSetting.TARGET] = armature_object
         ik_const[cSetting.BONE] = englishmap.getEnglishBoneName(
                 l.bones[ik.index].getName())
+        # Limit ROT
         lrot_const = p_bone.constraints.append(Blender.Constraint.Type.LIMITROT)
         lrot_const.influence = ik.weight
         lrot_const[cSetting.OWNERSPACE] = cSetting.SPACE_LOCAL