예제 #1
0
 def read_step(self, stream, tgi):
     hash = {}
     while self.read_property(stream, hash, tgi):
         pass
     step = TextureStep.get_step(hash[FNV32.hash('id')])()
     for key in step.params.keys():
         hname = FNV32.hash(key)
         if hname in hash:
             step.params[key] = hash[hname]
     return step
예제 #2
0
 def read_step(self, stream, tgi):
     hash = {}
     while self.read_property(stream, hash, tgi):
         pass
     step = TextureStep.get_step(hash[FNV32.hash('id')])()
     for key in step.params.keys():
         hname = FNV32.hash(key)
         if hname in hash:
             step.params[key] = hash[hname]
     return step
예제 #3
0
def save_bone_delta(skeleton):
    bond = BoneDelta()
    for pose_bone in skeleton.pose.bones:
        if pose_bone.location != Vector(0, 0, 0) or pose_bone.scale != Vector(1, 1,
            1) or pose_bone.rotation_quaternion != Quaternion(1, 0, 0, 0):
            delta = BoneDelta.Delta()
            delta.position = list(pose_bone.location)
            delta.scale = list(pose_bone.scale)
            delta.orientation = list(quat_xyzw(pose_bone.rotation_quaternion))
            bond.deltas[FNV32.hash(pose_bone.name)] = delta
    return bond
예제 #4
0
def load_bone_delta(bond, skeleton):
    assert isinstance(bond, BoneDelta)

    for pose_bone in skeleton.pose.bones:
        hash = FNV32.hash(pose_bone.name)
        if hash in bond.deltas:
            delta = bond.deltas[hash]
            assert isinstance(delta, BoneDelta.Delta)
            pose_bone.scale += Vector(swizzle_v3(delta.scale))
            pose_bone.location += Vector(swizzle_v3(delta.position))
            pose_bone.rotation_quaternion += Quaternion(quat_wxyz(delta.orientation))
예제 #5
0
def save_bone_delta(skeleton):
    bond = BoneDelta()
    for pose_bone in skeleton.pose.bones:
        if pose_bone.location != Vector(0, 0, 0) or pose_bone.scale != Vector(
                1, 1, 1) or pose_bone.rotation_quaternion != Quaternion(
                    1, 0, 0, 0):
            delta = BoneDelta.Delta()
            delta.position = list(pose_bone.location)
            delta.scale = list(pose_bone.scale)
            delta.orientation = list(quat_xyzw(pose_bone.rotation_quaternion))
            bond.deltas[FNV32.hash(pose_bone.name)] = delta
    return bond
예제 #6
0
def load_bone_delta(bond, skeleton):
    assert isinstance(bond, BoneDelta)

    for pose_bone in skeleton.pose.bones:
        hash = FNV32.hash(pose_bone.name)
        if hash in bond.deltas:
            delta = bond.deltas[hash]
            assert isinstance(delta, BoneDelta.Delta)
            pose_bone.scale += Vector(swizzle_v3(delta.scale))
            pose_bone.location += Vector(swizzle_v3(delta.position))
            pose_bone.rotation_quaternion += Quaternion(
                quat_wxyz(delta.orientation))
예제 #7
0
파일: rig.py 프로젝트: garthand/s3py
 def read(self, stream, resource=None):
     s = StreamReader(stream)
     self.version_major = s.u32()
     self.version_minor = s.u32()
     cBones = s.i32()
     self.bones = []
     opposites = []
     parents = []
     self.__hashes = {}
     for i in range(cBones):
         bone = Bone(self)
         bone.position = [s.f32() for i in range(3)]
         bone.orientation = [s.f32() for i in range(4)]
         bone.scale = [s.f32() for i in range(3)]
         bone.name = s.p32()
         opposites.append(s.i32())
         parents.append(s.i32())
         hash_name = s.u32()
         if not hash_name == FNV32.hash(bone.name):
             print(
                 "WARNING: Bone %s should have matching hash 0x%08X, but has 0x%08X",
                 bone.name, FNV32.hash(bone.name), hash_name)
         self.__hashes[hash] = bone
         bone.flags = s.u32()
         self.bones.append(bone)
     for bone_index, opposite_index in enumerate(opposites):
         if opposite_index >= 0:
             self.bones[bone_index].opposite = self.bones[opposite_index]
     for bone_index, parent_index in enumerate(parents):
         if parent_index >= 0:
             self.bones[bone_index].parent = self.bones[parent_index]
     if self.version_major >= 4: self.name = s.p32()
     self.ik_chains = []
     cChains = s.i32()
     for i in range(cChains):
         chain = IKChain(self)
         chain.read(stream)
         self.ik_chains.append(chain)
