TITLE: They Come For Your Goldfish. NAME: Duncan Gray COUNTRY: Great Britain EMAIL: duncang@eclipse.co.uk WEBPAGE: www.eclipse.co.uk/duncang TOPIC: Creatures COPYRIGHT: I SUBMIT TO THE STANDARD RAYTRACING COMPETITION COPYRIGHT. MPGFILE: dg_gfish.mpg ZIPFILE: dg_gfish.zip RENDERER USED: POV-Ray 3.1a TOOLS USED: Windows Paint Program CREATION TIME: Difficult to say; 6 weeks including rendering time. HARDWARE USED: Pentium P133 for development; Pentium P100 for batch rendering. AMD 350 for last minute clean up work. ANIMATION DESCRIPTION: It's the middle of the night and all is quiet. The Goldfish sleeps, but his slumber will be disturbed; they come at night - they come for the Goldfish ! Please Note: No fish were injured or in any was distressed in the making of this movie. ACKNOWLEDGEMENTS: I would like to take this opportunity to thank the POV-Ray team for the production of POV-Ray, and decision to distribute and license POV-Ray in such a generous manner. Cheers guys. Furthermore, I would like to extend additional thanks to those responsible for adding the #macro functionality, well done. I would also like to thank my employer for giving me 2 days holiday at very short notice, and for the loan of an AMD 350 to finish the rendering. Without these, I wouldn't have made the deadline. VIEWING RECOMMENDATIONS: Windows Media Player, if possible, view at 15-20 frames per second. DESCRIPTION OF HOW THIS ANIMATION WAS CREATED: The animation I have submitted was rendered to be played back at 15 frames per second (fps), unfortunately, it was only in the last week having downloaded an MPEG encoder have I discovered that 15 fps is not an option for an MPG file. Time did not permit re-rendering, so I continued at 15 fps. The file should have been 1min 50 seconds - 1650 frames total ! Whew. It still has 1650 frames, but on my player, measures just 1min 8 secs. As a result of this, my basic scene settings assume that a clock value of 1 represents 1 second, or 15 frames, this is the case in the following descriptions. Should you be playing the movie back, you will find that the time counter does not match the times listed here. You will have to judge the time by the key points. The scene must be rendered as a two pass operation - this is to permit the 'picture in picture' effect scene on the bridge of the ufo. The scene file ufo_cam.pov must first be rendered for clock values 0 to 74 and 80-110 (frame numbers 0000 to 1110 and 1200 to 1650). The scene file will automatically switch camera position at 15 seconds for the close up view, and again at 95 seconds for the 'exit' shot. Having rendered this lot, the bridge sequence must be rendered for clock values 0 to 35 (frames 000 to 525). These sequence does not simply get inserted into the ufo_cam sequence; the final output mpeg must consist of: ufo_0000 - ufo_0224 (Approach Sequence) ufo_0225 - ufo_0899 (Goldfish Sequence) bridg000 - bridg525 (Bridge Sequence) ufo_1426 - ufo_1650 (Exit Sequence) The video display on the ufo bridge plays back the frames ufo_0900 to ufo_1425. As we didn't render frames 1110 to 1200, there is a calculation at the top of the bridge.pov file which as well as calculating the ufo_cam frame number required, also cycles the frames 1050 to 1110 to fill the missing gap. Although this only actually saves something like 90 frames of rendering, if the bridge sequence were to be extended, the savings would be larger. This cycleing of the frames equates to clock values 70-74 of ufo_cam, 4 seconds are required, as this is the 'resonant frequency' of the weeds in the fish bowl. It is also suitable for the rotational speed of the ufo - just in case you have the cpu power to render it with the fishbowl-glass in place ! Thats a basic overview of the animation - the interesting stuff is going on in the scene files, I shall describe them in turn, starting with the goldfish; as he's pretty much the main character. GOLDFISH.INC The goldfish file requires a mountain of parameters to be set before its inclusion: f_clock=0; // step this from 0 to 1 for fish to swim through one cycle swim_power=0; // magnitude of the swim movement fish_mouth=0; // 0 is closed, 1 is open eyelid=0; // 0 is closed, 1 is open iris=1; // 1 is 'normal' 0 is a tiny iris (frightened) shock=off; // this isn't actually used in the scenes. eye_down=0; // degrees rotation of the eye downwards eye_right=0; // 0 looks ahead, +ve is degrees right, -ve is degrees left. head_dip=0; // head dip is degrees rotation down about the second spine element head_rise=0; // head rise is degrees rotation up about the first spine element head_tilt_right=0; // rotates the head about the axis the fish is aligned on sympathy_twist=10; // rotates the eyelids downwards on the outside. Pathetic look. rf_downplane=0; // right fin downplane angle (sub-talk) lf_downplane=0; // left fin downplane angle rf_down=0; // right fin lf_down=0; // left fin rf_back=10; // right fin rearward angle (swingwing) typ -10 to +20 lf_back=10; // left fin rearward angle (swingwing) typ -10 to +20 three additional variables are applied in the parent .pov file: fish_elevation=0; // 'nose up' attitude - degrees fish_downright=0; // bank as though turning right - degrees fish_right=0; // turn right (about y axis) The file declares 2 objects of interest; fish, and fish_bones. The objects are located at 0,0,0 - this being the center of the fish's head, on the axis the mouth opens on. the fish and fishbones objects follow each others movements, some parameters are not relevant to the fish_bones object - namely eye and eyelid controls. The fish swim movement was developed more or less by trial and error, but basically, the 6 segment of the fish's body each rotate on a sine-wave, there is then an ever-increasing phase lag in the sin calculations as the tail is approached. For a more natural feel, the head is counter-rotated by a small amount (the tail wags the fish a little as well sa the fish wagging the tail). The fish also tracks left and right slightly as it swims, this was again calculated 'by eye' by rendering up little 20 frame sequences and cycling them. GF2.INC When I developed the Goldfish, I discovered, and made use of macro's, unfortunately, I neglected to define the goldfish itself as a parameterised macro. GF2.INC defines 2 fish and 2 fish_bone objects. The second fish, and all parameters for it are prefixed with an 's', it operates in the same manner as the primary fish. FISHBOWL.INC Is the natural habitat for my Goldfish, it consists of a height-field for the gravel, a bridge, and some weeds. The weeds require a weed_clock parameter to be set before including the file, the weeds waft slightly based on this number and begin to repeat their animation on a weed_clock of 1. The algorythm for the weeds movement is applied to each strand of the weed as it is constructed. The macro which constructs the weeds basically builds a single helix - the radius of the helix expands slightly as it grows upward, and the diameter of the strand itself decreases as it grows. When this thickness reaches a threshold value, the strand is terminated with a sphere. These strands are gouped in bundles of 6, with a rotation of 60 degrees between each strand. Like most of the scene, this construction was build by eye. A second parameter bowl_type determines the construction of the bowl, in variuos parts of the final animation different bowl types are used. type 0 is no bowl - it is quickest, but can only be used for the close up. there is a water only option which is better for the close up, but still not suitable for the room shots. For these, the glass is always present, but rendering time can be improved by draining the water. UFO.INC Pretty straight forward really, the ufo is made of a squashed sphere with a slice taken out of the middle. The spinning lights and white bar are then added. Ufo doesn't spin - the textures do. This is to permit mounting of a light-source. three declares must be made before inclusion - ufo_lamp, lamp_slide and ufo_clock. ufo lamp is designed to range from 0 to 1, and switches on the ufo's light source to this level of intensity. lamp_slide reduces the length of a cylinder which contains the light source - a value of .25 will give a wide angle of effect. Larger values contract the projected circle of light. ufo_clock is the clock value for the rotation of the ufo textures. The shiny top and bottom of the ufo rotate 1 turn for every 2 turns of the flashing lights. The lights rotate in the opposite direction from the top and bottom of the saucer. ROOM.INC The design of the room is fairly basic, one 'quirk' you might notice is that I am performing some rather strange operations with the blinds - there are two sets of blinds - one opaque, and set to 'no_shadow' and one semi-transparent set, slightly smaller, and obscured from view by the opaque blinds. The reason for this is so the shadow cast is not total - in the shadow area of the blinds (when they were opaque to light) the goldfish had a tendancy to look very flat up until the ufo light came on. The initial resolution to theis was to add an additional room light, but this proved too slow on the rendering, so I made the blinds semi-transparent. This worked, it meant that a certain amount of light would hit the goldfish with direction, therefore the diffuse effect of his skin (scales ??) worked. Unfortunately, for the opening shot, the blinds are in direct view, and when semi-transparent, they looked rather odd. Rather than switch the transparency half way through the animation, I opted for this dual blind arrangement. Seems to work OK, and is not too dramatic on the render times. UFO_CAM.POV This is the main pov file - it renders the approach and retreat sequences, the main fish-bowl close up, and the frames to be displayed on the ufo's video screen. The 'scripting' of all movements is performed using the flight_spline macro, I wont go into details as to the mathematics of the algorythm, for those interseted - the formula is that of a cubic spline. flight_spline takes 7 parameters: flight_spline(A,B,C,D,t1,t2,t) It returns a value being the interpolation from A to D, weighted in the direction of (though not necessarily passing through) B and C. The sub-point is described using the t1,t2 and t parameters. A clock value should be passed into t. If this clock value is less than or equal to t1, then A is returned. If the clock value is greater than or equal to t2, then D is returned. for values between t1 and t2, the interpolation takes place. Because of this built in range checking, the script becomes that much easier to build, consider the following construct: #declare pos=A1; #declare pos=(flight_spline(pos,B1,C1,D1,t1,t2,t) ); #declare pos=(flight_spline(pos,B2,C2,D2,t2,t3,t) ); You might think that the second declare of pos would overwrite the first - you would be quite right, but by passing pos as the first parameter into the flight_spline routine, it will set it to itself if t