Difference between revisions of "HowTo:Create animations"

From POV-Wiki
Jump to navigation Jump to search
(Test)
 
(Add source tag for highlighting POV SDL.)
Line 4: Line 4:
 
When animating, we use the ini-file. Here we tell the renderer what frames to render, and what clockvalues the renderer should use.
 
When animating, we use the ini-file. Here we tell the renderer what frames to render, and what clockvalues the renderer should use.
  
+W150
+
<source lang="pov">
+H150         
+
+W150
Input_File_Name=robot.pov
+
+H150         
Initial_Frame=1
+
Input_File_Name=robot.pov
Final_Frame=30
+
Initial_Frame=1
Initial_Clock=0
+
Final_Frame=30
Final_Clock=1
+
Initial_Clock=0
 +
Final_Clock=1
 +
</source>
  
 
Using the above INI-file will render 30 frames, and the clockvariable will run from 0 to 1. This clock we set in the ini-file wille be avaiable at rendertime as the variable 'clock'. To be of interest every frame should be different according to the clockvalue.  
 
Using the above INI-file will render 30 frames, and the clockvariable will run from 0 to 1. This clock we set in the ini-file wille be avaiable at rendertime as the variable 'clock'. To be of interest every frame should be different according to the clockvalue.  
Line 31: Line 33:
 
[[Image:Birds_2_02.gif|right]]
 
[[Image:Birds_2_02.gif|right]]
  
When you want to show complex behaviour in your animation, you will have a lot of programming to do. Sometimes however it is not nescessary to define everything in detail. Sometimes simple sets of rules (working on a simple set of variables) wil exhibit complex behaviour which will nonetheless be recognizable.  
+
When you want to show complex behaviour in your animation, you will have a lot of programming to do. Sometimes however it is not necessary to define everything in detail. Sometimes simple sets of rules (working on a simple set of variables) wil exhibit complex behavior which will nonetheless be recognizable.  
  
It is possible to define an array of object, say birds or fish, setting up varibles for position, orientation and speed, and creating a macro to draw them (with this orientation and speed). Now every time a frame is rendered you call the macro which draws all birds or fish,  and call a macro which calculates the new state for every object (position, speed) and stores it for use in the next frame. This calculation macro is in fact a simple set of -more or less- high-level rules. Changing these rules, you setup behaviour, not exact positions for the objects.  You can 'guide' each bird, not exactly, but with simple rules like "stay above the ground" and "if you are going to collide, turn left a bit" you have some control.  These sets of rules will generate almost random behaviour, which has recognizable dynamics like flocking for birds, traffic-jamming for cars, or bending in the 'wind' for trees.
+
It is possible to define an array of object, say birds or fish, setting up variables for position, orientation and speed, and creating a macro to draw them (with this orientation and speed). Now every time a frame is rendered you call the macro which draws all birds or fish,  and call a macro which calculates the new state for every object (position, speed) and stores it for use in the next frame. This calculation macro is in fact a simple set of -more or less- high-level rules. Changing these rules, you setup behavior, not exact positions for the objects.  You can 'guide' each bird, not exactly, but with simple rules like "stay above the ground" and "if you are going to collide, turn left a bit" you have some control.  These sets of rules will generate almost random behavior, which has recognizable dynamics like flocking for birds, traffic-jamming for cars, or bending in the 'wind' for trees.
  
 
===State variables===
 
===State variables===
The state variables are the core of this method, and you will need to carefully analyse the behaviour of the object you are trying to mimic. You the capture these in a simple data structure. You might create something like this:
+
The state variables are the core of this method, and you will need to carefully analyse the behavior of the object you are trying to mimic. You the capture these in a simple data structure. You might create something like this:
  
#declare Blocation = array[max_birds];
+
<source lang="pov">
#declare Bvelocity = array[max_birds];
+
#declare Blocation = array[max_birds];
#declare Bphase = array[max_birds];
+
#declare Bvelocity = array[max_birds];
 +