예제 #8
0
 def animate_bone(root_bone):
     track_key = FNV32.hash(root_bone.name)
     if track_key in frame_map:
         group = action.groups.new(name=root_bone.name)
         data_path = 'pose.bones["%s"].' % root_bone.name
         location_path = '%slocation' % data_path
         rotation_path = '%srotation_quaternion' % data_path
         fcurves_translate = []
         fcurves_rotate = []
         for i in range(3):
             fcurve = action.fcurves.new(data_path=location_path, index=i)
             fcurve.group = group
             fcurves_translate.append(fcurve)
         for i in range(4):
             fcurve = action.fcurves.new(data_path=rotation_path, index=i)
             fcurve.group = group
             fcurves_rotate.append(fcurve)
         frame_indices = sorted(frame_map[track_key].keys())
         current_matrix = root_bone.bone.matrix_local
         rotation_matrix = current_matrix.to_3x3().to_4x4()
         translation_matrix = Matrix.Translation(
             current_matrix.to_translation())
         for frame_index in frame_indices:
             frame_data = frame_map[track_key][frame_index]
             if frame_data['orientation']:
                 rotation_matrix = (
                     Quaternion() if not root_bone.parent else
                     frame_data['orientation']).to_matrix().to_4x4()
             if frame_data['position']:
                 translation_matrix = Matrix.Translation(
                     frame_data['position'])
             transform_matrix = translation_matrix * rotation_matrix
             if root_bone.parent:
                 transform_matrix = root_bone.parent.matrix * transform_matrix
             root_bone.matrix = transform_matrix
             if frame_data['position']:
                 for i in range(3):
                     fcurves_translate[i].keyframe_points.add(1)
                     fcurves_translate[i].keyframe_points[-1].co = [
                         frame_index, root_bone.location[i]
                     ]
             if frame_data['orientation']:
                 for i in range(4):
                     fcurves_rotate[i].keyframe_points.add(1)
                     fcurves_rotate[i].keyframe_points[-1].co = [
                         frame_index, root_bone.rotation_quaternion[i]
                     ]
         root_bone.matrix = root_bone.bone.matrix_local
     for child in root_bone.children:
         animate_bone(child)
예제 #9
0
파일: rig.py 프로젝트: markmanching/s3py
 def write(self, stream, resource=None):
     s = StreamWriter(stream)
     s.u32(self.version_major)
     s.u32(self.version_minor)
     s.i32(len(self.bones))
     for bone in self.bones:
         for i in range(3): s.f32(bone.position[i])
         for i in range(4): s.f32(bone.orientation[i])
         for i in range(3): s.f32(bone.scale[i])
         assert bone.name != None, "Bone %s must have a name"
         s.p32(bone.name)
         s.i32(-1 if not bone.opposite in self.bones else self.bones.index(bone.opposite))
         s.i32(-1 if not bone.parent in self.bones else self.bones.index(bone.parent))
         s.u32(FNV32.hash(bone.name))
         s.u32(bone.flags)
     if self.version_major >= 4: s.p32(self.name)
     s.i32(len(self.ik_chains))
     for chain in self.ik_chains:
         chain.write(stream)
예제 #10
0
 def animate_bone(root_bone):
     track_key = FNV32.hash(root_bone.name)
     if track_key in frame_map:
         group = action.groups.new(name=root_bone.name)
         data_path = 'pose.bones["%s"].' % root_bone.name
         location_path = '%slocation' % data_path
         rotation_path = '%srotation_quaternion' % data_path
         fcurves_translate = []
         fcurves_rotate = []
         for i in range(3):
             fcurve = action.fcurves.new(data_path=location_path, index=i)
             fcurve.group = group
             fcurves_translate.append(fcurve)
         for i in range(4):
             fcurve = action.fcurves.new(data_path=rotation_path, index=i)
             fcurve.group = group
             fcurves_rotate.append(fcurve)
         frame_indices = sorted(frame_map[track_key].keys())
         current_matrix = root_bone.bone.matrix_local
         rotation_matrix = current_matrix.to_3x3().to_4x4()
         translation_matrix = Matrix.Translation(current_matrix.to_translation())
         for frame_index in frame_indices:
             frame_data = frame_map[track_key][frame_index]
             if frame_data['orientation']:
                 rotation_matrix = (
                     Quaternion() if not root_bone.parent else frame_data['orientation']).to_matrix().to_4x4()
             if frame_data['position']:
                 translation_matrix = Matrix.Translation(frame_data['position'])
             transform_matrix = translation_matrix * rotation_matrix
             if root_bone.parent:
                 transform_matrix = root_bone.parent.matrix * transform_matrix
             root_bone.matrix = transform_matrix
             if frame_data['position']:
                 for i in range(3):
                     fcurves_translate[i].keyframe_points.add(1)
                     fcurves_translate[i].keyframe_points[-1].co = [frame_index, root_bone.location[i]]
             if frame_data['orientation']:
                 for i in range(4):
                     fcurves_rotate[i].keyframe_points.add(1)
                     fcurves_rotate[i].keyframe_points[-1].co = [frame_index, root_bone.rotation_quaternion[i]]
         root_bone.matrix = root_bone.bone.matrix_local
     for child in root_bone.children:
         animate_bone(child)
