Pinecoast Software Inc.
      Home
Subscribe
 

Tutorial: Butterflies

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



Copyright © Pinecoast Software 2000-2008. All rights reserved.