|
Tutorial: Butterflies

This scene contains two butterflies. The first butterfly is in a Transform
node that is called Butterfly1. This Transform node contains two other Transform
nodes, one for the left wing and one for the right wing. The left wing contains
two Shapes, one for the top of the wing and one for the bottom of the wing.
DEF Butterfly1 Transform {
children [
DEF leftWingButterfly1 Transform {
children [
Shape {
appearance Appearance {
texture ImageTexture {
url "gauche.gif"
}
}
geometry IndexedFaceSet {
coordIndex [ 0, 1, 2, 3, -1 ]
texCoordIndex [ 0, 1, 2, 3, -1 ]
normalPerVertex FALSE
coord Coordinate {
point [ -0.89 0 0.67, 0 0 0.67,
0 0 -0.67, -0.89 0 -0.67 ]
}
texCoord TextureCoordinate {
point [ 0 0, 1 0, 1 1, 0 1 ]
}
}
}
Shape {
appearance Appearance {
texture ImageTexture {
url "gauche.gif"
}
}
geometry IndexedFaceSet {
coordIndex [ 1, 0, 3, 2, -1 ]
texCoordIndex [ 1, 0, 3, 2, -1 ]
normalPerVertex FALSE
coord Coordinate {
point [ -0.89 0 0.67, 0 0 0.67,
0 0 -0.67, -0.89 0 -0.67 ]
}
texCoord TextureCoordinate {
point [ 0 0, 1 0, 1 1, 0 1 ]
}
}
}
]
}
DEF rightWingButterfly1 Transform {
...
}
]
All the geometry nodes are IndexedFaceSets. The geometry for the top of the
left wing is formed from the points (-0.89 0 0.67), (0 0 0.67), (0 0 -0.67), (-0.89 0 -0.67)
in the Coordinate subnode. The coordIndex field specifies that this points are
to be taken in order, which is counterclockwise around a rectangle. The
normalPerVertex field being FALSE means that there will be one normal for the face.
Since the rectangle is traversed counterclockwise, this normal will be vertical and equal
to (0, 1, 0). The TextureCoordinate node contains the vertices of the unit square in the
same order. This means that the ImageTexture "gauche.gif" will be applied
to the rectangle to cover it completely. The texture contains transparency. This means
that the rectangle will take the form of the wing. The other parts of the rectangle will
not be visible. The bottom part of the wing is a rectangle containing the
same points, but the coordIndex specifies that they be taken in a different order. This time
the points traverse clockwise, so the normal will point downwards because this is a negative
orientation. This means that the image will appear on the underside of the rectangle.
Animation
There are two motions in getting the butterflies to fly. The first motion is the flapping
of the wings. This is accomplished by changing the rotation of the Transform nodes Butterfly1LeftWing
and Butterfly1RightWing which contain the wings.
DEF leftWingButterfly1_ORI OrientationInterpolator {
key [ 0, 0.25, 0.5, 0.75, 1 ]
keyValue [ 0 0 1 0, 0 0 1 -0.8, 0 0 1 0, 0 0 1 0.8, 0 0 1 0 ]
}
DEF rightWingButterfly1_ORI OrientationInterpolator {
key [ 0, 0.25, 0.5, 0.75, 1 ]
keyValue [ 0 0 1 0, 0 0 1 0.8, 0 0 1 0, 0 0 1 -0.8, 0 0 1 0 ]
}
DEF Butterfly1_TS1 TimeSensor {
loop TRUE
}
ROUTE Butterfly1_TS1.fraction_changed
TO leftWingButterfly1_ORI.set_fraction
ROUTE Butterfly1_TS1.fraction_changed
TO rightWingButterfly1_ORI.set_fraction
ROUTE leftWingButterfly1_ORI.value_changed
TO leftWingButterfly1.rotation
ROUTE rightWingButterfly1_ORI.value_changed
TO rightWingButterfly1.rotation
Because the first butterfly is contained in the Butterfly1 Transform node, its movement
can be created be changing the translation and rotation fields of that node.
DEF Butterfly1_TS2 TimeSensor {
cycleInterval 20
loop TRUE
}
DEF Butterfly1_POS2 PositionInterpolator {
key [ 0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1 ]
keyValue [ 0 0 5, 3.53553 2.5 3.53554, 5 5 6.63397e-006,
3.53554 2.50001 -3.53553, 1.32679e-005 3.52077e-011 -5,
-3.53552 2.49998 -3.53555, -5 5 -1.99019e-005,
-3.53555 2.50002 3.53552, -2.65359e-005 1.40831e-010 5
]
}
DEF Butterfly1_ORI2 OrientationInterpolator {
key [ 0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1 ]
keyValue [ -0.261856 0.929545 -0.25957 -1.63504,
-0.590284 0.769274 -0.244504 -0.987862, 0 1 0 0,
-0.590286 0.769273 0.244504 0.98786, 0 1 0 1.57079,
0.124492 0.945607 -0.300549 2.39496,
0 1 0 -3.14159, 0.124491 0.945607 0.300549 -2.39496,
0.257612 0.930644 0.259882 -1.65136
]
}
ROUTE Butterfly1_TS2.fraction_changed
TO Butterfly1_POS2.set_fraction
ROUTE Butterfly1_TS2.fraction_changed
TO Butterfly1_ORI2.set_fraction
ROUTE Butterfly1_POS2.value_changed
TO Butterfly1.translation
ROUTE Butterfly1_ORI2.value_changed
TO Butterfly1.rotation
In xz coordinates the PositionInterpolator node specifies that the path of the
butterfly is a circle of radius 5. To make the flight path more interesting the y
value has also been varied. The cycleInterval is 20, so it takes 20 seconds to
complete a circle. Because the butterfly is rising and falling it must be rotated
so that it is pointing in the direction that it is travelling. These rotations
were calculated from the direction of the path and put into the OrientationInterpolator node.
The second butterfly is created in the same way but the TimeSensor cycleIntervals
are different to create interest.
Thanks to Christian Guillermet for supplying the images of the two butterflies from the
island of Reunion.
Download tutorial files
|