예제 #11
0
파일: rig.py 프로젝트: garthand/s3py
 def write(self, stream, resource=None):
     s = StreamWriter(stream)
     s.u32(self.version_major)
     s.u32(self.version_minor)
     s.i32(len(self.bones))
     for bone in self.bones:
         for i in range(3):
             s.f32(bone.position[i])
         for i in range(4):
             s.f32(bone.orientation[i])
         for i in range(3):
             s.f32(bone.scale[i])
         assert bone.name != None, "Bone %s must have a name"
         s.p32(bone.name)
         s.i32(-1 if not bone.opposite in self.bones else self.bones.
               index(bone.opposite))
         s.i32(-1 if not bone.parent in self.bones else self.bones.
               index(bone.parent))
         s.u32(FNV32.hash(bone.name))
         s.u32(bone.flags)
     if self.version_major >= 4: s.p32(self.name)
     s.i32(len(self.ik_chains))
     for chain in self.ik_chains:
         chain.write(stream)
예제 #12
0
파일: rig.py 프로젝트: markmanching/s3py
 def read(self, stream, resource=None):
     s = StreamReader(stream)
     self.version_major = s.u32()
     self.version_minor = s.u32()
     cBones = s.i32()
     self.bones = []
     opposites = []
     parents = []
     self.__hashes = {}
     for i in range(cBones):
         bone = Bone(self)
         bone.position = [s.f32() for i in range(3)]
         bone.orientation = [s.f32() for i in range(4)]
         bone.scale = [s.f32() for i in range(3)]
         bone.name = s.p32()
         opposites.append(s.i32())
         parents.append(s.i32())
         hash_name = s.u32()
         if not hash_name == FNV32.hash(bone.name):
             print("WARNING: Bone %s should have matching hash 0x%08X, but has 0x%08X",bone.name, FNV32.hash(bone.name),hash_name)
         self.__hashes[hash] = bone
         bone.flags = s.u32()
         self.bones.append(bone)
     for bone_index, opposite_index in enumerate(opposites):
         if opposite_index >= 0:
             self.bones[bone_index].opposite = self.bones[opposite_index]
     for bone_index, parent_index in enumerate(parents):
         if parent_index >= 0:
             self.bones[bone_index].parent = self.bones[parent_index]
     if self.version_major >= 4: self.name = s.p32()
     self.ik_chains = []
     cChains = s.i32()
     for i in range(cChains):
         chain = IKChain(self)
         chain.read(stream)
         self.ik_chains.append(chain)
