- elif classtype == 'k_classtype_skeleton':
- node.classtype = 11
- entdata_length += sizeof( classtype_skeleton )
- skeleton = classtype_skeleton()
-
- armature_def = graph_lookup[obj]
- armature = obj
- bones = armature_def['bones']
- skeleton.channels = len(bones)
- skeleton.ik_count = armature_def["ik_count"]
- skeleton.collider_count = armature_def["collider_count"]
-
- if armature.animation_data:
- previous_frame = bpy.context.scene.frame_current
- previous_action = armature.animation_data.action
-
- skeleton.anim_start = len(anim_buffer)
- skeleton.anim_count = 0
-
- for NLALayer in obj.animation_data.nla_tracks:
- for NLAStrip in NLALayer.strips:
- # Use action
- for a in bpy.data.actions:
- if a.name == NLAStrip.name:
- armature.animation_data.action = a
- break
-
- anim_start = int(NLAStrip.action_frame_start)
- anim_end = int(NLAStrip.action_frame_end)
-
- # export strips
- anim = mdl_animation()
- anim.pstr_name = emplace_string( NLAStrip.action.name )
- anim.rate = 30.0
- anim.offset = animdata_length
- anim.length = anim_end-anim_start
-
- # Export the fucking keyframes
- for frame in range(anim_start,anim_end):
- bpy.context.scene.frame_set(frame)
-
- for bone_name in bones:
- for pb in armature.pose.bones:
- if pb.name == bone_name:
- rb = armature.data.bones[ bone_name ]
-
- # relative bone matrix
- if rb.parent is not None:
- offset_mtx = rb.parent.matrix_local
- offset_mtx = offset_mtx.inverted_safe() @ \
- rb.matrix_local
-
- inv_parent = pb.parent.matrix @ offset_mtx
- inv_parent.invert_safe()
- fpm = inv_parent @ pb.matrix
- else:
- bone_mtx = rb.matrix.to_4x4()
- local_inv = rb.matrix_local.inverted_safe()
- fpm = bone_mtx @ local_inv @ pb.matrix
-
- loc, rot, sca = fpm.decompose()
-
- # local position
- final_pos = Vector(( loc[0], loc[2], -loc[1] ))
-
- # rotation
- lc_m = pb.matrix_channel.to_3x3()
- if pb.parent is not None:
- smtx = pb.parent.matrix_channel.to_3x3()
- lc_m = smtx.inverted() @ lc_m
- rq = lc_m.to_quaternion()
-
- kf = mdl_keyframe()
- 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]
- kf.q[2] = -rq[2]
- kf.q[3] = rq[0]
-
- # scale
- kf.s[0] = sca[0]
- kf.s[1] = sca[2]
- kf.s[2] = sca[1]
-
- animdata_buffer += [kf]
- animdata_length += sizeof(mdl_keyframe)
- break
-
- anim_buffer += [anim]
- skeleton.anim_count += 1
-
- s000 = F" [{uid: 3}/{header.node_count-1}]" + " |"*(depth-1)
- print( F"{s000} | *anim: {NLAStrip.action.name}" )
-
- bpy.context.scene.frame_set( previous_frame )
- armature.animation_data.action = previous_action
-
- entdata_buffer += [skeleton]
-
- elif classtype == 'k_classtype_bone':
- node.classtype = 10
- entdata_length += sizeof( classtype_bone )
-
- bone = classtype_bone()
- bone.deform = node_def['deform']
-
- if 'target' in node_def:
- bone.ik_target = armature_def['bones'].index( node_def['target'] )
- bone.ik_pole = armature_def['bones'].index( node_def['pole'] )
- else:
- bone.ik_target = 0
- bone.ik_pole = 0
-
- bone.collider = 1 if obj.cv_data.collider else 0
- if obj.cv_data.collider:
- bone.hitbox[0][0] = obj.cv_data.v0[0]
- bone.hitbox[0][1] = obj.cv_data.v0[2]
- bone.hitbox[0][2] = -obj.cv_data.v1[1]
- bone.hitbox[1][0] = obj.cv_data.v1[0]
- bone.hitbox[1][1] = obj.cv_data.v1[2]
- bone.hitbox[1][2] = -obj.cv_data.v0[1]
- else:
- bone.hitbox[0][0] = 0.0
- bone.hitbox[0][1] = 0.0
- bone.hitbox[0][2] = 0.0
- bone.hitbox[1][0] = 0.0
- bone.hitbox[1][1] = 0.0
- bone.hitbox[1][2] = 0.0
-
- if obj.cv_data.con0:
- bone.use_limits = 1
- bone.angle_limits[0][0] = obj.cv_data.mins[0]
- bone.angle_limits[0][1] = obj.cv_data.mins[2]
- bone.angle_limits[0][2] = -obj.cv_data.maxs[1]
- bone.angle_limits[1][0] = obj.cv_data.maxs[0]
- bone.angle_limits[1][1] = obj.cv_data.maxs[2]
- bone.angle_limits[1][2] = -obj.cv_data.mins[1]
- else:
- bone.use_limits = 0
- bone.angle_limits[0][0] = 0.0
- bone.angle_limits[0][1] = 0.0
- bone.angle_limits[0][2] = 0.0
- bone.angle_limits[1][0] = 0.0
- bone.angle_limits[1][1] = 0.0
- bone.angle_limits[1][2] = 0.0
-
- bone.deform = node_def['deform']
- entdata_buffer += [bone]
-
- elif classtype == 'k_classtype_gate':
- node.classtype = 1
- entdata_length += sizeof( classtype_gate )
-
- gate = classtype_gate()
- gate.target = 0
- if obj.cv_data.target != None:
- gate.target = obj.cv_data.target.cv_data.uid
-
- if obj.type == 'MESH':
- gate.dims[0] = obj.data.cv_data.v0[0]
- gate.dims[1] = obj.data.cv_data.v0[1]
- gate.dims[2] = obj.data.cv_data.v0[2]
- else:
- gate.dims[0] = obj.cv_data.v0[0]
- gate.dims[1] = obj.cv_data.v0[1]
- gate.dims[2] = obj.cv_data.v0[2]