#declare Bphase = array[max_birds];
 +
</source>
  
 
The amount of detail in the dissemination of the object tends to grow in time, see below for further explanation of the phase-parameter.  
 
The amount of detail in the dissemination of the object tends to grow in time, see below for further explanation of the phase-parameter.  
Line 46: Line 50:
 
To make this work you will need to 'transfer' the state of the objects (birds) from each frame to the next. This can easily be done using macro's to write out, and readback the variables to a file on disk. The following macro's can be easily extended to save and load more complex data-sets.
 
To make this work you will need to 'transfer' the state of the objects (birds) from each frame to the next. This can easily be done using macro's to write out, and readback the variables to a file on disk. The following macro's can be easily extended to save and load more complex data-sets.
  
#macro SaveState()     
+
<source lang="pov">
        #fopen wfile "state.txt" write
+
#macro SaveState()     
        #local i = 0;
+
      #fopen wfile "state.txt" write
        # while (i<max_birds)
+
      #local i = 0;
                #write ( wfile, Blocation[i], ",", Bvelocity[i], "," , Bphase[i], ",")
+
      # while (i<max_birds)
                #local i=i+1;                 
+
              #write ( wfile, Blocation[i], ",", Bvelocity[i], "," , Bphase[i], ",")
        #end     
+
              #local i=i+1;                 
        #fclose file     
+
      #end     
#end     
+
      #fclose file     
 +
#end     
  
#macro LoadState()     
+
#macro LoadState()     
        #fopen rfile "state.txt" read
+
      #fopen rfile "state.txt" read
        #local i = 0;
+
      #local i = 0;
        #while (i<max_birds)
+
      #while (i<max_birds)
                #read ( rfile, Blocation[i] ,Bvelocity[i], Bphase[i] )
+
              #read ( rfile, Blocation[i] ,Bvelocity[i], Bphase[i] )
                #local i=i+1;                 
+
              #local i=i+1;                 
        #end         
+
      #end         
        #fclose file
+
      #fclose file
#end     
+
#end     
 +
</source>
  
 
===Drawing the objects===
 
===Drawing the objects===
Line 78: Line 84:
 
Now further on you can create a rule to stop birds from stalling:
 
Now further on you can create a rule to stop birds from stalling:
  
// Do not stall
+
<source lang="pov">
#if (Speed<1)  
+
// Do not stall
    #declare Bvelocity[i]=Bvelocity[i]*1.2;  
+
#if (Speed<1)  
#end
+
    #declare Bvelocity[i]=Bvelocity[i]*1.2;  
 +
#end
 +
</source>
  
 
===Detailed control===
 
===Detailed control===

Revision as of 13:34, 8 December 2007

Creating animations in POV is nothing like using graphical tools some of us are already used to. Small animations are easily done, but when animations grow, a little planning and preparation goes a long way.

Basics

When animating, we use the ini-file. Here we tell the renderer what frames to render, and what clockvalues the renderer should use.

+W150
+H150         
Input_File_Name=robot.pov
Initial_Frame=1
Final_Frame=30
Initial_Clock=0
Final_Clock=1

Using the above INI-file will render 30 frames, and the clockvariable will run from 0 to 1. This clock we set in the ini-file wille be avaiable at rendertime as the variable 'clock'. To be of interest every frame should be different according to the clockvalue.

Animating objects

To animate a ball going up and down we could use the clockvariable in an object creation of translation.

sphere { <0,clock,0>,1 }
or
sphere { <0,0,0>,1 translate <0,clock,0> }

Animating object properties

More interesting behaviour is possible is you imagine everything can be animated. Allthough impossible in the real world you can show how a piece of glass would look if it's index of refraction would slowly change.

Animating the camera