예제 #13
0
def load_mesh(armature_rig,model_mesh,materials):
    assert isinstance(model_mesh,s3py.buybuild.geometry.ObjectMesh)




    bone_name_map = {}
    if armature_rig.type == 'ARMATURE':
        for bone_hash in armature_rig.data.bones: bone_name_map[FNV32.hash(bone_hash.name)] = bone_hash.name




    vertices = model_mesh.get_vertices()
    faces = model_mesh.get_triangles()
    mesh_name = '%08X' % int(model_mesh.name)
    print(mesh_name)


    print('Creating Mesh %s'%mesh_name)
    mesh = bpy.data.meshes.new(mesh_name)

    mesh_obj = bpy.data.objects.new(mesh_name, mesh)
    bpy.context.scene.objects.link(mesh_obj)
    bpy.context.scene.objects.active = mesh_obj
    mesh_obj.parent = armature_rig

    mesh_obj.show_transparent = True

    matd = model_mesh.material
    if isinstance(matd,MaterialSet):
        matd= matd.default_material

    if isinstance(matd,MaterialDefinition):
        mesh_material = materials.generate(mesh_name,matd.material_block)
        mesh_obj.data.materials.append(mesh_material)


    vertex_groups = []
    if model_mesh.skin_controller:
        print('Adding Vertex groups from skin controller')

        for bone_hash in model_mesh.bone_references:
            bone_name = '%0X8'%bone_hash
            if bone_hash in bone_name_map:
                bone_name = bone_name_map[bone_hash]
            vertex_groups.append(mesh_obj.vertex_groups.new(bone_name))



    print('Adding armature modifier and attach to rig')
    mesh_skin = mesh_obj.modifiers.new(type='ARMATURE', name="%s_skin" % mesh_name)
    mesh_skin.use_bone_envelopes = False
    mesh_skin.object = armature_rig



    bm = bmesh.new()
    bm.from_mesh(mesh)

    for vertex in vertices: bm.verts.new(vertex.position)
    for face_index,face in enumerate(faces):
        if invalid_face(face): print('[%s]Face[%04i] %s has duplicate points, skipped'%(mesh_name,face_index,face)); continue
        bm.faces.new([bm.verts[face_point] for face_point in face])


    for vertex_index,vertex in enumerate(vertices): bm.verts[vertex_index].normal = Vector(vertex.normal[:-1])

    bm.to_mesh(mesh)

    print('Adding weights')
    for vertex_index,vertex in enumerate(vertices):
        if vertex.blend_indices and vertex.blend_weights:
            for blend_index, blend_bone_index in enumerate(vertex.blend_indices):
                if blend_bone_index >= 0:
                    weight = vertex.blend_weights[blend_index]
                    if weight > 0.0:
                        blend_vertex_group = vertex_groups[int(blend_bone_index)]
                        blend_vertex_group.add((vertex_index,), weight, 'ADD')


    print('Adding UV Groups')
    for declaration in model_mesh.get_vertex_format().declarations:
        if declaration.usage == VertexFormat.USAGE.UV:
            mesh.uv_textures.new(name='uv_%i' %  declaration.usage_index)

    faces_skipped = 0
    for face_index, face in enumerate(faces):
        if invalid_face(face): faces_skipped+=1; continue
        for face_point_index, face_point_vertex_index in enumerate([face[1],face[2],face[0]]):
            vertex = vertices[face_point_vertex_index]
            if vertex.uv:
                for uv_channel_index, uv_coord in enumerate(vertex.uv):
                    mesh.uv_layers[uv_channel_index].data[ face_point_index + ((face_index-faces_skipped)* 3)].uv = swizzle_uv(uv_coord)

    mesh_obj.select = True
    bpy.ops.object.shade_smooth()
    mesh_obj.select = False
    return mesh_obj
