""" Track 09: WITH U - Two Orbiting Souls/Spheres with Stars (THE TURN!) """ import bpy import math import random import sys import os sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from utils import * def create_with_u_animation(): """Create the full Track 09 animation - the emotional centerpiece.""" clear_scene() setup_scene(background_color=(0.047, 0.039, 0.035, 1.0)) # Warm dark # Create camera camera = create_camera(location=(0, -12, 6), rotation=(1.1, 0, 0)) animate_camera_orbit(camera, center=(0, 0, 0), radius=12, height=5, start_frame=1, end_frame=TOTAL_FRAMES, revolutions=0.35) # Create Soul 1 (main gold) soul1 = create_sphere(location=(2, 0, 0), radius=0.4, segments=24, rings=16, name="Soul1") soul1_mat = create_emission_material("Soul1Mat", COLORS["with_u"], strength=4.0) soul1.data.materials.append(soul1_mat) # Create Soul 2 (lighter gold) soul2 = create_sphere(location=(-2, 0, 0), radius=0.35, segments=24, rings=16, name="Soul2") soul2_mat = create_emission_material("Soul2Mat", (0.988, 0.827, 0.302, 1.0), strength=4.0) soul2.data.materials.append(soul2_mat) # Entrance animation keyframe_scale(soul1, 1, 0.01) keyframe_scale(soul1, 60, 1.0) keyframe_scale(soul2, 1, 0.01) keyframe_scale(soul2, 60, 1.0) # Orbital dance animation orbit_start = 90 orbit_end = 550 for frame in range(orbit_start, orbit_end + 1, 3): t = (frame - orbit_start) / (orbit_end - orbit_start) angle = t * 2.5 * math.pi # Elliptical orbits with vertical motion r1 = 2 + 0.3 * math.sin(angle * 2) r2 = 2 + 0.3 * math.sin(angle * 2 + math.pi) pos1 = ( r1 * math.cos(angle), r1 * math.sin(angle), 0.5 * math.sin(angle * 3) ) pos2 = ( r2 * math.cos(angle + math.pi), r2 * math.sin(angle + math.pi), 0.5 * math.sin(angle * 3 + math.pi) ) keyframe_location(soul1, frame, pos1) keyframe_location(soul2, frame, pos2) # Create orbital trails using curves trail1_points = [] trail2_points = [] for t in range(100): angle = t / 100 * 2.5 * math.pi r1 = 2 + 0.3 * math.sin(angle * 2) r2 = 2 + 0.3 * math.sin(angle * 2 + math.pi) trail1_points.append(( r1 * math.cos(angle), r1 * math.sin(angle), 0.5 * math.sin(angle * 3) )) trail2_points.append(( r2 * math.cos(angle + math.pi), r2 * math.sin(angle + math.pi), 0.5 * math.sin(angle * 3 + math.pi) )) trail1 = create_curve_from_points(trail1_points, name="Trail1", bevel_depth=0.015) trail1_mat = create_emission_material("Trail1Mat", COLORS["with_u"], strength=1.5) trail1.data.materials.append(trail1_mat) trail2 = create_curve_from_points(trail2_points, name="Trail2", bevel_depth=0.015) trail2_mat = create_emission_material("Trail2Mat", (0.988, 0.827, 0.302, 1.0), strength=1.5) trail2.data.materials.append(trail2_mat) # Animate trails appearing trail1.data.bevel_factor_end = 0.0 trail1.data.keyframe_insert(data_path="bevel_factor_end", frame=orbit_start) trail1.data.bevel_factor_end = 1.0 trail1.data.keyframe_insert(data_path="bevel_factor_end", frame=orbit_end) trail2.data.bevel_factor_end = 0.0 trail2.data.keyframe_insert(data_path="bevel_factor_end", frame=orbit_start) trail2.data.bevel_factor_end = 1.0 trail2.data.keyframe_insert(data_path="bevel_factor_end", frame=orbit_end) # EPIC MOMENT - Stars appear! stars_appear_frame = 480 stars = create_star_field(count=200, radius=15, min_size=0.02, max_size=0.06) for i, star in enumerate(stars): keyframe_scale(star, 1, 0.01) keyframe_scale(star, stars_appear_frame + i // 5, 0.01) keyframe_scale(star, stars_appear_frame + i // 5 + 30, 1.0) # Souls come together union_start = 580 union_end = 650 keyframe_location(soul1, union_start, soul1.location[:]) keyframe_location(soul2, union_start, soul2.location[:]) keyframe_location(soul1, union_end, (0.35, 0, 0)) keyframe_location(soul2, union_end, (-0.35, 0, 0)) # Glow brighter together # (In Blender, we'd animate material emission strength, but for export compatibility # we'll animate scale as a visual indicator) keyframe_scale(soul1, union_end, 1.0) keyframe_scale(soul1, union_end + 30, 1.5) keyframe_scale(soul2, union_end, 1.0) keyframe_scale(soul2, union_end + 30, 1.5) # Dim stars when souls unite for star in stars: keyframe_scale(star, union_end, 1.0) keyframe_scale(star, union_end + 30, 0.7) # Exit animation keyframe_scale(soul1, TOTAL_FRAMES - 30, 1.5) keyframe_scale(soul1, TOTAL_FRAMES, 0.01) keyframe_scale(soul2, TOTAL_FRAMES - 30, 1.5) keyframe_scale(soul2, TOTAL_FRAMES, 0.01) return soul1, soul2, trail1, trail2, stars if __name__ == "__main__": create_with_u_animation() output_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) bpy.ops.wm.save_as_mainfile(filepath=os.path.join(output_dir, "exports", "track09_with_u.blend")) bpy.ops.export_scene.gltf( filepath=os.path.join(output_dir, "exports", "track09_with_u.gltf"), export_animations=True, export_format='GLTF_SEPARATE' ) bpy.ops.wm.alembic_export( filepath=os.path.join(output_dir, "exports", "track09_with_u.abc"), start=1, end=TOTAL_FRAMES ) print("Track 09 - With U: Export complete!")