The first thing to contemplate is what we want to create. I have recently downloaded StarWreck, In The Pirkinning
It is a funny movie and makes for a nice DVD to give to a friend.
Lets get started ...
First I wanted to have a background image I can work with. I found this page and eventually got a nice enough, stary background image.
Preparation:
Animation:
We want to have the shuttle fly around the earth. For this effet to look original, we have to calculate a eliptical orbit, which should follow about the yellow path...
For NTSC we have : Note: I am using awk to do the math. BASH alone would not be suited. You can also use PERL or any other interpreted language which allows to print to stdout.
BEGIN { PI = 3.141592654; DEGTOPI = PI / 180.0; iNrOfSteps = 300; iWidth = 720; iHeight = 480; } function createCircle(radius) { rr = radius * radius; for(t=0;t<iNrOfSteps;t++) { # full circle == 2*PI alpha = t / iNrOfSteps * 2.0 * PI; x = radius * sin ( alpha ); y = sqrt ( rr - x * x ); X[t] = x; Y[t] = y; Z[t] = 0.0; if ( ( alpha > 0.5 * PI ) && ( alpha < 1.5 * PI ) ) { Y[t] = -y; } } }; function rotateX(angle) { a = angle * DEGTOPI; for (t=0;t<iNrOfSteps;t++) { Y[t] = cos(a) * Y[t] - sin(a) * Z[t]; Z[t] = sin(a) * Y[t] + cos(a) * Z[t]; } }; function rotateY(angle) { a = angle * DEGTOPI; for (t=0;t<iNrOfSteps;t++) { X[t] = cos(a) * X[t] + sin(a) * Z[t]; Z[t] =-sin(a) * X[t] + cos(a) * Z[t]; } }; function rotateZ(angle) { a = angle * DEGTOPI; for (t=0;t<iNrOfSteps;t++) { X[t] = cos(a) * X[t] - sin(a) * Y[t]; Y[t] = sin(a) * X[t] + cos(a) * Y[t]; } }; END { # First we create a centered circle with set radius createCircle(400); # Next we rotate the circle around the X-Axis ( make a Ellipse out of it) rotateX( 75.0 ); # and we also rotate around the Z-Axis rotateZ( 50.0 ); rotateY( -30.0 ); # Lastly we print the valus to stdout for(t=0;t<iNrOfSteps;t++) { if ( ( t > 119 ) && ( t < 183 ) ) continue; printf ( "%d %d\n", X[t] + 422, Y[t] + 230 ); } | I drew the yellow line by hand to get a feel for where I want to go. The script to the right will approximate the orbit close enough. In order to accelerate the development of this algorithm I wrote a tiny project, which loads the above image. Then I wrote the awk script to calculate the values and write them to a temp file. This file was read in and the positions were drawn. Total time for this project was one day. Next we had to suppress the path which should be behind the globe. For this I simply found the samples which are affected.
| In order to give some depth to the animation we should also resize the shuttle.
Thankfully the script above handles the transfomation in 3D space, so that we also have the Z - Axis values for the circle. After about 15 minutes of trial and error I had the Z values normalized ( in the range between 0 and 1) and could use them to set the scale of the shuttle. So in order to preview this I added a timer and drew the animation ... In the final script I replaced the last loop from the script above with the one to the right to have the desired effect. ---->
Here is a snipplet of the generated output, which is used by QDVDAuthor to animate the object.
0::pos.x=303 0::pos.y=235 0::rect.width=251 0::rect.height=251 0::scale.x=0.688843 0::scale.y=0.688843 0::rotate=-354.262038 1::pos.x=308 1::pos.y=239 1::rect.width=251 1::rect.height=251 1::scale.x=0.687031 1::scale.y=0.687031 1::rotate=-353.330196 2::pos.x=312 2::pos.y=244 2::rect.width=251 : |
# Lastly we print the valus to stdout for(t=0;t<iNrOfSteps;t++) { # The Z index (size of image) is off by 90deg. thus the [300/4 = 75] offset. iZIndex = t + 75; if ( iZIndex >= iNrOfSteps ) iZIndex -= iNrOfSteps; if ( ( t > 119 ) && ( t < 190 ) ) { printf ( "%d::rect.x1=0\n", t ); printf ( "%d::rect.y1=0\n", t ); printf ( "%d::rect.width=1\n", t ); printf ( "%d::rect.height=1\n", t ); } else { zoom= (Z[iZIndex]+115.0)/230.0 * 0.7; angle=-zoom*360.0/ 0.7; printf ( "%d::pos.x=%d\n", t, X[t] + 422 ); printf ( "%d::pos.y=%d\n", t, Y[t] + 230 ); printf ( "%d::rect.width=251\n", t ); printf ( "%d::rect.height=251\n",t ); printf ( "%d::scale.x=%f\n", t, zoom ); printf ( "%d::scale.y=%f\n", t, zoom ); printf ( "%d::rotate=%f\n", t, angle ); } }
|
Template Creation:
So after we have a menu which we like, we have to create a template out of it. Lets go to [DVDMenu->Store as Template ...] After we filled in all the information we click on the [Define Dropzones >>>] button.
| |
After you press [Define Dropzones >>>] you get to this page, | where you have to click on the objects you want to become the DropZone. Note, that only ButtonObjects can be chosen as DropZones. |
This is the last step in the creation process. If you open the TemplateDialog now, the new template should be displayed in the appropriate templates - tab.
|
Other interesting links:
Gallery 3D
CRISS Personal links
Last updated July 14'th 2006