예제 #14
0
def load_clip(clip_resource, skeleton, scale=1.0):
    print('Loading clip...')

    #clear existing animations
    skeleton.animation_data_clear()

    clip = clip_resource.clip
    skeleton.hide = False
    bpy.context.scene.objects.active = skeleton
    skeleton.animation_data_clear()
    skeleton.animation_data_create()
    action = skeleton.animation_data.action = bpy.data.actions.new(clip.name)

    #set custom props
    action.s3py.actor_name = clip_resource.actor_name
    action.s3py.name = clip.name
    action.s3py.source_name = clip.source_file_name

    bone_transforms = {}
    pose_bone_map = {}
    for pose_bone in skeleton.pose.bones:
        hash = FNV32.hash(pose_bone.name)
        pose_bone_map[hash] = pose_bone
        bone_transforms[hash] = pose_bone.bone.matrix_local
    bpy.ops.object.mode_set(mode='POSE')

    #reset to bind pose
    bpy.ops.pose.user_transforms_clear()

    frame_map = {}
    for track in clip.tracks:
        if not track.track_key in frame_map:
            frame_map[track.track_key] = {}
        if track.orientations:
            for orientation_key in track.orientations.frames:
                if not orientation_key.frame_index in frame_map[
                        track.track_key].keys():
                    frame_map[track.track_key][orientation_key.frame_index] = {
                        'orientation': None,
                        'position': None,
                        'morph': None
                    }
                frame_map[track.track_key][
                    orientation_key.frame_index]['orientation'] = Quaternion(
                        quat_wxyz(orientation_key.data))
        if track.positions:
            for position_key in track.positions.frames:
                if not position_key.frame_index in frame_map[
                        track.track_key].keys():
                    frame_map[track.track_key][position_key.frame_index] = {
                        'orientation': None,
                        'position': None,
                        'morph': None
                    }
                position = Vector(position_key.data)
                #                if track.track_key == FNV32.hash(ROOT_BIND):
                #                    position[1] /= scale
                frame_map[track.track_key][
                    position_key.frame_index]['position'] = position

        if track.morphs:
            for morph_key in track.morphs.frames:
                if not morph_key.frame_index in frame_map[
                        track.track_key].keys():
                    frame_map[track.track_key][morph_key.frame_index] = {
                        'orientation': None,
                        'position': None,
                        'morph': None
                    }
                frame_map[track.track_key][
                    morph_key.frame_index]['morph'] = morph_key.data

    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_bone(root_bone):
        track_key = FNV32.hash(root_bone.name)
        if track_key in frame_map:
            group = action.groups.new(name=root_bone.name)
            data_path = 'pose.bones["%s"].' % root_bone.name
            location_path = '%slocation' % data_path
            rotation_path = '%srotation_quaternion' % data_path
            fcurves_translate = []
            fcurves_rotate = []
            for i in range(3):
                fcurve = action.fcurves.new(data_path=location_path, index=i)
                fcurve.group = group
                fcurves_translate.append(fcurve)
            for i in range(4):
                fcurve = action.fcurves.new(data_path=rotation_path, index=i)
                fcurve.group = group
                fcurves_rotate.append(fcurve)
            frame_indices = sorted(frame_map[track_key].keys())
            current_matrix = root_bone.bone.matrix_local
            rotation_matrix = current_matrix.to_3x3().to_4x4()
            translation_matrix = Matrix.Translation(
                current_matrix.to_translation())
            for frame_index in frame_indices:
                frame_data = frame_map[track_key][frame_index]
                if frame_data['orientation']:
                    rotation_matrix = (
                        Quaternion() if not root_bone.parent else
                        frame_data['orientation']).to_matrix().to_4x4()
                if frame_data['position']:
                    translation_matrix = Matrix.Translation(
                        frame_data['position'])
                transform_matrix = translation_matrix * rotation_matrix
                if root_bone.parent:
                    transform_matrix = root_bone.parent.matrix * transform_matrix
                root_bone.matrix = transform_matrix
                if frame_data['position']:
                    for i in range(3):
                        fcurves_translate[i].keyframe_points.add(1)
                        fcurves_translate[i].keyframe_points[-1].co = [
                            frame_index, root_bone.location[i]
                        ]
                if frame_data['orientation']:
                    for i in range(4):
                        fcurves_rotate[i].keyframe_points.add(1)
                        fcurves_rotate[i].keyframe_points[-1].co = [
                            frame_index, root_bone.rotation_quaternion[i]
                        ]
            root_bone.matrix = root_bone.bone.matrix_local
        for child in root_bone.children:
            animate_bone(child)

    animate_bone(skeleton.pose.bones[ROOT_BONE])
    if ROOT_MORPH in skeleton.pose.bones:
        animate_driver_bones(skeleton.pose.bones[ROOT_MORPH])

    bpy.context.scene.frame_set(0)
    print('Done.')
    return action
예제 #15
0
파일: rig.py 프로젝트: garthand/s3py
 def __getitem__(self, item):
     if isinstance(item, int) and item < len(self.bones):
         return self.bones[item]
     elif isinstance(item, str) and FNV32.hash(item) in self.__hashes:
         return self.__hashes[FNV32.hash(item)]
     return None
예제 #16
0
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))
예제 #17
0
파일: rig.py 프로젝트: markmanching/s3py
 def __getitem__(self, item):
     if isinstance(item,int) and item < len(self.bones):
         return self.bones[item]
     elif isinstance(item,str) and FNV32.hash(item) in self.__hashes:
         return self.__hashes[FNV32.hash(item)]
     return None
