Exemplo n.º 1
0
 def build_skeleton(self, pkg_name, obj_name):
     pkg = ue.get_or_create_package('{0}_Skeleton'.format(pkg_name))
     skel = Skeleton('{0}_Skeleton'.format(obj_name), pkg)
     # add a root bone from which all of the others will descend
     # (this trick will avoid generating an invalid skeleton [and a crash], as in UE4 only one root can exist)
     skel.skeleton_add_bone('root', -1, FTransform())
     # iterate bones in the json file, note that we move from opengl axis to UE4
     # (y on top, x right, z forward right-handed) to (y right, x forward left-handed, z on top)
     for bone in self.model['bones']:
         # assume no rotation
         quat = FQuat()
         # give priority to quaternions
         # remember to negate x and y axis, as we invert z on position
         if 'rotq' in bone:
             quat = FQuat(bone['rotq'][2], bone['rotq'][0] * -1,
                          bone['rotq'][1] * -1, bone['rotq'][3])
         elif 'rot' in bone:
             quat = FRotator(bone['rot'][2], bone['rot'][0] - 180,
                             bone['rot'][1] - 180).quaternion()
         pos = FVector(bone['pos'][2] * -1, bone['pos'][0],
                       bone['pos'][1]) * self.scale
         # always set parent+1 as we added the root bone before
         skel.skeleton_add_bone(bone['name'], bone['parent'] + 1,
                                FTransform(pos, quat))
     skel.save_package()
     return skel
    def build_animation(self, pkg_name, obj_name):
        factory = AnimSequenceFactory()
        factory.TargetSkeleton = self.skeleton
        new_anim = factory.factory_create_new('{0}_Animation'.format(pkg_name))

        new_anim.NumFrames = self.model['animation']['length'] * \
            self.model['animation']['fps']
        new_anim.SequenceLength = self.model['animation']['length']
        # each bone maps to a track in UE4 animations
        for bone_index, track in enumerate(self.model['animation']['hierarchy']):
            # retrieve the bone/track name from the index (remember to add 1 as we have the additional root bone)
            bone_name = self.skeleton.skeleton_get_bone_name(bone_index + 1)

            positions = []
            rotations = []
            scales = []

            for key in track['keys']:
                t = key['time']
                if 'pos' in key:
                    positions.append(
                        (t, FVector(key['pos'][2] * -1, key['pos'][0], key['pos'][1]) * 100))
                if 'rotq' in key:
                    rotations.append((t, FQuat(
                        key['rotq'][2], key['rotq'][0] * -1, key['rotq'][1] * -1, key['rotq'][3])))
                elif 'rot' in key:
                    # is it a quaternion ?
                    if len(key['rot']) == 4:
                        rotations.append(
                            (t, FQuat(key['rot'][2], key['rot'][0] * -1, key['rot'][1] * -1, key['rot'][3])))
                    else:
                        rotations.append(
                            (t, FRotator(key['rot'][2], key['rot'][0] - 180, key['rot'][1] - 180).quaternion()))
            pos_keys = []
            rot_keys = []
            # generate the right number of frames
            for t in numpy.arange(0, self.model['animation']['length'], 1.0 / self.model['animation']['fps']):
                pos_keys.append(self.interpolate_vector(positions, t))
                rot_keys.append(self.interpolate_quaternion(
                    rotations, t).get_normalized())
            track_data = FRawAnimSequenceTrack()
            track_data.pos_keys = pos_keys
            track_data.rot_keys = rot_keys
            new_anim.add_new_raw_track(bone_name, track_data)

        # if we have curves, just add them to the animation
        if self.curves:
            new_anim.RawCurveData = RawCurveTracks(FloatCurves=self.curves)

        new_anim.save_package()

        return new_anim
Exemplo n.º 3
0
    def split_hips(self, animation, bone='Hips'):
        self.choosen_skeleton = None
        # first ask for which skeleton to use:
        self.window = SWindow(title='Choose your new Skeleton', modal=True, sizing_rule=1)(
                     SObjectPropertyEntryBox(allowed_class=Skeleton, on_object_changed=self.set_skeleton)
                 )
        self.window.add_modal()
        if not self.choosen_skeleton:
            raise DialogException('Please specify a Skeleton for retargeting')

        factory = AnimSequenceFactory()
        factory.TargetSkeleton = self.choosen_skeleton
        
        base_path = animation.get_path_name()
        package_name = ue.get_path(base_path)
        object_name = ue.get_base_filename(base_path)

        new_anim = factory.factory_create_new(package_name + '/' + object_name + '_rooted')

        new_anim.NumFrames = animation.NumFrames
        new_anim.SequenceLength = animation.SequenceLength

        # first step is generatin the 'root' track
        # we need to do it before anything else, as the 'root' track must be the 0 one
        for index, name in enumerate(animation.AnimationTrackNames):
            if name == bone:
                data = animation.get_raw_animation_track(index)
                # extract root motion
                root_motion = [(position - data.pos_keys[0]) for position in data.pos_keys]

                # create a new track (the root motion one)
                root_data = FRawAnimSequenceTrack()
                root_data.pos_keys = root_motion
                # ensure empty rotations !
                root_data.rot_keys = [FQuat()]
        
                # add  the track
                new_anim.add_new_raw_track('root', root_data)
                break
        else:
            raise DialogException('Unable to find bone {0}'.format(bone))
           
        # now append the original tracks, but removes the position keys
        # from the original root bone
        for index, name in enumerate(animation.AnimationTrackNames):
            data = animation.get_raw_animation_track(index)
            if name == bone:
                # remove root motion from original track
                data.pos_keys = [data.pos_keys[0]]
                new_anim.add_new_raw_track(name, data)
            else:
                new_anim.add_new_raw_track(name, data)

        new_anim.save_package()
Exemplo n.º 4
0
    def interpolate_quaternion(self, timeline, t):
        keys = []
        x_values = []
        y_values = []
        z_values = []
        w_values = []
        for key, value in timeline:
            keys.append(key)
            x_values.append(value[0])
            y_values.append(value[1])
            z_values.append(value[2])
            w_values.append(value[3])

        x = numpy.interp(t, keys, x_values)
        y = numpy.interp(t, keys, y_values)
        z = numpy.interp(t, keys, z_values)
        w = numpy.interp(t, keys, w_values)
        return FQuat(x, y, z, w)