""" Example 10: Trapcode Particular Iconic Features Showcase Demonstrates: 1. Auxiliary Particle System (Aux Trails & Secondary Sparkle Dust) 2. Floor Collision & Bounce Physics (Elasticity & Surface Friction) 3. Custom Curves Over Life (Bell, GrowAndFade, Pulse) 4. Layer Mask Emitter (Particle Birth from Image/Logo with Pixel Color Inheritance) """ import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) import numpy as np from PIL import Image, ImageDraw, ImageFont import particri as pc output_dir = Path("output") output_dir.mkdir(exist_ok=True) print("--- 1. Generating Aux Trails & Floor Bounce Demo ---") engine_bounce = pc.ParticleEngine(max_particles=35000, width=1920, height=1080) # Add Floor Bounce Plane at y=920 engine_bounce.add_bounce_plane(coord=920.0, bounce=0.62, friction=0.88, is_horizontal=True, is_max=True) # Add Gravity & subtle atmospheric drag engine_bounce.add_gravity(0.0, 180.0) engine_bounce.add_drag(0.08) # Add slight curl noise turbulence engine_bounce.add_curl_noise(seed=42, strength=60.0, frequency=0.002, speed=0.2) # Primary Emitter: Golden Fountain shooting upwards & outwards engine_bounce.add_emitter( shape=pc.EmitterShape.Circle, position=(960.0, 750.0), size=(30.0, 30.0), rate=180.0, speed_range=(250.0, 520.0), angle_range=(-2.35, -0.78), # Upward fan lifetime_range=(1.8, 3.2), size_start_range=(8.0, 18.0), size_end_range=(1.0, 3.0), color_start=(1.0, 0.9, 0.5, 1.0), color_end=(1.0, 0.35, 0.05, 0.0), particle_shape=pc.ParticleShape.Star4, size_curve=pc.CurveType.GrowAndFade, opacity_curve=pc.CurveType.GrowAndFade, seed=101, ) # Auxiliary System: Each falling firework spark leaves shimmering golden dust trails! engine_bounce.enable_aux_system( rate=25.0, # 25 child particles per second from each primary particle lifetime=1.4, size_range=(4.0, 0.5), color_start=(1.0, 0.85, 0.3, 0.95), color_end=(1.0, 0.2, 0.05, 0.0), inherit_color=True, velocity_inheritance=0.12, # Child inherits 12% parent speed spread=18.0, # Slight jitter particle_shape=pc.ParticleShape.Glitter, size_curve=pc.CurveType.Bell, # Peaks in middle, gentle fade opacity_curve=pc.CurveType.GrowAndFade, emit_at_death=8, # 8 sparks burst on particle death ) # Simulate 3.5 seconds print("Simulating physics & particle lifecycles...") engine_bounce.warmup(duration=3.5, step=1.0 / 60.0) frame_bounce = engine_bounce.render(blend_mode=pc.BlendMode.Additive, bloom=True, bloom_intensity=0.85, bloom_radius=8) pc.Exporter.save_image(frame_bounce, output_dir / "10_particular_aux_trails_bounce.png") print(f"Saved: {output_dir / '10_particular_aux_trails_bounce.png'}") print("\n--- 2. Generating Layer Mask / Logo Emitter Demo ---") engine_layer = pc.ParticleEngine(max_particles=30000, width=1920, height=1080) # Create a vibrant synthetic logo image mask (1920x1080) with PIL logo_img = Image.new("RGBA", (1920, 1080), (0, 0, 0, 0)) draw = ImageDraw.Draw(logo_img) # Draw central geometric glowing star emblem with gradient rings cx, cy = 960, 540 # Outer ring (Cyan / Teal) draw.ellipse([cx - 280, cy - 280, cx + 280, cy + 280], outline=(0, 220, 255, 255), width=8) # Middle ring (Magenta / Pink) draw.ellipse([cx - 200, cy - 200, cx + 200, cy + 200], outline=(255, 60, 180, 255), width=6) # Inner ring (Warm Gold) draw.ellipse([cx - 120, cy - 120, cx + 120, cy + 120], outline=(255, 215, 80, 255), width=5) # Central diamond star polygon def make_star(center_x, center_y, r_outer, r_inner, num_pts=8): pts = [] for i in range(num_pts * 2): r = r_outer if i % 2 == 0 else r_inner angle = i * np.pi / num_pts - np.pi / 2 pts.append((center_x + r * np.cos(angle), center_y + r * np.sin(angle))) return pts star_pts = make_star(cx, cy, 100, 35, num_pts=8) draw.polygon(star_pts, fill=(255, 240, 200, 255), outline=(255, 180, 50, 255)) # Add Layer Emitter to engine with automatic pixel color inheritance! mask_np = np.asarray(logo_img, dtype=np.float32) / 255.0 engine_layer.add_layer_emitter( image=mask_np, rate=2800.0, speed_range=(8.0, 45.0), lifetime_range=(1.2, 3.0), size_start_range=(5.0, 14.0), size_end_range=(0.0, 2.0), particle_shape=pc.ParticleShape.Star8, size_curve=pc.CurveType.Bell, opacity_curve=pc.CurveType.GrowAndFade, inherit_layer_color=True, drag=0.18, seed=777, ) # Add subtle vortex swirl around the logo engine_layer.add_vortex(center=(cx, cy), strength=70.0, radial_pull=-10.0, radius=600.0) engine_layer.add_curl_noise(seed=999, strength=50.0, frequency=0.003, speed=0.2) print("Simulating logo layer emission...") engine_layer.warmup(duration=2.5, step=1.0 / 60.0) frame_layer = engine_layer.render(blend_mode=pc.BlendMode.Screen, bloom=True, bloom_intensity=0.9, bloom_radius=7) pc.Exporter.save_image(frame_layer, output_dir / "10_particular_layer_mask_logo.png") print(f"Saved: {output_dir / '10_particular_layer_mask_logo.png'}") print("\nAll Trapcode Particular demos generated successfully!")