예제 #18
0
def load_clip(clip_resource, skeleton, scale=1.0):
    print('Loading clip...')

    #clear existing animations
    skeleton.animation_data_clear()

    clip = clip_resource.clip
    skeleton.hide = False
    bpy.context.scene.objects.active = skeleton
    skeleton.animation_data_clear()
    skeleton.animation_data_create()
    action = skeleton.animation_data.action = bpy.data.actions.new(clip.name)

    #set custom props
    action.s3py.actor_name = clip_resource.actor_name
    action.s3py.name = clip.name
    action.s3py.source_name = clip.source_file_name

    bone_transforms = {}
    pose_bone_map = {}
    for pose_bone in skeleton.pose.bones:
        hash = FNV32.hash(pose_bone.name)
        pose_bone_map[hash] = pose_bone
        bone_transforms[hash] = pose_bone.bone.matrix_local
    bpy.ops.object.mode_set(mode='POSE')

    #reset to bind pose
    bpy.ops.pose.user_transforms_clear()

    frame_map = {}
    for track in clip.tracks:
        if not track.track_key in frame_map:
            frame_map[track.track_key] = {}
        if track.orientations:
            for orientation_key in track.orientations.frames:
                if not orientation_key.frame_index in frame_map[track.track_key].keys():
                    frame_map[track.track_key][orientation_key.frame_index] = {
                        'orientation': None,
                        'position': None,
                        'morph': None
                    }
                frame_map[track.track_key][orientation_key.frame_index]['orientation'] = Quaternion(
                    quat_wxyz(orientation_key.data))
        if track.positions:
            for position_key in track.positions.frames:
                if not position_key.frame_index in frame_map[track.track_key].keys():
                    frame_map[track.track_key][position_key.frame_index] = {
                        'orientation': None,
                        'position': None,
                        'morph': None
                    }
                position = Vector(position_key.data)
#                if track.track_key == FNV32.hash(ROOT_BIND):
#                    position[1] /= scale
                frame_map[track.track_key][position_key.frame_index]['position'] = position

        if track.morphs:
            for morph_key in track.morphs.frames:
                if not morph_key.frame_index in frame_map[track.track_key].keys():
                    frame_map[track.track_key][morph_key.frame_index] = {
                        'orientation': None,
                        'position': None,
                        'morph': None
                    }
                frame_map[track.track_key][morph_key.frame_index]['morph'] = morph_key.data

    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_bone(root_bone):
        track_key = FNV32.hash(root_bone.name)
        if track_key in frame_map:
            group = action.groups.new(name=root_bone.name)
            data_path = 'pose.bones["%s"].' % root_bone.name
            location_path = '%slocation' % data_path
            rotation_path = '%srotation_quaternion' % data_path
            fcurves_translate = []
            fcurves_rotate = []
            for i in range(3):
                fcurve = action.fcurves.new(data_path=location_path, index=i)
                fcurve.group = group
                fcurves_translate.append(fcurve)
            for i in range(4):
                fcurve = action.fcurves.new(data_path=rotation_path, index=i)
                fcurve.group = group
                fcurves_rotate.append(fcurve)
            frame_indices = sorted(frame_map[track_key].keys())
            current_matrix = root_bone.bone.matrix_local
            rotation_matrix = current_matrix.to_3x3().to_4x4()
            translation_matrix = Matrix.Translation(current_matrix.to_translation())
            for frame_index in frame_indices:
                frame_data = frame_map[track_key][frame_index]
                if frame_data['orientation']:
                    rotation_matrix = (
                        Quaternion() if not root_bone.parent else frame_data['orientation']).to_matrix().to_4x4()
                if frame_data['position']:
                    translation_matrix = Matrix.Translation(frame_data['position'])
                transform_matrix = translation_matrix * rotation_matrix
                if root_bone.parent:
                    transform_matrix = root_bone.parent.matrix * transform_matrix
                root_bone.matrix = transform_matrix
                if frame_data['position']:
                    for i in range(3):
                        fcurves_translate[i].keyframe_points.add(1)
                        fcurves_translate[i].keyframe_points[-1].co = [frame_index, root_bone.location[i]]
                if frame_data['orientation']:
                    for i in range(4):
                        fcurves_rotate[i].keyframe_points.add(1)
                        fcurves_rotate[i].keyframe_points[-1].co = [frame_index, root_bone.rotation_quaternion[i]]
            root_bone.matrix = root_bone.bone.matrix_local
        for child in root_bone.children:
            animate_bone(child)


    animate_bone(skeleton.pose.bones[ROOT_BONE])
    if ROOT_MORPH in skeleton.pose.bones:
        animate_driver_bones(skeleton.pose.bones[ROOT_MORPH])

    bpy.context.scene.frame_set(0)
    print('Done.')
    return action
