much better implicit IK solver
[carveJwlIkooP6JGAAIwe30JlM.git] / blender_export.py
index d43d4af0d1f236042b04388aa7feaefbf37d8d95..3f2dd793d04ff12d7f8e9091a0189a9d3530cb79 100644 (file)
@@ -143,6 +143,7 @@ class classtype_skin(Structure):
 class classtype_skeleton(Structure):
    _pack_ = 1
    _fields_ = [("channels",c_uint32),
+               ("ik_count",c_uint32),
                ("anim_start",c_uint32),
                ("anim_count",c_uint32)]
 
@@ -150,6 +151,12 @@ class classtype_bone(Structure):
    _pack_ = 1
    _fields_ = [("deform",c_uint32)]
 
+class classtype_ik_bone(Structure):
+   _pack_ = 1
+   _fields_ = [("deform",c_uint32),
+               ("target",c_uint32),
+               ("pole",c_uint32)]
+
 # Exporter
 # ==============================================================================
 
@@ -273,6 +280,7 @@ def write_model(collection_name):
 
             if n.type == 'ARMATURE':
                tree["bones"] = [None] # None is the root transform
+               tree["ik_count"] = 0
 
                def _extendb( p, n, d ):
                   nonlocal tree
@@ -283,13 +291,17 @@ def write_model(collection_name):
                   btree["children"] = []
                   btree["depth"] = d
                   btree["parent"] = p
-
-                  if n.use_deform:
-                     tree["bones"] += [n.name]
+                  tree["bones"] += [n.name]
 
                   for c in n.children:
                      _extendb( btree, c, d+1 )
 
+                  for c in tree['obj'].pose.bones[n.name].constraints:
+                     if c.type == 'IK':
+                        btree["target"] = c.subtarget
+                        btree["pole"] = c.pole_subtarget
+                        tree["ik_count"] += 1
+
                   btree['deform'] = n.use_deform
                   p['children'] += [btree]
 
@@ -359,7 +371,10 @@ def write_model(collection_name):
          node.parent = node_def["parent"]["uid"]
 
       if objt == 'BONE':
-         classtype = 'k_classtype_bone'
+         if 'target' in node_def:
+            classtype = 'k_classtype_ik_bone'
+         else:
+            classtype = 'k_classtype_bone'
       elif objt == 'ARMATURE':
          classtype = 'k_classtype_skeleton'
       else:
@@ -384,6 +399,7 @@ def write_model(collection_name):
             if mod.type == 'ARMATURE':
                classtype = 'k_classtype_skin'
                armature_def = graph_lookup[mod.object]
+               armature_def['obj'].data.pose_position = 'REST'
 
          if can_use_cache and obj.data.name in mesh_cache:
             ref = mesh_cache[obj.data.name]
@@ -564,9 +580,10 @@ def write_model(collection_name):
       s005 = ""
 
       if classtype == 'k_classtype_skin':
+         armature_def['obj'].data.pose_position = 'POSE'
          s005 = F" [armature -> {armature_def['obj'].cv_data.uid}]"
 
-      scmp = F"{s002:<32} {s003:<16} {s004} {s005}"
+      scmp = F"{s002:<32} {s003:<22} {s004} {s005}"
       print( scmp )
       
       if classtype == 'k_classtype_INSTANCE' or \
@@ -595,8 +612,8 @@ def write_model(collection_name):
          armature_def = graph_lookup[obj]
          armature = obj
          bones = armature_def['bones']
-         print( bones )
          skeleton.channels = len(bones)
+         skeleton.ik_count = armature_def["ik_count"]
          
          if armature.animation_data:
             previous_frame = bpy.context.scene.frame_current
@@ -646,9 +663,9 @@ def write_model(collection_name):
                               rq = lc_m.to_quaternion()
 
                               kf = mdl_keyframe()
-                              kf.co[0] =  loc[0]
-                              kf.co[1] =  loc[2]
-                              kf.co[2] = -loc[1]
+                              kf.co[0] =  final_pos[0]
+                              kf.co[1] =  final_pos[1]
+                              kf.co[2] =  final_pos[2]
 
                               kf.q[0] =  rq[1]
                               kf.q[1] =  rq[3]
@@ -680,9 +697,20 @@ def write_model(collection_name):
          entdata_length += sizeof( classtype_bone )
          
          bone = classtype_bone()
-         bone.use_deform = node_def['deform']
+         bone.deform = node_def['deform']
          entdata_buffer += [bone]
 
+      elif classtype == 'k_classtype_ik_bone':
+         node.classtype = 13
+         entdata_length += sizeof( classtype_ik_bone )
+         
+         ikbone = classtype_ik_bone()
+         ikbone.target = armature_def['bones'].index( node_def['target'] )
+         ikbone.pole   = armature_def['bones'].index( node_def['pole'] )
+         ikbone.deform = node_def['deform']
+
+         entdata_buffer += [ikbone]
+
       elif classtype == 'k_classtype_gate':
          node.classtype = 1
          entdata_length += sizeof( classtype_gate )