// Last edited on 2011-08-16 21:10:20 by stolfilocal // Slave // ---------------------------------------------------------------------- // Head and neck. #declare slave_neck_dz = 500; // Z distance from mid-hips to neck base. #declare slave_shoulder_pos = < 0, 200, 500 >; // Position of shoulder artic rel to mid-hips. #declare slave_hip_pos = < 0, 150, 0 >; // Position of hip artic rel to mid-hips. #declare slave_head_rad = 100; // Nominal radius of slave's head. #declare slave_neck_rad = 50; // Nominal radius of slave's neck. #declare slave_neck_len = 150; // Nominal length of slave's neck. #declare slave_torso_ry = 150; // Nominal torso half-width (in Y). #declare slave_torso_rx = 75; // Nominal torso half-thickness (in X). // ---------------------------------------------------------------------- // Shoulders, arms, hands. #declare slave_shoulder_rad = 40; // Nominal shoulder swelling radius. #declare slave_uparm_len = 250; // Nominal upper arm length. #declare slave_uparm_rad = 35; // Nominal upper arm radius. #declare slave_elbow_rad = 40; // Nominal elbow radius. #declare slave_forearm_len = 270; // Nominal forearm length. #declare slave_forearm_rad = 30; // Nominal forearm radius. #declare slave_wrist_rad = 30; // Nominal elbow radius. #declare slave_hand_len = 180; // Nominal hand length. #declare slave_hand_wid = 120; // Nominal hand width. #declare slave_hand_thk = 20; // Nominal hand thickness. // ---------------------------------------------------------------------- // Hips, legs, feet. #declare slave_hip_rad = 80; // Nominal radius of hip swelling. #declare slave_tigh_len = 300; // Nominal length of tigh, artic to artic. #declare slave_tigh_rad = 60; // Nominal radius of tigh. #declare slave_kne_rad = 70; // Nominal radius of knee swelling. #declare slave_shin_len = 450; // Nominal length of shin, artic to artic. #declare slave_shin_rad = 50; // Nominal radius of shin. #declare slave_ankle_rad = 65; // Nominal radius of ankle swelling. #declare slave_foot_ry = 75; // Nominal foot half-width (in Y). #declare slave_foot_rz = 20; // Nominal foot half-thickness (in Z). #declare slave_foot_len = 200; // Nominal foot length (in X). // Common parameters: // {blink} eye status 0 = closed, 1 = open. // {gape} 0 = closed mouth, 1 = open mouth. // {gaze_e} elevation of gaze direction rel to forward. // {gaze_a} azimuth of gaze direction rel to forward. #macro slave_head(blink,gape,gaze_e,gaze_a,tx) #local hrad = slave_head_rad; #local nrad = slave_neck_rad; #local nlen = slave_neck_len; #local nbot = < 0, 0, -nrad>; // Neck bottom ctr, buried in chest. #local ntop = < 0, 0, nlen + hrad >; // Neck bottom ctr, buried in chest. #local hctr = < 0, 0, nlen + hrad > ; // Head center. union{ sphere{ hctr, hrad rotate gaze_e*y rotate gaze_a*z } cylinder{ nbot, ntop, nrad } texture{ tx } } #end // ---------------------------------------------------------------------- // Torso. #macro slave_torso() #local tr_bot_ctr = < 0, 0, 0 >; // Mid-Hips. #local tr_top_ctr = < 0, 0, slave_neck_dz >; // Mid-shoulders. #local tr_rad = slave_torso_ry; #local tr_flatten = slave_torso_rx/slave_torso_ry; union{ cylinder{ tr_bot_ctr, tr_top_ctr, tr_rad } sphere{ 0, tr_rad scale < 1, 1, tr_flatten > translate tr_bot_ctr } sphere{ 0, tr_rad scale < 1, 1, tr_flatten > translate tr_top_ctr } scale < tr_flatten, 1, 1 > } #end // ---------------------------------------------------------------------- // Arm. #macro slave_left_arm(virt,elb_A,elb_B,wrs_A) // Slave left arm (with shoulder ball). // Shoulder cenered at origin, umerus along -Z, palm normal -Y. // {virt} 0 = actual arm, 1 = tiny ball at surface of palm near wrist. // {elb_A} axial rotation of forearm at elbow (+ = palm forward) // {elb_B} forward rotation of forearm at elbow (0 = straight, + = forward) // {wrs_A} angle of wrist (+ = inward) #local a_len = slave_uparm_len; #local a_rad = slave_uparm_rad; #local s_rad = slave_shoulder_rad; #local subarm = object{ slave_left_subarm(virt,wrs_A) rotate elb_A*z rotate -elb_B*y translate -a_len*z } #if (virt) object{ subarm } #else union{ sphere{ <0,0,0>, s_rad } cylinder{ <0,0,0>, <0,0,-a_len>, a_rad } object{ subarm } } #end #end #macro slave_left_subarm(virt,wrs_A) // Slave left forearm and hand (with elbow ball). // Elbow centered at origin, forearm along +Z, palm normal -Y. // {virt} 0 = actual arm, 1 = tiny ball at surface of palm near wrist. // {wrs_A} angle of wrist (+ = inward) #local f_len = slave_forearm_len; #local f_rad = slave_forearm_rad; #local e_rad = slave_elbow_rad; #local hand = object{ slave_left_hand(virt) rotate -wrs_A*x translate -f_len*z } #if (virt) object{ hand } #else union{ sphere{ <0,0,0>, e_rad } cylinder{ <0,0,0>, <0,0,-f_len>, f_rad } object{hand} } #end #end #macro slave_left_hand(virt) // Slave's hand (rudimentary, with wrist ball). // Wrist at 0, extends along +Z, palm normal -Y. #local h_len = slave_hand_len; #local h_wid = slave_hand_wid; #local h_thk = slave_hand_thk; #local w_rad = slave_wrist_rad; #if (virt) sphere{ <0,0,0>, 0.1 translate -h_thk/2*y } #else union{ sphere{ <0,0,0>, w_rad } sphere{ <0,0,0>, 1 translate -1*z scale < h_wid/2, h_thk/2, h_len/2 > } } #end #end // ---------------------------------------------------------------------- // Leg. #macro slave_left_leg(virt,kne_A,ank_A,ank_B) // Slave's left leg (hip ball, tigh, shin, and foot). // Tigh is vertical down, hip artic at origin. // {kne_A} angle of shin away from tigh (+ = back). // {ank_A} pitch angle of foot away from 90 degrees of shin (+ = down). // {ank_B} roll angle of foot (+ = inward). // {virt} 0 = actual leg, 1 = tiny ball at bottom of heel. #local hip_rad = slave_hip_rad; // Hip swelling rad. #local tigh_len = slave_tigh_len; #local tigh_rad = slave_tigh_rad; #local kne_pos = < 0, 0, -tigh_len >; // Knee artic position rel hip. #local subleg = object{ slave_left_subleg(virt,ank_A,ank_B) rotate kne_A*y translate kne_pos } #if (virt) object{ subleg } #else union{ sphere{ 0, hip_rad } cylinder{ 0, kne_pos, tigh_rad } object{ subleg } } #end #end #macro slave_left_subleg(virt,ank_A,ank_B) // Slave's left shin (with knee ball and foot). // Shin is vertical down, knee artic at origin. // {ank_A} pitch angle of foot away from 90 degrees of shin (+ = down). // {ank_B} roll angle of foot (+ = inward). // {virt} 0 = actual subleg, 1 = tiny ball at bottom of heel. #local kne_rad = slave_kne_rad; // Knee swelling rad. #local shin_len = slave_shin_len; #local shin_rad = slave_shin_rad; #local ank_pos = < 0, 0, -shin_len >; // Ankle artic position. #local foot = object{ slave_left_foot(virt) rotate -ank_B*x rotate ank_A*y translate ank_pos } #if (virt) object{ foot } #else union{ sphere{ 0, kne_rad } cylinder{ 0, ank_pos, shin_rad } object{ foot } } #end #end #macro slave_left_foot(virt) // Slave's left foot (with ankle ball). // Ankle artic at origin, toes towards +Y. // {virt} 0 = actual foot, 1 = tiny ball at bottom of heel. #local ft_len = slave_foot_len; #local ft_ry = slave_foot_ry; #local ft_rz = slave_foot_rz; #local ft_flatten = ft_rz/ft_ry; #local ank_rad = slave_ankle_rad; #local toes_ctr = < ft_len, 0, 0 >; // Toes center, before flattening. #if (virt) sphere{ 0, 0.1 translate -ft_rz*z } #else union{ union{ cylinder{ 0, toes_ctr, ft_ry } sphere{ 0, ft_ry } sphere{ 0, ft_ry scale < ft_flatten, 1, 1 > translate toes_ctr } scale < 1, 1, ft_flatten > } intersection{ sphere{ 0, ank_rad } cylinder{ 0, 1.01*ank_rad*z, 1.01*ank_rad } } } #end #end // ---------------------------------------------------------------------- // Placed body parts. #macro slave_placed_arm(virt,arm_A,which) // Slave's arm, properly positioned for attachment to body. // {arm_A} array with packed angles of leg joints. // {which} which side (+1 = left, -1 = right). // Unpack angle vector: #local sho_A = arm_A[0]; #local sho_B = arm_A[1]; #local sho_C = arm_A[2]; #local elb_A = arm_A[3]; #local elb_B = arm_A[4]; #local wrs_A = arm_A[5]; #local sho_pos = slave_shoulder_pos; // Position of left shoulder artic. object{ slave_left_arm(virt,elb_A,elb_B,wrs_A) rotate -sho_A*z rotate -sho_B*y rotate +sho_C*x translate sho_pos scale <+1,which,+1> } #end #macro slave_placed_leg(virt,leg_A,which) // Slave's leg, properly positioned for attachment to body. // Leg is placed assuming mid-hips at origin. // {leg_A} = array with packed angles of leg joints. // {which} which side (+1 = left, -1 = right). // Unpack angle vector: #local hip_A = leg_A[0]; #local hip_B = leg_A[1]; #local hip_C = leg_A[2]; #local kne_A = leg_A[3]; #local ank_A = leg_A[4]; #local ank_B = leg_A[5]; #local hip_pos = slave_hip_pos; // Position of left hip artic. object{ slave_left_leg(virt,kne_A,ank_A,ank_B) rotate -hip_A*z rotate -hip_B*y rotate -hip_C*x translate hip_pos scale <+1,which,+1> } #end #macro slave(arm_LA,arm_RA,leg_LA,leg_RA,blink,gape,gaze_e,gaze_a,tx) // The walking slave. // {tx} skin texture. // {arm_LA} = array with packed angles of left arm joints. // {arm_RA} = array with packed angles of right arm joints. // {leg_LA} = array with packed angles of left leg joints. // {leg_RA} = array with packed angles of right leg joints. // Slave is facing towards {+x} with mid-hips at origin. #local neck_dz = slave_neck_dz; union{ object{ slave_head(blink,gape,gaze_e,gaze_a,tx) translate neck_dz*z } union{ object{ slave_torso() } object{ slave_placed_arm(false,arm_LA,+1) } object{ slave_placed_arm(false,arm_RA,-1) } object{ slave_placed_leg(false,leg_LA,+1) } object{ slave_placed_leg(false,leg_RA,-1) } texture{ tx } } } #end