예제 #19
0
파일: blender.py 프로젝트: garthand/s3py
def load_geom(name, geom, blend_vertex_lod_map, armature_rig, material):
    bone_name_map = {}
    for bone in armature_rig.data.bones:
        bone_name_map[FNV32.hash(bone.name)] = bone.name

    mesh_name = name
    mesh = bpy.data.meshes.new(mesh_name)

    mesh_obj = bpy.data.objects.new(mesh_name, mesh)
    if material:
        mesh_obj.data.materials.append(material)

    bpy.context.scene.objects.link(mesh_obj)
    bpy.context.scene.objects.active = mesh_obj
    mesh_obj.parent = armature_rig

    print('processing mesh: %s' % mesh_name)
    shape_key_basis = mesh_obj.shape_key_add(from_mix=False, name='Basis')
    for blend_name in blend_vertex_lod_map:
        shape_key_morph = mesh_obj.shape_key_add(from_mix=False,
                                                 name=blend_name)
        shape_key_morph.relative_key = shape_key_basis
        print('making driver %s for %s' % (blend_name, mesh_name))
        shape_key_fcurve = shape_key_morph.driver_add('value')
        shape_key_fcurve.driver.type = 'AVERAGE'
        shape_key_var = shape_key_fcurve.driver.variables.new()
        shape_key_var.type = 'SINGLE_PROP'
        shape_key_var.targets[0].id_type = 'OBJECT'
        shape_key_var.targets[0].id = armature_rig
        shape_key_var.targets[
            0].data_path = 'pose.bones["%s"].morph_value' % blend_name

    mesh_uvs = []
    mesh_skin = mesh_obj.modifiers.new(type='ARMATURE',
                                       name="%s_skin" % mesh_name)
    mesh_skin.use_bone_envelopes = False
    mesh_skin.object = armature_rig
    vertex_groups = []
    for geom_bone in geom.bones:
        if not geom_bone in bone_name_map:
            raise Exception('0x%08X not found' % geom_bone)
        vertex_groups.append(
            mesh_obj.vertex_groups.new(bone_name_map[geom_bone]))

    bm = bmesh.new()
    bm.from_mesh(mesh)

    for vertex in geom.vertices:
        bvert = bm.verts.new(vertex.position)
        bvert.normal = Vector(swizzle_v3(vertex.normal[:3]))
    faces_skipped = 0
    for face_index, face in enumerate(geom.indices):
        if invalid_face(face):
            print('[%s]Face[%04i] %s has duplicate points, skipped' %
                  (mesh_name, face_index, face))
            continue
        try:
            bm.verts.ensure_lookup_table()
            bm.edges.ensure_lookup_table()
            bm.faces.ensure_lookup_table()
            bm.faces.new([bm.verts[face_point] for face_point in face])
        except ValueError as e:
            faces_skipped += 1
            print('Unable to load face %s' % face)
            print(e)
    bm.to_mesh(mesh)

    for vertex_index, vertex in enumerate(geom.vertices):
        # Positions
        blender_vertex = mesh.vertices[vertex_index]
        pos = blender_vertex.co.copy()
        shape_key_basis.data[vertex_index].co = pos
        # Add Shape Keys
        for blend_name in sorted(blend_vertex_lod_map):
            morph_blend_vertices = blend_vertex_lod_map[blend_name]
            morph_pos = pos.copy()
            if vertex.id in morph_blend_vertices:
                morph_blend_vertex = morph_blend_vertices[vertex.id]
                if morph_blend_vertex.position:
                    morph_pos += Vector(morph_blend_vertex.position)
            mesh.shape_keys.key_blocks[blend_name].data[
                vertex_index].co = morph_pos
            # Add Vertex Weights

        if vertex.blend_indices:
            for blend_index, blend_bone_index in enumerate(
                    vertex.blend_indices):
                if blend_bone_index <= len(vertex_groups):
                    blend_vertex_group = vertex_groups[blend_bone_index]
                    weight = vertex.blend_weights[blend_index]
                    if weight > 0.000:
                        blend_vertex_group.add(
                            (vertex_index, ),
                            vertex.blend_weights[blend_index], 'REPLACE')

    for face_index, face in enumerate(geom.indices):
        if invalid_face(face):
            faces_skipped += 1
            continue
        for face_point_index, face_point_vertex_index in enumerate(face):
            vertex = geom.vertices[face_point_vertex_index]
            if vertex.uv:
                for uv_channel_index, uv_coord in enumerate(vertex.uv):
                    if (uv_channel_index + 1) > len(mesh_uvs):
                        mesh_uvs.append(
                            mesh.uv_textures.new(name='uv_%i' %
                                                 uv_channel_index))
                    mesh.uv_layers[uv_channel_index].data[face_point_index + (
                        (face_index - faces_skipped) *
                        3)].uv = swizzle_uv(uv_coord)

    mesh_obj.select = True
    bpy.ops.object.shade_smooth()
    mesh_obj.select = False
    mesh_obj.active_shape_key_index = 0

    return mesh_obj