Animating a camera requires some planning when complex movements are required. Smooth movement is possible if you can specify a 'neat' set of position functions, and a flyby look-and-feel is possible if you also take into account gravity, speed and acceleration, so you can adjust the 'roll' of the camera according to the current down direction. This dynamical downdirection is a lineair combination of the gravity vector, and the centrifugal forces caused by direction changes.

Creating complex behaviour

Birds 2 02.gif

When you want to show complex behaviour in your animation, you will have a lot of programming to do. Sometimes however it is not necessary to define everything in detail. Sometimes simple sets of rules (working on a simple set of variables) wil exhibit complex behavior which will nonetheless be recognizable.

It is possible to define an array of object, say birds or fish, setting up variables for position, orientation and speed, and creating a macro to draw them (with this orientation and speed). Now every time a frame is rendered you call the macro which draws all birds or fish, and call a macro which calculates the new state for every object (position, speed) and stores it for use in the next frame. This calculation macro is in fact a simple set of -more or less- high-level rules. Changing these rules, you setup behavior, not exact positions for the objects. You can 'guide' each bird, not exactly, but with simple rules like "stay above the ground" and "if you are going to collide, turn left a bit" you have some control. These sets of rules will generate almost random behavior, which has recognizable dynamics like flocking for birds, traffic-jamming for cars, or bending in the 'wind' for trees.

State variables

The state variables are the core of this method, and you will need to carefully analyse the behavior of the object you are trying to mimic. You the capture these in a simple data structure. You might create something like this:

#declare Blocation = array[max_birds];
#declare Bvelocity = array[max_birds];
#declare Bphase = array[max_birds];

The amount of detail in the dissemination of the object tends to grow in time, see below for further explanation of the phase-parameter.

To make this work you will need to 'transfer' the state of the objects (birds) from each frame to the next. This can easily be done using macro's to write out, and readback the variables to a file on disk. The following macro's can be easily extended to save and load more complex data-sets.

#macro SaveState()    
       #fopen wfile "state.txt" write
       #local i = 0;
       # while (i<max_birds)
               #write ( wfile, Blocation[i], ",", Bvelocity[i], "," , Bphase[i], ",")
               #local i=i+1;                
       #end     
       #fclose file     
#end    

#macro LoadState()    
       #fopen rfile "state.txt" read
       #local i = 0;
       #while (i<max_birds)
               #read ( rfile, Blocation[i] ,Bvelocity[i], Bphase[i] )
               #local i=i+1;                
       #end         
       #fclose file
#end

Drawing the objects

You will need a macro or set of macros to draw the objects into the scene. The macro to draw the object will have to take into account all relevant parameters. For instance a bird rolls when taking a turn, according with it's changing down-vector. Also the wings will have a current state (a phase) which determines where the wings are in the up-down direction.

Rules

In the main file you will want to execute some 'business rules' for every bird to define it's solitary behaviour, and maybe you will want to run some other rules for each bird-pair, so social behaviour can be controlled. These rules act on the state variables, but can also gather information elsewhere provided the variables needed are in scope.

You can embed these rules in a macro which you run each frame. In this macro you could create some intermediate variables, deduced from the state variables to make the rule definition somewhat more comfortable. In the example above, we could define a speed, which is easier to compare than a velocity vector.

#local Speed = vlength(Bvelocity[i]);

Now further on you can create a rule to stop birds from stalling:

// Do not stall
#if (Speed<1) 
    #declare Bvelocity[i]=Bvelocity[i]*1.2; 
#end

Detailed control

As said you cannot control these objects at the position-level using these rules. At rendertime you have access to all the variables so you could do extra checks and 'force then around'. However this will not work at parse-time. Suppose you create a scene with mountains and buildings, and want to add some birds. Now when the birds calculate their 'next move' the information about buildings and mountains is NOT available. Detailed interaction with the scene requires capturing behaviour in rules, and creating an environment where data about say buildings and mountains can be stored. Now the extra rules can act on this data.

More to try

  • You could consider animating things like fish, cars, trees, houses and much more.
  • Try animating different species with specific interactions.