示例#1
0
def cam_and_swivel(cam_location=[25, 0, 0],
                   cam_rotation_euler=[0, 0, 0],
                   cam_name="Camera Bobject",
                   swivel_location=[0, 0, 0],
                   swivel_rotation_euler=[0, 0, 0],
                   swivel_name='Cam swivel',
                   control_sun=False):
    cam_bobj = bobject.Bobject(location=cam_location,
                               rotation_euler=cam_rotation_euler,
                               name=cam_name)
    cam_swivel = bobject.Bobject(
        cam_bobj,
        location=swivel_location,
        rotation_euler=swivel_rotation_euler,
        name=swivel_name,
    )

    cam_obj = bpy.data.objects['Camera']
    cam_obj.data.clip_end = 100
    cam_obj.location = [0, 0, 0]
    cam_obj.parent = cam_bobj.ref_obj

    if control_sun == True:
        sun_obj = bpy.data.objects['Sun']
        sun_obj.location = [0, 0, 0]
        sun_obj.parent = cam_bobj.ref_obj

    return cam_bobj, cam_swivel
示例#2
0
    def head_move_eyes_locked(self):
        cam_bobj, cam_swivel = cam_and_swivel(
            cam_location=[0, 0, 90],
            cam_rotation_euler=[0, 0, 0],
            cam_name="Camera Bobject",
            swivel_location=[0, 0, -2],
            swivel_rotation_euler=[math.pi / 2, 0, math.pi / 2],
            swivel_name='Cam swivel',
            #control_sun = True
        )
        cam_swivel.add_to_blender(appear_time=-1)

        skull = bpy.data.objects['Skull_Top']
        skull_bobj = bobject.Bobject(objects=[skull])
        skull_bobj.add_to_blender(appear_time=0, animate=False)

        eye_l = bpy.data.objects['eye_l']
        eye_l_initial_angle = list(eye_l.rotation_euler)
        eye_r = bpy.data.objects['eye_r']
        eye_r_initial_angle = list(eye_r.rotation_euler)

        angles = [[0, 0, 15 * math.pi / 180], [0, 0, -15 * math.pi / 180],
                  [0, 0, 15 * math.pi / 180], [0, 0, -15 * math.pi / 180],
                  [0, 0, -15 * math.pi / 180], [0, 10 * math.pi / 180, 0],
                  [0, -5 * math.pi / 180, 0], [0, 0, 15 * math.pi / 180],
                  [0, 10 * math.pi / 180, 0], [0, 0, 0]]

        rot_start_time = 49.5

        for i, angle in enumerate(angles):
            time = i / 2
            skull_bobj.move_to(new_angle=angle,
                               start_time=time + rot_start_time)

            #Eyes aren't set up to work well as bobjects since I currently don't
            #plan to reuse them a bunch. Probably poor foresight. /shrug
            #They are also rotated in the z-direction with xyz euler angles, so
            #the corrections need to accound for this.
            eye_l.keyframe_insert(data_path='rotation_euler',
                                  frame=(time + rot_start_time) * FRAME_RATE)
            eye_l.rotation_euler = [
                eye_l_initial_angle[0] - angle[1],
                eye_l_initial_angle[1] + angle[0],
                eye_l_initial_angle[2] - angle[2]
            ]
            eye_l.keyframe_insert(data_path='rotation_euler',
                                  frame=(time + rot_start_time + 0.5) *
                                  FRAME_RATE)

            eye_r.keyframe_insert(data_path='rotation_euler',
                                  frame=(time + rot_start_time) * FRAME_RATE)
            eye_r.rotation_euler = [
                eye_r_initial_angle[0] - angle[1],
                eye_r_initial_angle[1] + angle[0],
                eye_r_initial_angle[2] - angle[2]
            ]
            eye_r.keyframe_insert(data_path='rotation_euler',
                                  frame=(time + rot_start_time + 0.5) *
                                  FRAME_RATE)
