#version 3.7; /* Animated Marionette Puppets performing in a Medieval Castle Courtyard. Render as an animation with clock in [0..1] for a seamless loop. */ global_settings { assumed_gamma 1.3 max_trace_level 16 radiosity { pretrace_start 0.08 pretrace_end 0.01 count 200 nearest_count 10 error_bound 0.5 recursion_limit 2 low_error_factor 0.5 gray_threshold 0.0 } } background { color rgb <0.93, 0.95, 0.98> } // ---------------- Camera (reframed to actually see the courtyard/stage) ---------------- camera { location <12.0, 6.2, -12.8> look_at <0.0, 2.0, 3.8> angle 40 up <0,9,0> right <16,0,0> // right,up -> 16:9 } // ---------------- Lights (warm, soft shadows; reduced intensity to avoid blowout) ----- light_source { <18, 16, -18> color rgb <1.00, 0.86, 0.70>*0.70 area_light <3.2,0,0>, <0,0,3.2>, 6, 6 adaptive 1 jitter } light_source { <-16, 11, -6> color rgb <1.00, 0.90, 0.80>*0.35 area_light <2.6,0,0>, <0,0,2.6>, 5, 5 adaptive 1 jitter } light_source { <0, 14, 10> color rgb <1.00, 0.88, 0.76>*0.22 area_light <3.0,0,0>, <0,0,3.0>, 5, 5 adaptive 1 jitter } // subtle torch accents near gate light_source { <-1.6, 2.8, 0.65> color rgb <1.0,0.62,0.28>*0.18 fade_distance 5 fade_power 2 area_light <0.6,0,0>, <0,0.6,0>, 4, 4 adaptive 1 jitter } light_source { < 1.6, 2.8, 0.65> color rgb <1.0,0.62,0.28>*0.18 fade_distance 5 fade_power 2 area_light <0.6,0,0>, <0,0.6,0>, 4, 4 adaptive 1 jitter } // ---------------- Simple shading (no textures; fast) --------------------------------- #declare Fin_Matte = finish { diffuse 0.92 specular 0.04 roughness 0.15 }; #declare Fin_Wood = finish { diffuse 0.85 specular 0.08 roughness 0.10 }; #declare Fin_Metal = finish { diffuse 0.35 specular 0.55 roughness 0.04 }; #declare Mat_Stone = texture { pigment { color rgb <0.78,0.80,0.83> } finish { Fin_Matte } }; #declare Mat_StoneAccent = texture { pigment { color rgb <0.68,0.70,0.74> } finish { Fin_Matte } }; #declare Mat_Ground = texture { pigment { color rgb <0.86,0.87,0.89> } finish { Fin_Matte } }; #declare Mat_Wood = texture { pigment { color rgb <0.50,0.33,0.20> } finish { Fin_Wood } }; #declare Mat_Rope = texture { pigment { color rgb <0.80,0.72,0.55> } finish { Fin_Matte } }; #declare Mat_Skin = texture { pigment { color rgb <0.92,0.80,0.68> } finish { Fin_Matte } }; #declare Mat_ClothBlue = texture { pigment { color rgb <0.22,0.42,0.85> } finish { Fin_Matte } }; #declare Mat_ClothRed = texture { pigment { color rgb <0.82,0.18,0.16> } finish { Fin_Matte } }; #declare Mat_ClothGreen = texture { pigment { color rgb <0.20,0.62,0.36> } finish { Fin_Matte } }; #declare Mat_Metal = texture { pigment { color rgb <0.42,0.43,0.46> } finish { Fin_Metal } }; #declare Mat_DarkPassage = texture { pigment { color rgb <0.14,0.14,0.16> } finish { Fin_Matte } }; // ---------- Helpers ---------- #declare TAU = 6.28318530718; #declare T = clock; #declare Sway = sin(T*TAU); // crenels for a straight wall segment centered at ZCenter #macro CrenelatedTop(LengthX, TopY, ZCenter, WallThick, CrenW, CrenH, Phase) union { #local StartX = -LengthX/2; #local EndX = LengthX/2; #local X = StartX; #while (X < EndX - 0.0001) #local isUp = (mod(floor((X-StartX)/CrenW + Phase), 2) = 0); #if (isUp) box { , } #end #local X = X + CrenW; #end } #end #macro TowerCrenels(R, TopY, CrenW, CrenH, N) union { #local i=0; #while (i, rotate <0, degrees(ang), 0> } #end #local i=i+1; #end } #end // ---------- Courtyard ground ---------- plane { y, 0 texture { Mat_Ground } } // ---------- Castle (simple medieval layout; aligned) ---------- #declare CourtyardZ = 7.3; #declare WallHeight = 4.3; #declare WallThick = 1.10; #declare WallTopY = WallHeight; #declare CrenW = 0.70; #declare CrenH = 0.70; #declare CastleHalfX = 8.7; #declare CastleHalfZ = 6.6; #declare Wall_Front = box { <-CastleHalfX,0,CourtyardZ-CastleHalfZ>, < CastleHalfX,WallHeight,CourtyardZ-CastleHalfZ+WallThick> } #declare Wall_Back = box { <-CastleHalfX,0,CourtyardZ+CastleHalfZ-WallThick>, < CastleHalfX,WallHeight,CourtyardZ+CastleHalfZ> } #declare Wall_Left = box { <-CastleHalfX,0,CourtyardZ-CastleHalfZ>, <-CastleHalfX+WallThick,WallHeight,CourtyardZ+CastleHalfZ> } #declare Wall_Right = box { < CastleHalfX-WallThick,0,CourtyardZ-CastleHalfZ>, < CastleHalfX,WallHeight,CourtyardZ+CastleHalfZ> } // Gatehouse (front-center) #declare GateW = 3.0; #declare GateH = 3.1; #declare GatehouseW = 4.6; #declare GatehouseD = 2.2; #declare GatehouseH = 5.4; #declare Gatehouse = difference { box { <-GatehouseW/2, 0, CourtyardZ-CastleHalfZ-0.0001>, < GatehouseW/2, GatehouseH, CourtyardZ-CastleHalfZ+GatehouseD> } box { // opening <-GateW/2, 0, CourtyardZ-CastleHalfZ-0.25>, < GateW/2, GateH, CourtyardZ-CastleHalfZ+GatehouseD+0.25> } } // Corner towers #declare TowerR = 1.60; #declare TowerH = 6.4; #declare Tower_Pos1 = < CastleHalfX-WallThick, 0, CourtyardZ-CastleHalfZ+WallThick>; #declare Tower_Pos2 = <-CastleHalfX+WallThick, 0, CourtyardZ-CastleHalfZ+WallThick>; #declare Tower_Pos3 = < CastleHalfX-WallThick, 0, CourtyardZ+CastleHalfZ-WallThick>; #declare Tower_Pos4 = <-CastleHalfX+WallThick, 0, CourtyardZ+CastleHalfZ-WallThick>; #declare Tower = union { cylinder { <0,0,0>, <0,TowerH,0>, TowerR } object { TowerCrenels(TowerR, TowerH-0.70, 0.75, 0.65, 14) } cone { <0,TowerH,0>, TowerR*0.98, <0,TowerH+1.25,0>, 0.12 } } // Full castle group union { object { Wall_Front } object { Wall_Back } object { Wall_Left } object { Wall_Right } object { Gatehouse texture { Mat_StoneAccent } } object { CrenelatedTop(CastleHalfX*2, WallTopY, CourtyardZ+CastleHalfZ-WallThick/2, WallThick, CrenW, CrenH, 0) } object { CrenelatedTop(CastleHalfX*2, WallTopY, CourtyardZ-CastleHalfZ+WallThick/2, WallThick, CrenW, CrenH, 1) } object { CrenelatedTop(CastleHalfZ*2, WallTopY, CourtyardZ, WallThick, CrenW, CrenH, 0) rotate <0,90,0> translate <-CastleHalfX+WallThick/2,0,0> } object { CrenelatedTop(CastleHalfZ*2, WallTopY, CourtyardZ, WallThick, CrenW, CrenH, 1) rotate <0,90,0> translate < CastleHalfX-WallThick/2,0,0> } object { Tower translate Tower_Pos1 } object { Tower translate Tower_Pos2 } object { Tower translate Tower_Pos3 } object { Tower translate Tower_Pos4 } texture { Mat_Stone } } // Gate door slab precisely behind opening box { <-GateW/2, 0, CourtyardZ-CastleHalfZ+0.22>, < GateW/2, GateH, CourtyardZ-CastleHalfZ+0.38> texture { Mat_Wood } } // Dark passage behind the door to avoid see-through box { <-GateW/2, 0, CourtyardZ-CastleHalfZ+0.38>, < GateW/2, GateH, CourtyardZ-CastleHalfZ+1.35> texture { Mat_DarkPassage } } // Courtyard stage/platform for puppets #declare PlinthW = 7.2; #declare PlinthD = 4.4; #declare PlinthH = 0.26; box { <-PlinthW/2, 0, 1.25>, texture { Mat_StoneAccent } } // ---------- Marionette rig ---------- #declare RigY = 6.8; #declare BarLen = 10.6; #declare BarRad = 0.10; #declare BarZ = 3.05; // Crossbar cylinder { <-BarLen/2, RigY, BarZ>, , BarRad texture { Mat_Wood } } // Posts cylinder { <-BarLen/2, 0, BarZ>, <-BarLen/2, RigY, BarZ>, 0.15 texture { Mat_Wood } } cylinder { < BarLen/2, 0, BarZ>, < BarLen/2, RigY, BarZ>, 0.15 texture { Mat_Wood } } // Braces cylinder { <-BarLen/2, 2.2, BarZ>, <-BarLen/2+1.1, 0.25, BarZ>, 0.10 texture { Mat_Wood } } cylinder { < BarLen/2, 2.2, BarZ>, < BarLen/2-1.1, 0.25, BarZ>, 0.10 texture { Mat_Wood } } // ---------- Puppet macro (animated) ---------- #macro Puppet(P, OutfitMat) #local Bob = 0.18*Sway; #local ArmSwing = 35*sin(T*TAU + P*0.9); #local LegSwing = 28*sin(T*TAU + 1.2 + P*0.7); #local HeadTurn = 12*sin(T*TAU*0.5 + P*0.3); #local BodyH = 1.15; #local BodyR = 0.28; #local HeadR = 0.26; #local HipY = 0.20 + Bob; #local ShoulderY = HipY + BodyH*0.80; #local NeckY = HipY + BodyH; #local HeadY = NeckY + HeadR; #local ArmUpper = 0.52; #local ArmLower = 0.48; #local LegUpper = 0.62; #local LegLower = 0.58; #local JointR = 0.06; #local C = ; union { // torso cylinder { C+<0,HipY,0>, C+<0,HipY+BodyH,0>, BodyR texture { OutfitMat } } // head sphere { C+<0,HeadY,0>, HeadR texture { Mat_Skin } rotate <0, HeadTurn, 0> } // joints sphere { C+<0,NeckY,0>, JointR texture { Mat_Metal } } sphere { C+<-BodyR*0.95,ShoulderY,0>, JointR texture { Mat_Metal } } sphere { C+< BodyR*0.95,ShoulderY,0>, JointR texture { Mat_Metal } } sphere { C+<-BodyR*0.55,HipY,0>, JointR texture { Mat_Metal } } sphere { C+< BodyR*0.55,HipY,0>, JointR texture { Mat_Metal } } // left arm union { #local S = C+<-BodyR*0.95,ShoulderY,0>; #local E = S + <0,-ArmUpper,0>; #local W = E + <0,-ArmLower,0>; cylinder { S, E, 0.08 texture { Mat_Wood } } sphere { E, JointR texture { Mat_Metal } } cylinder { E, W, 0.07 texture { Mat_Wood } } sphere { W, 0.08 texture { Mat_Skin } } rotate } // right arm union { #local S = C+< BodyR*0.95,ShoulderY,0>; #local E = S + <0,-ArmUpper,0>; #local W = E + <0,-ArmLower,0>; cylinder { S, E, 0.08 texture { Mat_Wood } } sphere { E, JointR texture { Mat_Metal } } cylinder { E, W, 0.07 texture { Mat_Wood } } sphere { W, 0.08 texture { Mat_Skin } } rotate <-ArmSwing,0,0> } // left leg (green hose) union { #local H = C+<-BodyR*0.55,HipY,0>; #local K = H + <0,-LegUpper,0>; #local A = K + <0,-LegLower,0>; cylinder { H, K, 0.09 texture { Mat_ClothGreen } } sphere { K, JointR texture { Mat_Metal } } cylinder { K, A, 0.085 texture { Mat_ClothGreen } } box { A+<-0.12,-0.05,-0.16>, A+<0.12,0.05,0.08> texture { Mat_Wood } } rotate <-LegSwing,0,0> } // right leg union { #local H = C+< BodyR*0.55,HipY,0>; #local K = H + <0,-LegUpper,0>; #local A = K + <0,-LegLower,0>; cylinder { H, K, 0.09 texture { Mat_ClothGreen } } sphere { K, JointR texture { Mat_Metal } } cylinder { K, A, 0.085 texture { Mat_ClothGreen } } box { A+<-0.12,-0.05,-0.16>, A+<0.12,0.05,0.08> texture { Mat_Wood } } rotate } // gentle whole-body sway rotate <0, 7*sin(T*TAU + P*0.5), 0> } #end #declare P1x = -1.7; #declare P2x = 1.9; object { Puppet(P1x, Mat_ClothBlue) } object { Puppet(P2x, Mat_ClothRed ) } // ---------- Strings ---------- #declare StringRad = 0.02; #macro StringsForPuppet(P) #local Bob = 0.18*Sway; #local BodyH = 1.15; #local BodyR = 0.28; #local HeadR = 0.26; #local HipY = 0.20 + Bob; #local ShoulderY = HipY + BodyH*0.80; #local NeckY = HipY + BodyH; #local HeadY = NeckY + HeadR; #local C = ; #local TopMain = ; cylinder { TopMain, C+<0,HeadY,0>, StringRad texture { Mat_Rope } } cylinder { TopMain+<-0.30,0,0>, C+<-BodyR*1.45,ShoulderY-0.95,0>, StringRad texture { Mat_Rope } } cylinder { TopMain+< 0.30,0,0>, C+< BodyR*1.45,ShoulderY-0.95,0>, StringRad texture { Mat_Rope } } #end StringsForPuppet(P1x) StringsForPuppet(P2x) // ---------- Simple props ---------- box { <-0.40, 3.05, CourtyardZ-CastleHalfZ+WallThick+0.02>, < 0.40, 4.70, CourtyardZ-CastleHalfZ+WallThick+0.05> texture { Mat_ClothRed } } // Small training post / ring prop cylinder { <3.45, 0, 3.85>, <3.45, 0.90, 3.85>, 0.40 texture { Mat_Wood } } torus { 0.42, 0.05 rotate <90,0,0> translate <3.45, 0.22, 3.85> texture { Mat_Metal } } torus { 0.42, 0.05 rotate <90,0,0> translate <3.45, 0.70, 3.85> texture { Mat_Metal } }