예제 #20
0
파일: blender.py 프로젝트: garthand/s3py
def load_mesh(armature_rig, model_mesh, materials):
    assert isinstance(model_mesh, s3py.buybuild.geometry.ObjectMesh)

    bone_name_map = {}
    if armature_rig.type == 'ARMATURE':
        for bone_hash in armature_rig.data.bones:
            bone_name_map[FNV32.hash(bone_hash.name)] = bone_hash.name

    vertices = model_mesh.get_vertices()
    faces = model_mesh.get_triangles()
    mesh_name = '%08X' % int(model_mesh.name)
    print(mesh_name)

    print('Creating Mesh %s' % mesh_name)
    mesh = bpy.data.meshes.new(mesh_name)

    mesh_obj = bpy.data.objects.new(mesh_name, mesh)
    bpy.context.scene.objects.link(mesh_obj)
    bpy.context.scene.objects.active = mesh_obj
    mesh_obj.parent = armature_rig

    mesh_obj.show_transparent = True

    matd = model_mesh.material
    if isinstance(matd, MaterialSet):
        matd = matd.default_material

    if isinstance(matd, MaterialDefinition):
        mesh_material = materials.generate(mesh_name, matd.material_block)
        mesh_obj.data.materials.append(mesh_material)

    vertex_groups = []
    if model_mesh.skin_controller:
        print('Adding Vertex groups from skin controller')

        for bone_hash in model_mesh.bone_references:
            bone_name = '%0X8' % bone_hash
            if bone_hash in bone_name_map:
                bone_name = bone_name_map[bone_hash]
            vertex_groups.append(mesh_obj.vertex_groups.new(bone_name))

    print('Adding armature modifier and attach to rig')
    mesh_skin = mesh_obj.modifiers.new(type='ARMATURE',
                                       name="%s_skin" % mesh_name)
    mesh_skin.use_bone_envelopes = False
    mesh_skin.object = armature_rig

    bm = bmesh.new()
    bm.from_mesh(mesh)
    for vertex in vertices:
        bm.verts.new(vertex.position)
    for face_index, face in enumerate(faces):
        bm.verts.ensure_lookup_table()
        bm.edges.ensure_lookup_table()
        bm.faces.ensure_lookup_table()
        if invalid_face(face):
            print('[%s]Face[%04i] %s has duplicate points, skipped' %
                  (mesh_name, face_index, face))
            continue
        bm.faces.new([bm.verts[face_point] for face_point in face])

    for vertex_index, vertex in enumerate(vertices):
        bm.verts[vertex_index].normal = Vector(vertex.normal[:-1])

    bm.to_mesh(mesh)

    print('Adding weights')
    for vertex_index, vertex in enumerate(vertices):
        if vertex.blend_indices and vertex.blend_weights:
            for blend_index, blend_bone_index in enumerate(
                    vertex.blend_indices):
                if blend_bone_index >= 0:
                    weight = vertex.blend_weights[blend_index]
                    if weight > 0.0:
                        blend_vertex_group = vertex_groups[int(
                            blend_bone_index)]
                        blend_vertex_group.add((vertex_index, ), weight, 'ADD')

    print('Adding UV Groups')
    for declaration in model_mesh.get_vertex_format().declarations:
        if declaration.usage == VertexFormat.USAGE.UV:
            mesh.uv_textures.new(name='uv_%i' % declaration.usage_index)

    faces_skipped = 0
    for face_index, face in enumerate(faces):
        if invalid_face(face):
            faces_skipped += 1
            continue
        for face_point_index, face_point_vertex_index in enumerate(face):
            vertex = vertices[face_point_vertex_index]
            if vertex.uv:
                for uv_channel_index, uv_coord in enumerate(vertex.uv):
                    mesh.uv_layers[uv_channel_index].data[face_point_index + (
                        (face_index - faces_skipped) *
                        3)].uv = swizzle_uv(uv_coord)

    mesh_obj.select = True
    bpy.ops.object.shade_smooth()
    mesh_obj.select = False
    return mesh_obj
예제 #21
0
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))