Загрузка данных
import bpy
import math
import random
from mathutils import Vector
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)
for m in list(bpy.data.materials):
bpy.data.materials.remove(m)
def c_mat(c, r=0.5, m=0.0, em=0.0):
mat = bpy.data.materials.new("Material")
mat.use_nodes = True
b = mat.node_tree.nodes.get("Principled BSDF")
if b:
b.inputs['Base Color'].default_value = c
b.inputs['Roughness'].default_value = r
b.inputs['Metallic'].default_value = m
if em > 0:
if 'Emission Color' in b.inputs:
b.inputs['Emission Color'].default_value = c
b.inputs['Emission Strength'].default_value = em
elif 'Emission' in b.inputs:
b.inputs['Emission'].default_value = c
if 'Emission Strength' in b.inputs:
b.inputs['Emission Strength'].default_value = em
return mat
m_sea = c_mat((0.01, 0.035, 0.07, 1.0), r=0.12, m=0.1)
m_wood_dark = c_mat((0.14, 0.07, 0.03, 1.0), r=0.75)
m_wood_deck = c_mat((0.28, 0.16, 0.07, 1.0), r=0.65)
m_sail = c_mat((0.75, 0.72, 0.65, 1.0), r=0.8)
m_iron = c_mat((0.12, 0.13, 0.15, 1.0), r=0.35, m=0.85)
m_lantern = c_mat((1.0, 0.65, 0.15, 1.0), r=0.2, em=12.0)
m_kraken = c_mat((0.28, 0.04, 0.18, 1.0), r=0.25)
m_sucker = c_mat((0.65, 0.25, 0.35, 1.0), r=0.35)
m_eye = c_mat((1.0, 0.85, 0.1, 1.0), r=0.1, em=15.0)
m_skin = c_mat((0.82, 0.62, 0.48, 1.0), r=0.55)
m_shirt = c_mat((0.85, 0.12, 0.12, 1.0), r=0.6)
m_pants = c_mat((0.1, 0.22, 0.55, 1.0), r=0.7)
m_shoes = c_mat((0.9, 0.9, 0.92, 1.0), r=0.4)
m_rain = c_mat((0.55, 0.75, 1.0, 1.0), r=0.1, em=1.5)
m_bolt = c_mat((0.75, 0.9, 1.0, 1.0), r=0.1, em=45.0)
world = bpy.context.scene.world
if not world:
world = bpy.data.worlds.new("World")
bpy.context.scene.world = world
world.use_nodes = True
bg_node = world.node_tree.nodes.get("Background")
if bg_node:
bg_node.inputs[0].default_value = (0.015, 0.025, 0.045, 1.0)
bg_node.inputs[1].default_value = 0.3
def make_limb_cyl(r1, r2, length, mat, segs=12, parent=None, loc=(0, 0, 0)):
bpy.ops.mesh.primitive_cone_add(vertices=segs, radius1=r1, radius2=r2, depth=length, location=(0, 0, 0))
o = bpy.context.active_object
for v in o.data.vertices:
v.co.z += length * 0.5
o.data.update()
o.data.materials.append(mat)
if parent:
o.parent = parent
o.location = loc
return o
def make_limb_box(sx, sy, sz, mat, parent=None, loc=(0, 0, 0), pivot_z=0.0):
bpy.ops.mesh.primitive_cube_add(size=1.0, location=(0, 0, 0))
o = bpy.context.active_object
for v in o.data.vertices:
v.co.x *= sx
v.co.y *= sy
v.co.z = (v.co.z + pivot_z) * sz
o.data.update()
o.data.materials.append(mat)
if parent:
o.parent = parent
o.location = loc
return o
bpy.ops.mesh.primitive_grid_add(x_subdivisions=70, y_subdivisions=70, size=140.0, location=(0, 0, 0))
ocean = bpy.context.active_object
ocean.data.materials.append(m_sea)
bpy.ops.object.shade_smooth()
w1 = ocean.modifiers.new("Wave", 'WAVE')
w1.height = 0.65
w1.width = 4.5
w1.narrowness = 1.4
w1.speed = 0.35
w2 = ocean.modifiers.new("Wave.001", 'WAVE')
w2.use_x = False
w2.use_y = True
w2.height = 0.4
w2.width = 3.2
w2.narrowness = 1.8
w2.speed = 0.45
bpy.ops.mesh.primitive_cube_add(size=1.0, location=(0, -12, 0.2))
ship = bpy.context.active_object
hull_levels = [
(-0.8, [(0.0, -5.2), (1.1, -4.5), (1.4, -1.5), (1.4, 2.0), (0.9, 4.2), (0.0, 5.2)]),
( 0.2, [(0.0, -5.8), (1.7, -4.8), (2.2, -1.5), (2.2, 2.2), (1.5, 4.6), (0.0, 5.8)]),
( 1.2, [(0.0, -6.2), (2.1, -5.0), (2.6, -1.5), (2.6, 2.4), (1.8, 5.0), (0.0, 6.6)]),
( 1.9, [(0.0, -6.4), (2.2, -5.1), (2.7, -1.5), (2.7, 2.5), (1.9, 5.2), (0.0, 7.0)])
]
h_verts = []
h_faces = []
ring_len = 10
for z, prof in hull_levels:
ring = []
ring.append((0.0, prof[0][1], z))
for x, y in prof[1:-1]:
ring.append((x, y, z))
ring.append((0.0, prof[-1][1], z))
for x, y in reversed(prof[1:-1]):
ring.append((-x, y, z))
h_verts.extend(ring)
for l in range(len(hull_levels) - 1):
b = l * ring_len
t = (l + 1) * ring_len
for i in range(ring_len):
ni = (i + 1) % ring_len
h_faces.append([b + i, b + ni, t + ni, t + i])
b_top = (len(hull_levels) - 1) * ring_len
h_faces.append(list(range(ring_len - 1, -1, -1)))
h_faces.append([b_top + i for i in range(ring_len)])
ship.data.clear_geometry()
ship.data.from_pydata(h_verts, [], h_faces)
ship.data.update()
ship.data.materials.append(m_wood_dark)
make_limb_box(4.6, 9.6, 0.15, m_wood_deck, ship, (0, 0.2, 1.9), 0.0)
make_limb_box(3.8, 3.0, 1.3, m_wood_dark, ship, (0, -4.4, 1.9), 0.5)
make_limb_box(4.1, 3.3, 0.15, m_wood_deck, ship, (0, -4.4, 3.2), 0.0)
for wx in [-1.1, 0.0, 1.1]:
make_limb_box(0.5, 0.1, 0.5, m_lantern, ship, (wx, -2.9, 2.55), 0.0)
for side in [-1, 1]:
make_limb_box(0.18, 7.5, 0.18, m_wood_dark, ship, (side * 2.45, 0.8, 2.55), 0.0)
for py in [-2.6, -1.4, -0.2, 1.0, 2.2, 3.4, 4.4]:
make_limb_box(0.14, 0.14, 0.65, m_wood_dark, ship, (side * 2.45, py, 1.9), 0.5)
bowsprit = make_limb_cyl(0.18, 0.08, 4.2, m_wood_dark, 10, ship, (0, 5.8, 1.95))
bowsprit.rotation_euler.x = math.radians(-68)
masts_cfg = [(0.0, 0.5, 8.5, 1.0), (0.0, 3.6, 6.8, 0.8), (0.0, -3.8, 6.2, 0.75)]
sails = []
for mx, my, mh, sc in masts_cfg:
make_limb_cyl(0.22 * sc, 0.12 * sc, mh, m_wood_dark, 12, ship, (mx, my, 1.9))
for sz, sh, sw in [(mh * 0.45, mh * 0.32, 4.4 * sc), (mh * 0.8, mh * 0.24, 3.4 * sc)]:
bpy.ops.mesh.primitive_cylinder_add(vertices=10, radius=0.09 * sc, depth=sw + 0.6, location=(0, 0, 0), rotation=(0, math.radians(90), 0))
yard = bpy.context.active_object
yard.data.materials.append(m_wood_dark)
yard.parent = ship
yard.location = (mx, my, 1.9 + sz + sh * 0.5)
bpy.ops.mesh.primitive_grid_add(x_subdivisions=8, y_subdivisions=8, size=1.0, location=(0, 0, 0))
sl = bpy.context.active_object
for v in sl.data.vertices:
nx = v.co.x * 2.0
ny = v.co.y * 2.0
bulge = (1.0 - nx * nx) * (1.0 - ny * ny) * 0.65
v.co.x = v.co.x * sw
v.co.z = v.co.y * sh
v.co.y = bulge + 0.12
sl.data.update()
sl.data.materials.append(m_sail)
sl.parent = ship
sl.location = (mx, my, 1.9 + sz)
sails.append(sl)
bpy.ops.mesh.primitive_torus_add(major_radius=0.45, minor_radius=0.05, location=(0, 0, 0), rotation=(math.radians(90), 0, 0))
wheel = bpy.context.active_object
wheel.data.materials.append(m_wood_dark)
wheel.parent = ship
wheel.location = (0, -3.3, 3.85)
make_limb_box(0.2, 0.2, 0.65, m_wood_dark, ship, (0, -3.4, 3.2), 0.5)
lantern_pivots = []
for lx, ly, lz in [(-1.6, -2.85, 3.0), (1.6, -2.85, 3.0), (0.0, 0.5, 4.8)]:
lp = make_limb_cyl(0.03, 0.03, 0.35, m_iron, 6, ship, (lx, ly, lz))
lp.rotation_euler.x = math.radians(180)
bulb = make_limb_cyl(0.14, 0.1, 0.28, m_lantern, 8, lp, (0, 0, 0.35))
bpy.ops.object.light_add(type='POINT', location=(0, 0, 0))
pt = bpy.context.active_object
pt.data.energy = 180.0
pt.data.color = (1.0, 0.6, 0.2)
pt.parent = bulb
pt.location = (0, 0, 0.15)
lantern_pivots.append(lp)
d_root = make_limb_box(0.36, 0.22, 0.2, m_pants, ship, (0.0, 1.3, 2.0), 0.0)
d_torso = make_limb_box(0.42, 0.24, 0.55, m_shirt, d_root, (0, 0, 0.1), 0.5)
d_head = make_limb_box(0.26, 0.26, 0.28, m_skin, d_torso, (0, 0, 0.58), 0.5)
make_limb_cyl(0.16, 0.15, 0.12, m_shirt, 12, d_head, (0, 0, 0.2))
d_arm_u_l = make_limb_cyl(0.08, 0.065, 0.38, m_shirt, 8, d_torso, (0.26, 0, 0.48))
d_arm_l_l = make_limb_cyl(0.065, 0.05, 0.36, m_skin, 8, d_arm_u_l, (0, 0, 0.38))
d_arm_u_r = make_limb_cyl(0.08, 0.065, 0.38, m_shirt, 8, d_torso, (-0.26, 0, 0.48))
d_arm_l_r = make_limb_cyl(0.065, 0.05, 0.36, m_skin, 8, d_arm_u_r, (0, 0, 0.38))
d_leg_u_l = make_limb_cyl(0.11, 0.085, 0.48, m_pants, 8, d_root, (0.13, 0, -0.05))
d_leg_l_l = make_limb_cyl(0.085, 0.065, 0.46, m_pants, 8, d_leg_u_l, (0, 0, 0.48))
make_limb_box(0.14, 0.28, 0.1, m_shoes, d_leg_l_l, (0, -0.06, 0.48), 0.5)
d_leg_u_r = make_limb_cyl(0.11, 0.085, 0.48, m_pants, 8, d_root, (-0.13, 0, -0.05))
d_leg_l_r = make_limb_cyl(0.085, 0.065, 0.46, m_pants, 8, d_root, (-0.13, 0, -0.05))
d_leg_l_r.parent = d_leg_u_r
d_leg_l_r.location = (0, 0, 0.48)
make_limb_box(0.14, 0.28, 0.1, m_shoes, d_leg_l_r, (0, -0.06, 0.48), 0.5)
k_head = make_limb_cyl(1.6, 0.4, 3.8, m_kraken, 16, ship, (4.5, 0.5, -0.6))
for ex in [-0.55, 0.55]:
bpy.ops.mesh.primitive_uv_sphere_add(segments=12, ring_count=8, radius=0.28, location=(0, 0, 0))
eye = bpy.context.active_object
eye.data.materials.append(m_eye)
eye.parent = k_head
eye.location = (ex, -1.15, 1.2)
def build_tentacle(base_loc, base_rot, seg_count=9, base_r=0.42, seg_len=0.72, parent_obj=ship):
segs = []
curr_parent = parent_obj
for i in range(seg_count):
t = i / seg_count
r1 = base_r * (1.0 - t * 0.85)
r2 = base_r * (1.0 - (t + 1.0 / seg_count) * 0.85)
l = seg_len * (1.0 - t * 0.25)
loc = base_loc if i == 0 else (0, 0, prev_l * 0.92)
seg = make_limb_cyl(r1, r2, l, m_kraken, 10, curr_parent, loc)
if i == 0:
seg.rotation_euler = base_rot
if 1 <= i <= seg_count - 2:
for sx in [-r1 * 0.45, r1 * 0.45]:
bpy.ops.mesh.primitive_cylinder_add(vertices=8, radius=r1 * 0.32, depth=r1 * 0.35, location=(0, 0, 0), rotation=(math.radians(90), 0, 0))
sc_cup = bpy.context.active_object
sc_cup.data.materials.append(m_sucker)
sc_cup.parent = seg
sc_cup.location = (sx, -r1 * 0.85, l * 0.5)
segs.append(seg)
curr_parent = seg
prev_l = l
return segs
t_star_slam = build_tentacle((2.75, 0.2, 0.2), (0, 0, math.radians(-90)), 9, 0.44, 0.72, ship)
t_star_bow = build_tentacle((2.65, 2.8, 0.3), (0, 0, math.radians(-105)), 9, 0.40, 0.68, ship)
t_port_grab = build_tentacle((-2.75, 1.5, 0.2), (0, 0, math.radians(90)), 9, 0.42, 0.72, ship)
t_port_stern = build_tentacle((-2.70, -1.8, 0.3), (0, 0, math.radians(80)), 9, 0.40, 0.68, ship)
t_sea_1 = build_tentacle((5.8, 3.8, -1.2), (0, 0, math.radians(-120)), 8, 0.50, 0.85, ship)
t_sea_2 = build_tentacle((-5.6, -0.5, -1.2), (0, 0, math.radians(100)), 8, 0.50, 0.85, ship)
bpy.ops.mesh.primitive_cylinder_add(vertices=6, radius=0.02, depth=0.65, location=(0, 0, -25))
rain_drop = bpy.context.active_object
rain_drop.data.materials.append(m_rain)
bpy.ops.mesh.primitive_plane_add(size=55.0, location=(0, 0, 22))
emitter = bpy.context.active_object
ps_mod = emitter.modifiers.new("ParticleSystem", 'PARTICLE_SYSTEM')
ps = emitter.particle_systems[0].settings
ps.count = 9000
ps.frame_start = -40
ps.frame_end = 250
ps.lifetime = 55
ps.render_type = 'OBJECT'
ps.instance_object = rain_drop
ps.particle_size = 1.0
ps.object_align_factor = (-3.5, -2.0, -26.0)
ps.effector_weights.gravity = 1.5
emitter.show_instancer_for_viewport = False
emitter.show_instancer_for_render = False
bolt_parts = []
bx, by, bz = -8.0, 22.0, 26.0
for bi in range(10):
nbx = bx + random.uniform(-1.8, 1.8)
nby = by + random.uniform(-0.8, 0.8)
nbz = bz - 2.6
vec = Vector((nbx - bx, nby - by, nbz - bz))
mid = Vector(((bx + nbx) * 0.5, (by + nby) * 0.5, (bz + nbz) * 0.5))
bpy.ops.mesh.primitive_cylinder_add(vertices=6, radius=0.22 * (1.0 - bi * 0.06), depth=vec.length, location=mid)
b_seg = bpy.context.active_object
b_seg.rotation_euler = vec.to_track_quat('Z', 'Y').to_euler()
b_seg.data.materials.append(m_bolt)
bolt_parts.append(b_seg)
bx, by, bz = nbx, nby, nbz
bpy.ops.object.select_all(action='DESELECT')
for bp in bolt_parts:
bp.select_set(True)
bpy.context.view_layer.objects.active = bolt_parts[0]
bpy.ops.object.join()
bolt_obj = bpy.context.active_object
bpy.ops.object.light_add(type='SUN', location=(8, -8, 15), rotation=(0.6, 0.2, 0.5))
sun = bpy.context.active_object
sun.data.energy = 0.25
sun.data.color = (0.25, 0.4, 0.7)
bpy.ops.object.light_add(type='POINT', location=(-4, 12, 24))
flash_light = bpy.context.active_object
flash_light.data.color = (0.75, 0.88, 1.0)
flash_light.data.energy = 0.0
bpy.ops.object.camera_add(location=(0, 0, 0))
cam = bpy.context.active_object
cam.data.lens = 24.0
cam.parent = ship
bpy.context.scene.camera = cam
bpy.context.scene.frame_start = 1
bpy.context.scene.frame_end = 250
flash_frames = {34, 35, 37, 94, 95, 98, 154, 155, 157, 212, 213, 215, 216}
slam_frames = [55, 135, 215]
for f in range(1, 251):
t = f / 250.0
ship.location.y = -14.0 + t * 28.0
ship.location.x = math.sin(f * 0.05) * 0.6
ship.location.z = 0.15 + math.sin(f * 0.11) * 0.35 + math.cos(f * 0.07) * 0.18
slam_shock = 0.0
for sf in slam_frames:
dist = f - sf
if 0 <= dist < 18:
slam_shock += math.exp(-dist * 0.25) * math.sin(dist * 1.8) * 0.09
ship.rotation_euler.x = math.sin(f * 0.09) * 0.09 + slam_shock * 0.5
ship.rotation_euler.y = math.sin(f * 0.07) * 0.14 + math.cos(f * 0.13) * 0.05 + slam_shock
ship.rotation_euler.z = math.sin(f * 0.04) * 0.06
ship.keyframe_insert(data_path="location", frame=f)
ship.keyframe_insert(data_path="rotation_euler", frame=f)
wheel.rotation_euler.y = math.sin(f * 0.08) * 2.5
wheel.keyframe_insert(data_path="rotation_euler", frame=f)
for idx, lp in enumerate(lantern_pivots):
lp.rotation_euler.x = math.radians(180) + math.sin(f * 0.14 + idx) * 0.35
lp.rotation_euler.y = math.cos(f * 0.11 + idx) * 0.45
lp.keyframe_insert(data_path="rotation_euler", frame=f)
for idx, sl in enumerate(sails):
sl.scale.y = 1.0 + math.sin(f * 0.25 + idx) * 0.12
sl.keyframe_insert(data_path="scale", frame=f)
k_head.location.z = -0.5 + math.sin(f * 0.08) * 0.55
k_head.rotation_euler.x = 0.25 + math.sin(f * 0.07) * 0.18
k_head.rotation_euler.y = -0.35 + math.cos(f * 0.09) * 0.15
k_head.keyframe_insert(data_path="location", frame=f)
k_head.keyframe_insert(data_path="rotation_euler", frame=f)
slam_phase = math.sin((f - 35) * (2.0 * math.pi / 80.0))
for i, seg in enumerate(t_star_slam):
if i == 0:
seg.rotation_euler.x = 0.25
elif i <= 3:
seg.rotation_euler.x = 0.38 + math.sin(f * 0.08 + i) * 0.06
else:
down_strike = max(0.0, slam_phase) ** 3
arch_up = max(0.0, -slam_phase)
seg.rotation_euler.x = 0.28 * down_strike - 0.22 * arch_up + math.sin(f * 0.15 + i) * 0.08
seg.rotation_euler.y = math.cos(f * 0.12 + i * 0.5) * 0.18
seg.keyframe_insert(data_path="rotation_euler", frame=f)
for i, seg in enumerate(t_star_bow):
if i > 0:
seg.rotation_euler.x = (0.35 if i <= 3 else 0.18) + math.sin(f * 0.11 - i * 0.4) * 0.15
seg.rotation_euler.y = math.cos(f * 0.09 + i * 0.5) * 0.22
seg.keyframe_insert(data_path="rotation_euler", frame=f)
for i, seg in enumerate(t_port_grab):
if i > 0:
seg.rotation_euler.x = (0.36 if i <= 3 else 0.22) + math.cos(f * 0.10 - i * 0.35) * 0.14
seg.rotation_euler.y = math.sin(f * 0.12 + i * 0.4) * 0.24
seg.keyframe_insert(data_path="rotation_euler", frame=f)
for i, seg in enumerate(t_port_stern):
if i > 0:
seg.rotation_euler.x = (0.34 if i <= 3 else 0.20) + math.sin(f * 0.13 + i * 0.4) * 0.16
seg.rotation_euler.y = math.cos(f * 0.10 - i * 0.3) * 0.20
seg.keyframe_insert(data_path="rotation_euler", frame=f)
for idx, sea_t in enumerate([t_sea_1, t_sea_2]):
for i, seg in enumerate(sea_t):
if i > 0:
seg.rotation_euler.x = 0.15 + math.sin(f * 0.12 - i * 0.5 + idx * 2.0) * 0.28
seg.rotation_euler.y = math.cos(f * 0.09 - i * 0.4 + idx) * 0.25
seg.keyframe_insert(data_path="rotation_euler", frame=f)
if f < 75:
spin_ang = f * 0.42
d_root.location = (math.cos(spin_ang * 0.5) * 0.18, 1.3 + math.sin(spin_ang * 0.5) * 0.18, 2.38)
d_root.rotation_euler = (2.35 + math.sin(spin_ang) * 0.25, math.cos(spin_ang) * 0.25, spin_ang)
d_torso.rotation_euler = (0.2, 0.0, math.sin(f * 0.3) * 0.2)
d_arm_u_l.rotation_euler = (1.35 + math.sin(spin_ang) * 0.3, 0.3, 0.0)
d_arm_u_r.rotation_euler = (1.35 - math.sin(spin_ang) * 0.3, -0.3, 0.0)
d_arm_l_l.rotation_euler = (0.4, 0, 0)
d_arm_l_r.rotation_euler = (0.4, 0, 0)
d_leg_u_l.rotation_euler = (math.sin(spin_ang) * 0.65, -0.65, 0.0)
d_leg_u_r.rotation_euler = (-math.sin(spin_ang) * 0.65, 0.65, 0.0)
d_leg_l_l.rotation_euler = (0.15, 0, 0)
d_leg_l_r.rotation_euler = (0.15, 0, 0)
elif f < 165:
spin_ang = f * 0.52
d_root.location = (0.0, 1.3, 2.82 + math.sin(f * 0.3) * 0.04)
d_root.rotation_euler = (math.pi + math.sin(f * 0.2) * 0.08, math.cos(f * 0.2) * 0.08, spin_ang)
d_torso.rotation_euler = (0.0, 0.0, 0.0)
d_arm_u_l.rotation_euler = (0.8, 0.9, 0.0)
d_arm_u_r.rotation_euler = (0.8, -0.9, 0.0)
d_arm_l_l.rotation_euler = (1.2, 0.0, 0.0)
d_arm_l_r.rotation_euler = (1.2, 0.0, 0.0)
split = 0.65 + math.sin(f * 0.25) * 0.25
d_leg_u_l.rotation_euler = (math.sin(f * 0.3) * 0.35, -split, 0.0)
d_leg_u_r.rotation_euler = (-math.sin(f * 0.3) * 0.35, split, 0.0)
d_leg_l_l.rotation_euler = (0.45 + math.cos(f * 0.3) * 0.35, 0, 0)
d_leg_l_r.rotation_euler = (0.45 - math.cos(f * 0.3) * 0.35, 0, 0)
else:
spin_ang = f * 0.38
d_root.location = (0.0, 1.3, 2.52 + abs(math.sin(f * 0.25)) * 0.15)
d_root.rotation_euler = (2.55, 0.35 * math.sin(f * 0.15), spin_ang)
d_torso.rotation_euler = (0.25, 0.0, 0.0)
d_arm_u_l.rotation_euler = (1.65, 0.15, 0.0)
d_arm_u_r.rotation_euler = (0.4, -0.8, 0.0)
d_arm_l_l.rotation_euler = (0.15, 0.0, 0.0)
d_arm_l_r.rotation_euler = (0.9, 0.0, 0.0)
d_leg_u_l.rotation_euler = (0.5 + math.sin(f * 0.4) * 0.5, -0.55, 0.0)
d_leg_u_r.rotation_euler = (-0.5 - math.sin(f * 0.4) * 0.5, 0.55, 0.0)
d_leg_l_l.rotation_euler = (0.3, 0, 0)
d_leg_l_r.rotation_euler = (0.6, 0, 0)
for part in [d_root, d_torso, d_arm_u_l, d_arm_u_r, d_arm_l_l, d_arm_l_r, d_leg_u_l, d_leg_u_r, d_leg_l_l, d_leg_l_r]:
part.keyframe_insert(data_path="rotation_euler", frame=f)
d_root.keyframe_insert(data_path="location", frame=f)
is_flash = f in flash_frames
flash_light.data.energy = 800000.0 if is_flash else 0.0
flash_light.data.keyframe_insert(data_path="energy", frame=f)
bolt_obj.scale = (1.0, 1.0, 1.0) if is_flash else (0.0, 0.0, 0.0)
bolt_obj.keyframe_insert(data_path="scale", frame=f)
if bg_node:
bg_node.inputs[1].default_value = 3.5 if is_flash else 0.3
bg_node.inputs[1].keyframe_insert(data_path="default_value", frame=f)
cam_shake = slam_shock * 1.4 + (0.045 * math.sin(f * 3.1) if is_flash else 0.0)
cam_pos = Vector((
-1.55 + math.sin(f * 0.03) * 0.85 + math.sin(f * 0.27) * 0.06,
-2.2 + math.cos(f * 0.025) * 1.2 + math.cos(f * 0.21) * 0.06,
2.95 + math.sin(f * 0.04) * 0.35 + abs(math.sin(f * 0.22)) * 0.08 + cam_shake * 0.8
))
target_pos = Vector((
0.55 + math.sin(f * 0.05) * 0.4,
1.15 + math.cos(f * 0.04) * 0.3,
2.55 + math.sin(f * 0.07) * 0.25
))
look_dir = target_pos - cam_pos
cam_rot = look_dir.to_track_quat('-Z', 'Y').to_euler('XYZ')
cam_rot.x += cam_shake * 0.9 + math.sin(f * 0.22) * 0.015
cam_rot.y += math.sin(f * 0.09) * 0.06 + cam_shake * 1.2
cam_rot.z += math.cos(f * 0.19) * 0.015
cam.location = cam_pos
cam.rotation_euler = cam_rot
cam.keyframe_insert(data_path="location", frame=f)
cam.keyframe_insert(data_path="rotation_euler", frame=f)
bpy.ops.object.select_all(action='DESELECT')
bpy.context.view_layer.update()