My cheesy Lego assembly animation system for POV-Ray... V0.63 Beta! ------------------------------------------------------------------- My first test model had to be something small and simple so I went with the standard Classic Space buggy. Here's what the array definition looks like for this model (follow along at http://library.brickshelf.com/scans/0000/0886/0886-01.html if you'd like! ;) ), along with some notes: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #declare number_of_steps = 5; // Pov-Ray's array system is kind of picky, so I had to set up these things ahead of time #declare PieceArray = array[number_of_steps+1][13]; #declare EndingPositionArray = array[number_of_steps+1][13]; #declare StartingPositionArray = array[number_of_steps+1][13]; #declare RotationPointArray = array[number_of_steps+1][13]; #declare RotationAngleArray = array[number_of_steps+1][13]; // I added a step #0 so that the step indices would match up with the instruction step numbers #declare PieceArray[0][1] = sphere { 0, 0.000001 translate 1000000 } #declare EndingPositionArray[0][1] = <0, 0, 0>; #declare StartingPositionArray[0][1] = <0, 0, 0>; #declare RotationPointArray[0][1] = <0, 0, 0>; #declare RotationAngleArray[0][1] = <0, 0, 0>; // Here's where the steps actually begin // Note: wide = width of 1 Lego stud (more accurately, the distance between two standardly adjacent studs) // flat = height of a Lego plate // tall = height of a Lego brick // l3g0 = teh winnar! // 1 #declare PieceArray[1][1] = object { plate2x6 } // what piece to use #declare EndingPositionArray[1][1] = <0, 0, 0>; // where it is placed in the completed model #declare StartingPositionArray[1][1] = <0, 5, -5>; // where it is when the animation starts #declare RotationPointArray[1][1] = ; // where its center is - for rotation #declare RotationAngleArray[1][1] = <360, 360, 360>; // how to rotate it while waiting to be placed // 2 #declare PieceArray[2][1] = object { Plate2x2WithWheelsOld(wheel_rotation_degrees+13.13*33) } #declare EndingPositionArray[2][1] = <0, -flat, 0>; #declare StartingPositionArray[2][1] = <-1, -10, -3>; #declare RotationPointArray[2][1] = ; #declare RotationAngleArray[2][1] = <360, 360, 0>; #declare PieceArray[2][2] = object { plate4x2 } #declare EndingPositionArray[2][2] = <-wide, -flat, 2*wide>; #declare StartingPositionArray[2][2] = <0, -11, 0>; #declare RotationPointArray[2][2] = <2*wide, flat/2, wide>; #declare RotationAngleArray[2][2] = <360, 0, 0>; #declare PieceArray[2][3] = object { Plate2x2WithWheelsOld(wheel_rotation_degrees+13.13*33) } #declare EndingPositionArray[2][3] = <0, -flat, 4*wide>; #declare StartingPositionArray[2][3] = <1, -10, 3>; #declare RotationPointArray[2][3] = ; #declare RotationAngleArray[2][3] = <360, 360, 0>; // 3 #declare PieceArray[3][1] = object { plate2x1_with_1_stud } #declare EndingPositionArray[3][1] = <0, flat, 0>; #declare StartingPositionArray[3][1] = <-1, 12, -2>; #declare RotationPointArray[3][1] = ; #declare RotationAngleArray[3][1] = <360, 0, 360>; #declare PieceArray[3][2] = object { Slope2x2_45(lg_grey) rotate y*180 translate <2*wide, 0, 2*wide> } #declare EndingPositionArray[3][2] = <0, flat, 4*wide>; #declare StartingPositionArray[3][2] = <2, 12, 4>; #declare RotationPointArray[3][2] = ; #declare RotationAngleArray[3][2] = <360, 360, -360>; #declare PieceArray[3][3] = object { air_tanks rotate y*180 } #declare EndingPositionArray[3][3] = ; #declare StartingPositionArray[3][3] = <-3, 13, -3>; #declare RotationPointArray[3][3] = <0, 0, 0>; #declare RotationAngleArray[3][3] = <0, 360, 0>; // 4 #declare PieceArray[4][1] = object { steering_wheel } #declare EndingPositionArray[4][1] = <0, flat, wide>; #declare StartingPositionArray[4][1] = <3, 14, 0>; #declare RotationPointArray[4][1] = ; #declare RotationAngleArray[4][1] = <0, -360, 360>; #declare PieceArray[4][2] = object { antenna } #declare EndingPositionArray[4][2] = <0, flat+tall, 5*wide>; #declare StartingPositionArray[4][2] = <-2, 7, 7>; #declare RotationPointArray[4][2] = ; #declare RotationAngleArray[4][2] = <0, 0, 360>; // 5 #declare PieceArray[5][1] = object { #declare right_hand_object = union { object { ray_gun texture { lg_grey } } object { brick1x1r_clear material { l3g0_clear_green_material } translate <0, -tall, 0> } translate <-wide/2, 0, -wide/2> rotate y*180 rotate z*90 translate rotate z*90 rotate x*-90 translate <0, -0.1, 0> rotate y*180 } #declare suit_color = 0; // 0 = white, 1 = red, 2 = yellow, 3 = black, 4 = blue #declare position = 0; // 0 = sitting, 1 = standing #declare torso_angle = 0.13; #declare head_angle = -17; #declare left_arm_angle = 30; #declare right_arm_angle = 50; object { #include "minifigs/instant_spacefig.inc" } } #declare EndingPositionArray[5][1] = <0, flat, 2*wide>; #declare StartingPositionArray[5][1] = <0, 15, 0>; #declare RotationPointArray[5][1] = ; #declare RotationAngleArray[5][1] = <0, -360, 0>; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// After defining the model the code later loops through the steps and pieces and then does something like this for each piece: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// object { PieceArray[step_count][piece_count] translate -RotationPointArray[step_count][piece_count] rotate From (0, RotationAngleArray[step_count][piece_count]) Using ( "", 1, step_count, "Decelerate") To ( assembly_start_time + (step_count - 1/10) * (assembly_total_time/number_of_steps) - ( (number_of_pieces_in_current_step-piece_count) * (assembly_total_time/number_of_steps)/number_of_pieces_in_current_step), <0, 0, 0> ) translate RotationPointArray[step_count][piece_count] translate From ( assembly_start_time + step_count * (assembly_total_time/ (number_of_steps+1) ) - ( (number_of_pieces_in_current_step-piece_count) * (assembly_total_time/number_of_steps)/number_of_pieces_in_current_step), StartingPositionArray[step_count][piece_count]) Using ("S-Curve", 1, 1, "") To ( assembly_start_time + (step_count+1) * (assembly_total_time/ (number_of_steps+1) ) - ( (number_of_pieces_in_current_step-piece_count) * (assembly_total_time/number_of_steps)/number_of_pieces_in_current_step), EndingPositionArray[step_count][piece_count]) } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// See? Painless! No, I don't really know what it all means. It makes stuff move around, so that's good. The first part spins the piece around (until it's almost time to move it into place). The second part moves the piece from its starting point to its ending point.