示例#3
0
    def zoom(self):
        cues = self.subscenes['zoom']

        cam_bobj = bobject.Bobject(
            location=[90, 0, 0],
            rotation_euler=[math.pi / 2, 0, 87 * math.pi / 180],
            name="Camera Bobject")
        cam_swivel = bobject.Bobject(cam_bobj,
                                     location=[0, 0, 0],
                                     rotation_euler=[0, 0, 0],
                                     name='Cam swivel')
        cam_swivel.add_to_blender(appear_time=0, animate=False)
        #cam_bobj.add_to_blender(appear_time = 0, animate = False)
        cam_obj = bpy.data.objects['Camera']
        cam_obj.data.clip_end = 1000
        cam_obj.location = [0, 0, 0]
        cam_obj.parent = cam_bobj.ref_obj

        #Look at brain and temporal bone
        cam_swivel.move_to(new_angle=[0, 0, -55 * math.pi / 180],
                           start_time=self.brain_zoom_time,
                           end_time=self.brain_zoom_time + 1.5)
        cam_bobj.move_to(
            new_location=[35.3, 0, 0],
            new_angle=[95.8 * math.pi / 180, 0, 85.6 * math.pi / 180],
            start_time=self.brain_zoom_time,
            end_time=self.brain_zoom_time + 1.5)

        #Look at inner ear
        cam_bobj.move_to(
            new_location=[5, 0, 0],
            new_angle=[92.5 * math.pi / 180, 0, 89 * math.pi / 180],
            start_time=self.inner_zoom_time,
            end_time=self.inner_zoom_time + 1.5)

        #Look at utricle
        cam_swivel.move_to(
            new_angle=[0, 15.5 * math.pi / 180, -190 * math.pi / 180],
            start_time=self.utricle_time,
            end_time=self.utricle_time + 1.5)
        cam_bobj.move_to(
            new_location=[0.3, 0, 0.15],
            new_angle=[80.9 * math.pi / 180, 0, 89 * math.pi / 180],
            start_time=self.utricle_time,
            end_time=self.utricle_time + 1.5)

        #Side view of canals
        cam_swivel.move_to(new_angle=[0, 0, -217 * math.pi / 180],
                           start_time=self.dislodged_time,
                           end_time=self.dislodged_time + 1.5)
        cam_bobj.move_to(
            new_location=[5, 0, 0],
            new_angle=[92.5 * math.pi / 180, 0, 91 * math.pi / 180],
            start_time=self.dislodged_time,
            end_time=self.dislodged_time + 1.5)

        #rotate and highlight
        rot_duration = 2  #25
        deg_angle = -217 + 360 / 10 * rot_duration
        cam_swivel.move_to(new_angle=[0, 0, deg_angle * math.pi / 180],
                           start_time=self.only_posterior_time,
                           end_time=self.only_posterior_time + rot_duration)

        #Epley position (stationary camera after initial positioning)
        cam_swivel.move_to(
            new_angle=[0, 0, 60 * math.pi / 180],
            start_time=self.epley_camera_time,
        )
        """#Dix Hallpike lean back
示例#4
0
    def end_card(self):
        logo = svg_bobject.SVGBobject(
            "UCSF_logo",
            #location = (-5, 3.75, 0), #Centered position
            #scale = 0.26, #Centered scale
            location=[0, 0, 0],
            scale=0.121,
            color='color2',
            #centered = True,
        )
        baf = svg_bobject.SVGBobject(
            'BaFC_Arial',
            location=[5.2257280349731445, -0.26257357001304626, 0.0],
            scale=2.23,
            color='color2',
            #centered = True,
        )
        logobaf = bobject.Bobject(
            logo,
            baf,
            location=[-11.57, 2.5, 0],
            #location = [0, 1.5, Z0],
            scale=0.852,
            #centered = True
        )
        logobaf.add_to_blender(
            appear_time=0,
            animate=False,
        )
        url = tex_bobject.TexBobject(
            '\\text{ohns.ucsf.edu/otology-neurotology/balance-and-falls}',
            location=[0, 0.8, 0],
            color='color2',
            name='url',
            typeface='arial',
            scale=0.8,
            centered=True)
        url.add_to_blender(appear_time=0)

        mpb_loc = [1, -4.25, 0]
        mpb = tex_bobject.TexBobject('\\text{Made possible by:}',
                                     location=mpb_loc,
                                     color='color2',
                                     name='mpb',
                                     typeface='arial')
        mzhf = tex_bobject.TexBobject(
            '\\text{Mount Zion Health Fund}',
            color='color2',
            scale=1.2,
            location=[mpb_loc[0] + 0.5, mpb_loc[1] - 1.4, mpb_loc[2]],
            name='mzhf',
            typeface='arial')
        vpb_loc = [-13, -4.25, 0]
        vpb = tex_bobject.TexBobject('\\text{Video produced by:}',
                                     color='color2',
                                     location=vpb_loc,
                                     name='vpb',
                                     typeface='arial')
        jh = tex_bobject.TexBobject(
            '\\text{Justin Helps}',
            location=[vpb_loc[0] + 0.5, vpb_loc[1] - 1.4, vpb_loc[2]],
            scale=1.2,
            color='color2',
            name='jh',
            typeface='arial')
        jds = tex_bobject.TexBobject(
            '\\text{Jeffrey D. Sharon, MD}',
            location=[vpb_loc[0] + 0.5, vpb_loc[1] - 2.8, vpb_loc[2]],
            scale=1.2,
            color='color2',
            name='jds',
            typeface='arial')

        for bobj in [mpb, mzhf, vpb, jh, jds]:
            bobj.add_to_blender(appear_time=0, animate=False)
示例#5
0
    def add_annotation(self,
                       targets=None,
                       alignment='top',
                       labels=None,
                       angle=0,
                       length=1,
                       label_scale=0.67,
                       gest_scale=1):
        #calc points from targets
        gesture_series = []
        tex_bobj = self.tex_bobjects[targets[0]]
        #label_anchor = None
        for j, target in enumerate(targets[1]):
            bobjs = []
            path = tex_bobj.paths[target[0]]
            for i in range(target[1], target[2] + 1):
                bobjs.append(tex_bobj.imported_svg_data[path]['curves'][i])

            left_most = math.inf
            right_most = -math.inf
            y = 0
            for bobj in bobjs:
                cur = bobj.objects[0]
                for spline in cur.data.splines:
                    for point in spline.bezier_points:
                        candidatex = cur.location[0] * cur.parent.scale[0] + \
                            cur.parent.location[0] * cur.parent.parent.scale[0] + \
                            point.co[0] * cur.scale[0]
                        if right_most < candidatex:
                            right_most = candidatex
                        if left_most > candidatex:
                            left_most = candidatex
                    for point in spline.bezier_points:
                        candidatey = cur.location[1] * cur.parent.scale[1] + \
                            cur.parent.location[1] * cur.parent.parent.scale[1] + \
                            point.co[1] * cur.scale[1]
                        if alignment == 'top':
                            if y < candidatey:
                                y = candidatey
                        elif alignment == 'bottom':
                            if y > candidatey:
                                y = candidatey

            if isinstance(angle, (float, int)):
                this_angle = angle
            elif isinstance(angle, list):
                this_angle = angle[j]

            if len(target
                   ) > 3 and target[3] == None:  #No bobjs, empty gesture. HEH.
                if alignment == 'top':
                    #y += 0 * self.scale[1] * tex_bobj.scale[1]
                    head = ((right_most + left_most) / 2 / gest_scale,
                            y + length, 0)
                    rot = (0, 0, 0)
                elif alignment == 'bottom':
                    #y -= 0 * self.scale[1] * tex_bobj.scale[1]
                    head = ((right_most + left_most) / 2 / gest_scale,
                            y - length, 0)
                    rot = (0, 0, math.pi)
                    #if label_anchor == None:
                    #    label_anchor = list(head)
                gesture_series.append({
                    'type': None,
                    'points': {
                        'location': head,
                        'rotation': rot
                    }
                })
            elif len(target) > 3 and target[3] == 'bracket' or \
                (len(target) == 3 and len(bobjs) > 1): #Bracket
                if alignment == 'top':
                    y += 0.2 * self.scale[1] * tex_bobj.scale[1]
                    annotation_point = ((right_most + left_most) / 2 /
                                        gest_scale, y + length, 0)
                    left_point = (left_most / gest_scale, y, 0)
                    right_point = (right_most / gest_scale, y, 0)
                elif alignment == 'bottom':
                    y -= 0.2 * self.scale[1] * tex_bobj.scale[1]
                    annotation_point = ((right_most + left_most) / 2 /
                                        gest_scale, y - length, 0)
                    left_point = [right_most / gest_scale, y, 0]
                    right_point = [left_most / gest_scale, y, 0]
                    #if label_anchor == None:
                    #    label_anchor = list(annotation_point)
                gesture_series.append({
                    'type': 'bracket',
                    'points': {
                        'annotation_point': annotation_point,
                        'left_point': left_point,
                        'right_point': right_point
                    }
                })

            elif len(target) > 3 and target[3] == 'arrow' or \
                (len(target) == 3 and len(bobjs) == 1): #Arrow
                if alignment == 'top':
                    y += 0.3 * tex_bobj.scale[1]  #* self.scale[1]
                    head = ((right_most + left_most) / 2 / gest_scale +
                            math.tan(this_angle) * 0.4, y / gest_scale, 0)
                    tail = ((right_most + left_most) / 2 / gest_scale +
                            math.tan(this_angle) * length,
                            (y + length) / gest_scale, 0)
                elif alignment == 'bottom':
                    y -= 0.3 * tex_bobj.scale[1]  #* self.scale[1]
                    head = ((right_most + left_most) / 2 / gest_scale -
                            math.tan(this_angle) * 0.4, y / gest_scale, 0)
                    tail = ((right_most + left_most) / 2 / gest_scale -
                            math.tan(this_angle) * length,
                            (y - length) / gest_scale, 0)
                    #if label_anchor == None:
                    #    label_anchor = list(tail)
                gesture_series.append({
                    'type': 'arrow',
                    'points': {
                        'head': head,
                        'tail': tail,
                    }
                })
            else:
                raise Warning('Something is wrong with the gesture targets.')

        container = bobject.Bobject(name='annotation')

        gest = gesture.Gesture(gesture_series=gesture_series,
                               color='color2',
                               scale=gest_scale)
        container.add_subbobject(gest)
        tex_bobj.annotations.append([container, targets[1], alignment])
        self.annotations.append([container, targets[0]])

        #Make TexComplex for the annotation_text
        t_bobj_count = 0
        for label in labels:
            t_bobj_count = max(len(label), t_bobj_count)
        for label in labels:
            while len(label) < t_bobj_count:
                label.append(None)
        t_bobjs = []
        for i in range(t_bobj_count):
            strings = []
            for label in labels:
                strings.append(label[i])
                #print(len(strings))
            t_bobj = tex_bobject.TexBobject(*strings,
                                            centered=True,
                                            color='color2')
            t_bobjs.append(t_bobj)

        #label_scale = 0.67 #Smaller than text. Could do this in a more robust way
        #se;fline_height = 1.2 #Could make this a constant. It's already a default.
        #dy = (1 + t_bobj_count) / 2 * self.line_height
        #print(t_bobj_count)
        if alignment == 'top':
            dy = (t_bobj_count / 2 + 1 / 2) * self.line_height
        if alignment == 'bottom':
            dy = (t_bobj_count / 2) * self.line_height

        #Some t_bobjs may start with empty expressions. Initial position
        #shouldn't take empty lines into account, and position will be adjusted on morph
        if alignment == 'top':
            for t_bobj in t_bobjs:
                if t_bobj.paths[0] == None:
                    dy -= self.line_height  # * label_scale

        #label_anchor[1] += dy

        label_text = TexComplex(
            *t_bobjs,
            multiline=True,
            centered=True,
            align_y='center',
            scale=label_scale,
            name='label',
            location=(0, dy, 0),  #label_anchor
            rotation_euler=[
                0, 0, -gest.subbobjects[0].ref_obj.rotation_euler[2]
            ])

        gest.subbobjects[0].add_subbobject(label_text)
        self.add_subbobject(container)
示例#6
0
def import_object(filename, *folders, **kwargs):
    #Needs filename and the name of the template object to be the same
    DIR = BLEND_DIR
    for folder in folders:
        DIR = os.path.join(DIR, folder)

    filepath = os.path.join(DIR, filename) + '.blend'

    #Unsurprisingly, but for reasons not fully understood, this doesn't work
    #properly when the blender's open file is the one at the filepath.
    with bpy.data.libraries.load(filepath) as (data_from, data_to):
        data_to.objects = data_from.objects
        num = len([x for x in data_to.objects if filename in x])

    #Get most recent objects with the right kind of name
    #Matters when we want to import multiple objects from a .blend file
    #objs = [x for x in bpy.data.objects if filename == x.name]
    #obj_names = [x.name for x in objs]
    new_obj = None
    for object in bpy.data.objects:
        if object.name == filename:
            new_obj = object
    if new_obj == None:
        raise Warning('Did not find object with same name as file')

    #Make object and children names unique by adding a num in front
    #Blender already adds numbers to the end of names, but this allows more
    #than 1000 objects with the (otherwise) same name and groups metaballs
    #together.
    existing_names = [x.name for x in bpy.data.objects]
    count = 0
    prefix = str(count).zfill(4)
    name = prefix + new_obj.name
    while name in existing_names:
        count += 1
        prefix = str(count).zfill(4)
        name = prefix + new_obj.name
    new_obj.name = name
    #Give children a unique prefix to separate metaball groups
    #Would need to expand this if importing more complex files where children
    #have children
    for child in new_obj.children:
        child.name = new_obj.name + child.name

    if 'name' not in kwargs.keys():
        name = new_obj.name
        kwargs['name'] = name

    #If this is an svg from blend, make subbobjects out of children before
    #making the final bobject.
    '''if 'svg' in kwargs and kwargs['svg'] == True:
        #print('bananananan')
        subbobjs = []
        for child in new_obj.children:
            child_bobj = bobject.Bobject(objects = [child])
            subbobjs.append(child_bobj)
        new_bobject = bobject.Bobject(*subbobjs, **kwargs)
    else:'''
    new_bobject = bobject.Bobject(objects=[new_obj], **kwargs)

    #Blinks
    ref_obj = new_bobject.ref_obj
    if filename == 'boerd_blob' or filename == 'boerd_blob_squat':
        leye = ref_obj.children[0].pose.bones[5]
        reye = ref_obj.children[0].pose.bones[6]
        t = 0
        if 'cycle_length' not in kwargs:
            cycle_length = BLINK_CYCLE_LENGTH
        else:
            cycle_length = kwargs['cycle_length']

        leye.keyframe_insert(data_path='scale', frame=0)
        leye.keyframe_insert(data_path='scale', frame=BLINK_CYCLE_LENGTH)
        reye.keyframe_insert(data_path='scale', frame=0)
        reye.keyframe_insert(data_path='scale', frame=BLINK_CYCLE_LENGTH)

        while t < cycle_length - BLINK_LENGTH:
            blink_roll = random()
            if blink_roll < BLINK_CHANCE:
                leye.keyframe_insert(data_path='scale', frame=t)
                leye.scale[1] = 0.2
                frm = math.floor(BLINK_LENGTH / 2) - 1
                leye.keyframe_insert(data_path='scale', frame=t + frm)
                frm = math.ceil(BLINK_LENGTH / 2) + 1
                leye.keyframe_insert(data_path='scale', frame=t + frm)
                leye.scale[1] = 1
                leye.keyframe_insert(data_path='scale', frame=t + BLINK_LENGTH)

                reye.keyframe_insert(data_path='scale', frame=t)
                reye.scale[1] = 0.2
                frm = math.floor(BLINK_LENGTH / 2) - 1
                reye.keyframe_insert(data_path='scale', frame=t + frm)
                frm = math.ceil(BLINK_LENGTH / 2) + 1
                reye.keyframe_insert(data_path='scale', frame=t + frm)
                reye.scale[1] = 1
                reye.keyframe_insert(data_path='scale', frame=t + BLINK_LENGTH)

                t += BLINK_LENGTH

            else:
                t += 1
        #Make blinks cyclical
        try:
            leye_fcurve = ref_obj.children[
                0].animation_data.action.fcurves.find(
                    'pose.bones["brd_bone_eye.l"].scale', index=1)
            l_cycle = leye_fcurve.modifiers.new(type='CYCLES')
            #l_cycle.blend_out = BLINK_CYCLE_LENGTH

            reye_fcurve = ref_obj.children[
                0].animation_data.action.fcurves.find(
                    'pose.bones["brd_bone_eye.r"].scale', index=1)
            r_cycle = reye_fcurve.modifiers.new(type='CYCLES')
            #r_cycle.blend_out = BLINK_CYCLE_LENGTH
        except:
            #Sometimes a creature goes the whole cycle length without blinking,
            #in which case, there's no fcurve, so the above block throws an
            #error. In the end, it's fine if the creature never blinks. It's rare.
            pass

    #Wiggles
    if 'wiggle' in kwargs:
        wiggle = kwargs['wiggle']
    else:
        wiggle = False
    if (filename == 'boerd_blob' or filename == 'boerd_blob_squat') \
        and wiggle == True:
        if 'cycle_length' not in kwargs:
            wiggle_cycle_length = BLINK_CYCLE_LENGTH
        else:
            wiggle_cycle_length = int(kwargs['cycle_length'])
        wiggle_slow_factor = 1
        wind_down_time = FRAME_RATE / wiggle_slow_factor

        new_bobject.head_angle = [None] * wiggle_cycle_length
        new_bobject.head_angle_vel = [None] * wiggle_cycle_length
        for t in range(wiggle_cycle_length):
            if t == 0:
                #Start in neutral position
                new_bobject.head_angle[t] = [
                    1,
                    uniform(0, 0),
                    uniform(0, 0),
                    uniform(0, 0),
                ]
                new_bobject.head_angle_vel[t] = [
                    0,
                    uniform(-0.0025, 0.0025),
                    uniform(-0.0025, 0.0025),
                    uniform(-0.0025, 0.0025)
                ]
                bone = ref_obj.children[0].pose.bones[3]
                bone.rotation_quaternion = new_bobject.head_angle[t]
                bone.keyframe_insert(data_path="rotation_quaternion",
                                     frame=t * wiggle_slow_factor)
            elif t < wiggle_cycle_length - wind_down_time:
                #Random movement up to a half second before end of cycle.
                #update position
                a = new_bobject.head_angle[t - 1]
                b = new_bobject.head_angle_vel[t - 1]
                new_bobject.head_angle[t] = list(map(sum, zip(a, b)))

                #Hard max on head angles
                extrema = [[1, 1], [-0.05, 0.05], [-0.05, 0.05], [-0.05, 0]]
                a = new_bobject.head_angle[t]
                for i in range(1, len(new_bobject.head_angle[t])):
                    if a[i] < extrema[i][0]:
                        a[i] = extrema[i][0]
                    if a[i] > extrema[i][1]:
                        a[i] = extrema[i][1]

                #update velocity to be used when updating position
                #in next frame
                a = new_bobject.head_angle_vel[t - 1]
                b = [
                    0,
                    uniform(-0.0005, 0.0005),
                    uniform(-0.0005, 0.0005),
                    uniform(-0.0005, 0.0005)
                ]
                #Shift the acceleration distribution toward neutral
                for i in range(1, len(b)):
                    go_back = -new_bobject.head_angle[t][i] / 5000
                    b[i] += go_back
                new_bobject.head_angle_vel[t] = list(map(sum, zip(a, b)))

                bone = ref_obj.children[0].pose.bones[3]
                bone.rotation_quaternion = new_bobject.head_angle[t]
                bone.keyframe_insert(data_path="rotation_quaternion",
                                     frame=t * wiggle_slow_factor)
            else:
                #Approach neutral toward end of cycle, for continuity across
                #scenes
                #update position
                a = new_bobject.head_angle[t - 1]
                b = new_bobject.head_angle_vel[t - 1]
                new_bobject.head_angle[t] = list(map(sum, zip(a, b)))

                #Hard max on head angles
                extrema = [[1, 1], [-0.1, 0.1], [-0.1, 0.1], [-0.1, 0]]
                a = new_bobject.head_angle[t]
                for i in range(1, len(new_bobject.head_angle[t])):
                    if a[i] < extrema[i][0]:
                        a[i] = extrema[i][0]
                        if b[i] < 0: b[i] = 0
                    if a[i] > extrema[i][1]:
                        a[i] = extrema[i][1]
                        if b[i] > 0: b[i] = 0

                #update velocity to be used when updating position
                #in next frame
                #Calculate acceleration needed to get back to neutral

                time_left = wiggle_cycle_length - t
                timing_factor = (wind_down_time - time_left) * time_left \
                                        / wind_down_time ** 2
                target_v = [  #Approaches zero as distance goes to zero
                    -a[1] * timing_factor,
                    -a[2] * timing_factor,
                    -a[3] * timing_factor,
                ]

                acc_x = (target_v[0] - b[1]) / 2
                acc_y = (target_v[1] - b[2]) / 2
                acc_z = (target_v[2] - b[3]) / 2

                a = new_bobject.head_angle_vel[t - 1]
                b = [
                    0,
                    acc_x,
                    acc_y,
                    acc_z,
                ]

                new_bobject.head_angle_vel[t] = list(map(sum, zip(a, b)))

                bone = ref_obj.children[0].pose.bones[3]
                bone.rotation_quaternion = new_bobject.head_angle[t]
                bone.keyframe_insert(data_path="rotation_quaternion",
                                     frame=t * wiggle_slow_factor)

        #Make wiggle cyclical
        bone_x_fcurve = ref_obj.children[0].animation_data.action.fcurves.find(
            'pose.bones["brd_bone_neck"].rotation_quaternion', index=0)
        neck_x_cycle = bone_x_fcurve.modifiers.new(type='CYCLES')
        neck_x_cycle.frame_start = 0
        neck_x_cycle.frame_end = wiggle_cycle_length * wiggle_slow_factor

        bone_y_fcurve = ref_obj.children[0].animation_data.action.fcurves.find(
            'pose.bones["brd_bone_neck"].rotation_quaternion', index=1)
        neck_y_cycle = bone_y_fcurve.modifiers.new(type='CYCLES')
        neck_y_cycle.frame_start = 0
        neck_y_cycle.frame_end = wiggle_cycle_length * wiggle_slow_factor

        bone_z_fcurve = ref_obj.children[0].animation_data.action.fcurves.find(
            'pose.bones["brd_bone_neck"].rotation_quaternion', index=2)
        neck_z_cycle = bone_z_fcurve.modifiers.new(type='CYCLES')
        neck_z_cycle.frame_start = 0
        neck_z_cycle.frame_end = wiggle_cycle_length * wiggle_slow_factor

    if filename == 'stanford_bunny':
        eye = ref_obj.children[0].children[0]
        t = 0
        while t < BLINK_CYCLE_LENGTH:
            blink_roll = random()
            if blink_roll < BLINK_CHANCE:
                eye.keyframe_insert(data_path='scale', frame=t)
                eye.scale[1] = 0.2
                frm = math.floor(BLINK_LENGTH / 2) - 1
                eye.keyframe_insert(data_path='scale', frame=t + frm)
                frm = math.ceil(BLINK_LENGTH / 2) + 1
                eye.keyframe_insert(data_path='scale', frame=t + frm)
                eye.scale[1] = 1
                eye.keyframe_insert(data_path='scale', frame=t + BLINK_LENGTH)

                t += BLINK_LENGTH
            else:
                t += 1
        #Make blinks cyclical
        try:
            eye_fcurve = ref_obj.children[0].children[
                0].animation_data.action.fcurves.find('scale', index=1)
            cycle = eye_fcurve.modifiers.new(type='CYCLES')
            cycle.frame_start = 0
            cycle.frame_end = BLINK_CYCLE_LENGTH
        except:
            #Sometimes a creature goes the whole cycle length without blinking,
            #in which case, there's no fcurve, so the above block throws an
            #error. In the end, it's fine if the creature never blinks. It's rare.
            pass

    return new_bobject
示例#7
0
    def add_to_blender(self, **kwargs):
        super().add_to_blender(**kwargs)
        '''
        Pretty hacky due to the fact that the TexBobject class was created
        before the SVGBobject class, despite inheritance going the other direction
        '''

        appear_frame = kwargs['appear_frame']
        try:
            name = self.file_name
            path = os.path.join(SVG_DIR, name) + ".svg"
            #print(path)

            previous_curves = [
                obj for obj in bpy.data.objects if obj.type == 'CURVE'
            ]
            bpy.ops.import_curve.svg(filepath=path)
            new_curves = [obj for obj in bpy.data.objects if obj.type == 'CURVE' and \
                                                            obj not in previous_curves]
            print(new_curves)
            LOCAL_SCALE_UP = 260  #Value that makes line height about 1 Blender Unit
            scale_up = LOCAL_SCALE_UP  #* self.size

            for i, curve in enumerate(new_curves):
                for spline in curve.data.splines:
                    for point in spline.bezier_points:
                        point.handle_left_type = 'FREE'
                        point.handle_right_type = 'FREE'

                #This needs to be in a separate loop because moving points before
                #they're all 'Free' type makes the shape warp.
                #It makes a cool "disappear in the wind" visual, though.
                for spline in curve.data.splines:
                    for point in spline.bezier_points:
                        for i in range(len(point.co)):
                            point.co[i] *= scale_up
                            point.handle_left[i] *= scale_up
                            point.handle_right[i] *= scale_up

                curve.select = True
                bpy.ops.object.origin_set(type="ORIGIN_GEOMETRY")
                curve.select = False

                #for i, curve in enumerate(new_curves):
                #    curve.parent = self.ref_obj
                #    curve.matrix_parent_inverse = curve.parent.matrix_world.inverted()

            for curve in new_curves:
                #curve = expression['curves'][i]
                curve_bobj = bobject.Bobject()
                print('making bobject')
                curve_bobj.ref_obj.matrix_local = deepcopy(curve.matrix_local)
                curve_bobj.ref_obj.parent = self.ref_obj
                curve.parent = curve_bobj.ref_obj
                curve.location = [0, 0, 0]
                #curve.matrix_parent_inverse = curve.parent.matrix_world.inverted()
                curve_bobj.objects.append(curve)
                self.subbobjects.append(curve_bobj)
                curve_bobj.superbobject = self
                #if expression == self.expressions[0]:
                bpy.context.scene.objects.unlink(curve)
                curve_bobj.add_to_blender(appear_frame=appear_frame,
                                          animate=False)

        except:
            print('No SVG file')
示例#8
0
    def asymmetrical_inputs(self):
        cam_bobj, cam_swivel = cam_and_swivel(
            cam_location=[0, 0, 100],
            cam_rotation_euler=[0, 0, 0],
            cam_name="Camera Bobject",
            swivel_location=[0, 5.1, -2],
            swivel_rotation_euler=[75 * math.pi / 180, 0, 135 * math.pi / 180],
            swivel_name='Cam swivel',
            #control_sun = True
        )
        cam_swivel.add_to_blender(appear_time=-1)
        cam_bobj.ref_obj.children[0].data.clip_end = 200

        rot_start = 78

        l_green_time = 80.5
        l_back_time = 85.5
        spin_time_1 = 83
        spins_1 = 5
        spin_duration_1 = 3

        r_red_time = 90.5
        r_back_time = 102.5
        spin_time_2 = 100
        spins_2 = 5
        spin_duration_2 = 3

        skin = bpy.data.objects['robertot']
        r_inner_ear = bpy.data.objects['inner ear_from microCT']
        l_inner_ear = bpy.data.objects['inner ear_from microCT.001']
        to_keep = [skin, r_inner_ear, l_inner_ear]
        for obj in bpy.data.objects:
            if obj not in to_keep:
                obj.hide = True
                obj.hide_render = True

        mix = skin.material_slots[0].material.node_tree.nodes[
            'Mix Shader'].inputs[0]
        mix.default_value = 0.9

        #Prep inner ear materials
        slots = r_inner_ear.material_slots
        v_sys_mats = [
            slots[0].material, slots[1].material, slots[2].material,
            slots[3].material, slots[4].material
        ]
        #Set initial state for inner ear materials
        for mat in v_sys_mats:
            nodes = mat.node_tree.nodes
            mix = nodes['Mix Shader']
            mix.inputs[0].default_value = 0
            #princ = nodes['Principled BSDF']
            #color = princ.inputs[0]
            #color.default_value = [0, 1, 0, 1]

        #Make separate materials for left inner ear to animate separately
        for slot in l_inner_ear.material_slots:
            mat_copy = slot.material.copy()
            slot.material = mat_copy

        #Turn left inner ear green and back
        for slot in l_inner_ear.material_slots:
            nodes = slot.material.node_tree.nodes
            color = nodes['Principled BSDF'].inputs[0]
            initial_color = list(color.default_value)

            color.keyframe_insert(data_path='default_value',
                                  frame=l_green_time * FRAME_RATE)
            color.default_value = [0, 1, 0, 1]
            color.keyframe_insert(data_path='default_value',
                                  frame=l_green_time * FRAME_RATE +
                                  2 * OBJECT_APPEARANCE_TIME)
            color.keyframe_insert(data_path='default_value',
                                  frame=l_back_time * FRAME_RATE)
            color.default_value = initial_color
            color.keyframe_insert(data_path='default_value',
                                  frame=l_back_time * FRAME_RATE +
                                  2 * OBJECT_APPEARANCE_TIME)

        #Turn right inner ear red and back
        for mat in v_sys_mats:
            nodes = mat.node_tree.nodes
            color = nodes['Principled BSDF'].inputs[0]
            initial_color = list(color.default_value)

            color.keyframe_insert(data_path='default_value',
                                  frame=r_red_time * FRAME_RATE)
            color.default_value = [1, 0, 0, 1]
            color.keyframe_insert(data_path='default_value',
                                  frame=r_red_time * FRAME_RATE +
                                  2 * OBJECT_APPEARANCE_TIME)
            color.keyframe_insert(data_path='default_value',
                                  frame=r_back_time * FRAME_RATE)
            color.default_value = initial_color
            color.keyframe_insert(data_path='default_value',
                                  frame=r_back_time * FRAME_RATE +
                                  2 * OBJECT_APPEARANCE_TIME)

        #Spins
        skull = bpy.data.objects['Skull_Top']
        skull_bobj = bobject.Bobject(objects=[skull])
        skull_bobj.add_to_blender(appear_time=0, unhide=False)
        skull_bobj.move_to(new_angle=[0, 0, spins_1 * 2 * math.pi],
                           start_time=spin_time_1,
                           end_time=spin_time_1 + spin_duration_1)

        skull_bobj.move_to(new_angle=[
            skull_bobj.ref_obj.rotation_euler[0],
            skull_bobj.ref_obj.rotation_euler[1],
            skull_bobj.ref_obj.rotation_euler[2] + spins_2 * 2 * math.pi,
        ],
                           start_time=spin_time_2,
                           end_time=spin_time_2 + spin_duration_2)

        cam_swivel.move_to(
            new_angle=[75 * math.pi / 180, 0, 45 * math.pi / 180],
            start_time=rot_start,
            end_time=r_red_time)
        cam_swivel.move_to(
            new_angle=[75 * math.pi / 180, 0, 135 * math.pi / 180],
            start_time=r_red_time,
            end_time=spin_time_2 + spin_duration_2)
        '''rate = 0.025
示例#9
0
    def asymmetrical_inputs(self):
        cam_bobj, cam_swivel = cam_and_swivel(
            cam_location=[0, 0, 100],
            cam_rotation_euler=[0, 0, 0],
            cam_name="Camera Bobject",
            swivel_location=[0, 5.1, -2],
            swivel_rotation_euler=[75 * math.pi / 180, 0, 135 * math.pi / 180],
            swivel_name='Cam swivel',
            #control_sun = True
        )
        cam_swivel.add_to_blender(appear_time=-1)
        cam_bobj.ref_obj.children[0].data.clip_end = 200

        l_red_time = 115
        spin_time = 117.5
        spins = 6
        spin_duration = 6
        r_red_time = 122.5

        skin = bpy.data.objects['robertot']
        r_inner_ear = bpy.data.objects['inner ear_from microCT']
        l_inner_ear = bpy.data.objects['inner ear_from microCT.001']
        to_keep = [skin, r_inner_ear, l_inner_ear]
        for obj in bpy.data.objects:
            if obj not in to_keep:
                obj.hide = True
                obj.hide_render = True

        mix = skin.material_slots[0].material.node_tree.nodes[
            'Mix Shader'].inputs[0]
        mix.default_value = 0.9

        slots = r_inner_ear.material_slots
        v_sys_mats = [
            slots[0].material, slots[1].material, slots[2].material,
            slots[3].material, slots[4].material
        ]
        #Set initial state for inner ear materials
        for mat in v_sys_mats:
            nodes = mat.node_tree.nodes
            mix = nodes['Mix Shader']
            mix.inputs[0].default_value = 0
            princ = nodes['Principled BSDF']
            color = princ.inputs[0]
            color.default_value = [0, 1, 0, 1]

        #Make separate materials for left inner ear to animate separately
        for slot in l_inner_ear.material_slots:
            mat_copy = slot.material.copy()
            slot.material = mat_copy

        for mat in v_sys_mats:
            nodes = mat.node_tree.nodes
            princ = nodes['Principled BSDF']
            color = princ.inputs[0]

            color.keyframe_insert(data_path='default_value',
                                  frame=l_red_time * FRAME_RATE)
            color.default_value = [1, 0, 0, 1]
            color.keyframe_insert(data_path='default_value',
                                  frame=l_red_time * FRAME_RATE +
                                  2 * OBJECT_APPEARANCE_TIME)

        skull = bpy.data.objects['Skull_Top']
        skull_bobj = bobject.Bobject(objects=[skull])
        skull_bobj.add_to_blender(appear_time=0, unhide=False)
        skull_bobj.move_to(new_angle=[0, 0, spins * 2 * math.pi],
                           start_time=spin_time,
                           end_time=spin_time + spin_duration)

        for slot in l_inner_ear.material_slots:
            nodes = slot.material.node_tree.nodes
            color = nodes['Principled BSDF'].inputs[0]

            color.keyframe_insert(data_path='default_value',
                                  frame=r_red_time * FRAME_RATE)
            color.default_value = [1, 0, 0, 1]
            color.keyframe_insert(data_path='default_value',
                                  frame=r_red_time * FRAME_RATE +
                                  2 * OBJECT_APPEARANCE_TIME)

        cam_swivel.move_to(
            new_angle=[75 * math.pi / 180, 0, 45 * math.pi / 180],
            start_time=110,
            end_time=127)
        '''rate = 0.025