def create_key(cls, name): assert len(name) > 4 s = name.split('_', 1) assert len(s[0]) >= 1 flags = { 'b': 0x01, 'p': 0x02, 'c': 0x03, 't': 0x04, 'h': 0x05, 'e': 0x06, 'ad': 0x08, 'cd': 0x09, 'al': 0x0A, 'ac': 0x0D, 'cc': 0x0E, 'ah': 0x10, 'ch': 0x11, 'ab': 0x12, 'ar': 0x13 } generic_name = name generic_actor_types = {'a', 'o'} def get_generic_actor_type(s): return 'o' if s == 'o' else 'a' actors = s[0].split('2', 1) mask = 0 xAge = 0 yAge = 0 if actors[0] in flags: xAge = flags[actors[0]] if len(actors) > 1: if not actors[0] in generic_actor_types or not actors[ 1] in generic_actor_types: if actors[1] in flags: yAge = flags[actors[1]] generic_name = '%s2%s_%s' % (get_generic_actor_type( actors[0]), get_generic_actor_type(actors[1]), s[1]) mask = 0x8000 | xAge << 8 | yAge elif not actors[0] in generic_actor_types: generic_name = 'a_' + s[1] mask = 0x8000 | xAge << 8 instance = FNV64.hash(generic_name) instance &= 0x7FFFFFFFFFFFFFFF instance ^= mask << 48 group = 0x48000000 if xAge > 0x06 or yAge > 0x06 else 0 return ResourceKey(cls.ID, group, instance)
def create_key(cls,name): assert len(name) > 4 s = name.split('_',1) assert len(s[0]) >=1 flags = { 'b' : 0x01, 'p' : 0x02, 'c' : 0x03, 't' : 0x04, 'h' : 0x05, 'e' : 0x06, 'ad': 0x08, 'cd': 0x09, 'al': 0x0A, 'ac': 0x0D, 'cc': 0x0E, 'ah': 0x10, 'ch': 0x11, 'ab': 0x12, 'ar': 0x13 } generic_name = name generic_actor_types = {'a','o'} def get_generic_actor_type(s): return 'o' if s == 'o' else 'a' actors = s[0].split('2',1) mask = 0 xAge = 0 yAge = 0 if actors[0] in flags: xAge = flags[actors[0]] if len(actors) >1: if not actors[0] in generic_actor_types or not actors[1] in generic_actor_types: if actors[1] in flags: yAge = flags[actors[1]] generic_name = '%s2%s_%s'% (get_generic_actor_type(actors[0]),get_generic_actor_type(actors[1]),s[1]) mask = 0x8000 | xAge << 8 | yAge elif not actors[0] in generic_actor_types: generic_name = 'a_'+ s[1] mask = 0x8000 | xAge<<8 instance = FNV64.hash(generic_name) instance &=0x7FFFFFFFFFFFFFFF instance ^= mask << 48 group = 0x48000000 if xAge > 0x06 or yAge >0x06 else 0 return ResourceKey(cls.ID,group,instance)
def animate_driver_bones(driver_root): for shape_key in driver_root.children: track_key = FNV64.hash(shape_key.name) & 0xFFFFFFFF print('shape_key %s' % shape_key) print('track_key: %08X' % track_key) if track_key in frame_map: group = action.groups.new(name=shape_key.name) data_path = 'pose.bones["%s"].morph_value' % shape_key.name fcurve = action.fcurves.new(data_path=data_path, index=0) fcurve.group = group frame_indices = sorted(frame_map[track_key].keys()) for frame_index in frame_indices: print('[%i]: %s' % ( frame_index, frame_map[track_key][frame_index]['morph'][0])) val = frame_map[track_key][frame_index]['morph'][0] fcurve.keyframe_points.add(1) fcurve.keyframe_points[-1].co = [frame_index, val]
def animate_driver_bones(driver_root): for shape_key in driver_root.children: track_key = FNV64.hash(shape_key.name) & 0xFFFFFFFF print('shape_key %s' % shape_key) print('track_key: %08X' % track_key) if track_key in frame_map: group = action.groups.new(name=shape_key.name) data_path = 'pose.bones["%s"].morph_value' % shape_key.name fcurve = action.fcurves.new(data_path=data_path, index=0) fcurve.group = group frame_indices = sorted(frame_map[track_key].keys()) for frame_index in frame_indices: print('[%i]: %s' % (frame_index, frame_map[track_key][frame_index]['morph'][0])) val = frame_map[track_key][frame_index]['morph'][0] fcurve.keyframe_points.add(1) fcurve.keyframe_points[-1].co = [frame_index, val]
def save_clip(clip_resource, skeleton, scale=1.0): print(skeleton.name, skeleton.type) clip = clip_resource.clip clip.tracks = [] action = skeleton.animation_data.action clip_resource.actor_name = action.s3py.actor_name clip.name = action.s3py.name clip.source_file_name = action.s3py.source_name clip.max_frame_count = int(action.frame_range[1]) start_time = time.clock() print('Saving CLIP...') track_map = {} used_bones = [] for fcurve in action.fcurves: s = str(fcurve.data_path).split('.') if s[0] != 'pose' or s[1][:5] != 'bones': continue cname = s[1][7:-2] if cname == ROOT_MORPH: continue if cname in skeleton.pose.bones: pose_bone = skeleton.pose.bones[cname] track_key = FNV32.hash(cname) clip_track_key = FNV64.hash( cname) & 0xFFFFFFFF if pose_bone.parent and pose_bone.parent.name == ROOT_MORPH else track_key if not track_key in track_map: track = Track(clip_track_key) used_bones.append(pose_bone) clip.tracks.append(track) track_map[track_key] = track print(list(ub.name for ub in used_bones)) print('%i Frames found in %s' % (int(action.frame_range[1]), action.name)) def write_frame(current_value, track, frame_index): write = False if not any(track.frames): write = True else: last_value = track.frames[-1].data for i in range(len(current_value)): difference = math.fabs(current_value[i] - last_value[i]) if difference > 0.0001: write = True if write: f = Frame() f.frame_index = frame_index f.data = current_value track.frames.append(f) set_context('POSE', skeleton) for frame_index in range(int(action.frame_range[0]), int(action.frame_range[1])): bpy.context.scene.frame_set(frame_index) for pose_bone in used_bones: track_key = FNV32.hash(pose_bone.name) if not track_key in track_map: continue track = track_map[track_key] if pose_bone.parent and pose_bone.parent.name == ROOT_MORPH: if not track.morphs: track.morphs = Curve.create_morph() cur_morph = [pose_bone.morph_value] write_frame(cur_morph, track.morphs, frame_index) continue matrix_parent = Matrix() if not pose_bone.parent else pose_bone.parent.matrix matrix_delta = matrix_parent.inverted() * pose_bone.matrix if not track.orientations: track.orientations = Curve.create_orientation() rotation = quat_xyzw(matrix_delta.to_quaternion()) write_frame(rotation, track.orientations, frame_index) if not track.positions: track.positions = Curve.create_position() translation = matrix_delta.to_translation() # if pose_bone.name == ROOT_BIND: # translation[1] *= scale write_frame(translation, track.positions, frame_index) print('Finished in %.4f sec.' % (time.clock() - start_time))
def save_clip(clip_resource, skeleton, scale=1.0): print(skeleton.name, skeleton.type) clip = clip_resource.clip clip.tracks = [] action = skeleton.animation_data.action clip_resource.actor_name = action.s3py.actor_name clip.name = action.s3py.name clip.source_file_name = action.s3py.source_name clip.max_frame_count = int(action.frame_range[1]) start_time = time.clock() print('Saving CLIP...') track_map = {} used_bones = [] for fcurve in action.fcurves: s = str(fcurve.data_path).split('.') if s[0] != 'pose' or s[1][:5] != 'bones': continue cname = s[1][7:-2] if cname == ROOT_MORPH: continue if cname in skeleton.pose.bones: pose_bone = skeleton.pose.bones[cname] track_key = FNV32.hash(cname) clip_track_key = FNV64.hash( cname ) & 0xFFFFFFFF if pose_bone.parent and pose_bone.parent.name == ROOT_MORPH else track_key if not track_key in track_map: track = Track(clip_track_key) used_bones.append(pose_bone) clip.tracks.append(track) track_map[track_key] = track print(list(ub.name for ub in used_bones)) print('%i Frames found in %s' % (int(action.frame_range[1]), action.name)) def write_frame(current_value, track, frame_index): write = False if not any(track.frames): write = True else: last_value = track.frames[-1].data for i in range(len(current_value)): difference = math.fabs(current_value[i] - last_value[i]) if difference > 0.0001: write = True if write: f = Frame() f.frame_index = frame_index f.data = current_value track.frames.append(f) set_context('POSE', skeleton) for frame_index in range(int(action.frame_range[0]), int(action.frame_range[1])): bpy.context.scene.frame_set(frame_index) for pose_bone in used_bones: track_key = FNV32.hash(pose_bone.name) if not track_key in track_map: continue track = track_map[track_key] if pose_bone.parent and pose_bone.parent.name == ROOT_MORPH: if not track.morphs: track.morphs = Curve.create_morph() cur_morph = [pose_bone.morph_value] write_frame(cur_morph, track.morphs, frame_index) continue matrix_parent = Matrix( ) if not pose_bone.parent else pose_bone.parent.matrix matrix_delta = matrix_parent.inverted() * pose_bone.matrix if not track.orientations: track.orientations = Curve.create_orientation() rotation = quat_xyzw(matrix_delta.to_quaternion()) write_frame(rotation, track.orientations, frame_index) if not track.positions: track.positions = Curve.create_position() translation = matrix_delta.to_translation() # if pose_bone.name == ROOT_BIND: # translation[1] *= scale write_frame(translation, track.positions, frame_index) print('Finished in %.4f sec.' % (time.clock() - start_time))