Introducing script use
bounce1.wrl

	

#VRML V2.0 utf8
#
#  bounce1.wrl
#  Bouncing beachball (JavaScript/VRMLscript version)
#        by David R. Nadeau
#
#  This world illustrates the use of a Script node to create a computed
#  animation path.  In particular, the Script node uses a JavaScript
#  (or VRMLScript) program script to compute translation values for a
#  vertically bouncing beach ball.
#
#  The bounce path is based upon the projectile motion equation of
#  physics, constrained to create a cyclic bouncing path with a
#  user-selected maximum bounce height.  Also, there is no friction,
#  drag, or damping.
#
#  The equation is derived as follows:
#
#        (1)  Projectile motion computes a y(t) value (height as a function
#             of time) based upon the gravitation constant, g, an initial
#             y-direction velocity, v0, an initial y position, y0, and the
#             current time, t:
#
#                y(t) = 0.5 * g * t * t + v0 * t + y0
#
#        (2)  At time t=0, the ball should be on the ground with y=0.
#             So, y0 = y(0) = 0.  The equation in (1) simplifies to:
#
#                y(t) = 0.5 * g * t * t + v0 * t
#
#        (3)  At time t=1, at the end of the TimeSensor's fractional time
#             cycle, the ball should again be on the ground with y=0.
#             So, y(1) = 0.  Plugging this in to the equation in (2),
#             we get:
#
#                y(t) = 0.5 * g * t * t + v0 * t
#                y(1) = 0.5 * g * 1 * 1 + v0 * 1
#                   0 = 0.5 * g + v0
#
#             So
#
#                   v0 = -0.5 * g
#
#        (4)  At time t=0.5, the ball should be at the peak of its bounce
#             at a user-selected maximum height, h.  So, y(0.5) = h.
#             Plugging this in to the equation in (2), we get:
#
#                y(t)   = 0.5 * g * t * t + v0 * t
#                y(0.5) = 0.5 * g * 0.5 * 0.5 + v0 * 0.5
#                     h = g * 0.125 + v0 * 0.5
#
#            And v0 = -0.5 * g from equation (3), so
#
#                     h = g * 0.125 - 0.5 * g * 0.5
#                     h = -g * 0.125
#
#            So
#
#                     g = -8.0 * h
#
#        (5)  We can now simplify the equation in (2) using the results
#             from (3) and (4) to get an equation that computes the
#             ball height y(t) parameterized only by the maximum height, h,
#             giving us:
#
#                y(t) = 0.5 * g * t * t + v0 * t
#                     = 0.5 * (-8.0 * h) * t * t + (-0.5 * g) * t
#                     = 0.5 * (-8.0 * h) * t * t + (4.0 * h) * t
#                     = 4.0 * h * (-t * t + t)
#                     = 4.0 * h * t * (1.0 - t)
#
#             In the program script, the maximum height, h, is given in
#             the 'bounceHeight' field.  The current time, t, is given in
#             the 'set_fraction' eventIn and passed to the eventIn function
#             as the 'frac' parameter.  Using these names, the above
#             equation becomes:
#
#                 y = 4.0 * bounceHeight * frac * (1.0 - frac)
#
#  Things to experiment with
#        -  Encapsulate the ball, script, timer, and sensors within a
#           PROTO for a new node named "BouncingBall".  Then use that
#           new BouncingBall node multiple times to create multiple
#           bouncing balls.  Your PROTO interface might look like this:
#
#                PROTO BouncingBall [
#                        field SFFloat bounceHeight     2.0
#                        field SFTime  cycleInterval 2.0
#                ] { . . . }
#
#           See 'bounce3.wrl', which implements such a PROTO.
#
#        -  Add a shadow under the bouncing ball.  To do this, add a
#           circular, semi-transparent, black shape that doesn't bounce.
#           To make the shadow more realistic, scale the shadow in the X
#           and Z directions, shrinking it as the ball goes up, and
#           increasing it as the ball comes down.  You'll need to add
#           another eventOut for the Script node and send an XYZ scaling
#           factor triple out that eventOut.  Try the following values
#           for the XYZ scale values:
#
#                xzscale = 1.0 - 0.5 * y / bounceHeight;
#                shadowScale_changed[0] = xzscale;
#                shadowScale_changed[1] = 1.0;
#                shadowScale_changed[2] = xzscale;
#
#           See 'bounce4.wrl', which implements shadows using the above
#           scale values.
#
#        -  Add a sound to the PROTO so that each time the ball touches
#           the ground, it makes a 'boing' sound.
#
#        -  When the ball hits the ground, scale the ball slightly so that
#           it appears to squish.
#

WorldInfo {
        title "Bouncing beachball (JavaScript)"
        info [ "Copyright (c) 1997, David R. Nadeau" ]
}

Viewpoint {
    position 0.0 0.6 8.0
    orientation 1.0 0.0 0.0 0.1
}

NavigationInfo {
    type [ "WALK", "ANY" ]
    headlight FALSE
    speed 2.0
}

DirectionalLight {
    ambientIntensity 0.5
    direction 0.0 -1.0 -0.5
}

#
#  Sky
#
Background {
    skyColor [
        0.0 0.0 1.0,
        0.0 0.5 1.0,
        0.7 0.7 1.0,
    ]
    skyAngle [
        1.371,
        1.571,
    ]
}


#
#  Beach
#
Shape {
    appearance Appearance {
        material Material { }
        texture ImageTexture { url "sand.jpg" }
        textureTransform TextureTransform { scale 10.0 10.0 }
    }
    geometry IndexedFaceSet {
        coord Coordinate {
            point [
                -50.0 -1.0  50.0,
                 50.0 -1.0  50.0,
                 50.0 -1.0 -50.0,
                -50.0 -1.0 -50.0,
            ]
        }
        coordIndex [ 0, 1, 2, 3 ]
        solid FALSE
    }
}


#
#  Palm trees
#
Transform {
    translation -3.0 -1.0 -10.0
    children [
        DEF Palm Group {
            children [
            # Palm tree - in a billboard so it is never edge-on
                Billboard {
                    children [
                        Shape {
                            appearance Appearance {
                                material NULL  # emissive texturing
                                texture ImageTexture { url "palm.png" }
                            }
                            geometry IndexedFaceSet {
                                coord Coordinate {
                                    point [
                                        -2.5  0.0 0.0,
                                         2.5  0.0 0.0,
                                         2.5 11.25 0.0,
                                        -2.5 11.25 0.0,
                                    ]
                                }
                                coordIndex [ 0, 1, 2, 3 ]
                                texCoord TextureCoordinate {
                                        point [
                                                0.0 0.0,
                                                1.0 0.0,
                                                1.0 1.0,
                                                0.0 1.0,
                                        ]
                                }
                                texCoordIndex [ 0, 1, 2, 3 ]
                                solid FALSE
                            }
                        }
                    ]
                }
            # Fake tree shadow - a black semi-transparent rectangle with
            # a texture map to give it the right shape
                Shape {
                    appearance Appearance {
                        material Material {
                                diffuseColor 0.0 0.0 0.0
                                transparency 0.5
                        }
                        texture ImageTexture { url "palmsh.png" }
                    }
                    geometry IndexedFaceSet {
                        coord Coordinate {
                            point [
                                -2.5  0.05  2.5,
                                 2.5  0.05  2.5,
                                 2.5  0.05 -2.5,
                                -2.5  0.05 -2.5,
                            ]
                        }
                        coordIndex [ 0, 1, 2, 3 ]
                        texCoord TextureCoordinate {
                                point [
                                        0.0 0.0,
                                        1.0 0.0,
                                        1.0 1.0,
                                        0.0 1.0,
                                ]
                        }
                        texCoordIndex [ 0, 1, 2, 3 ]
                        solid FALSE
                    }
                }
            ]
        }
    ]
}
Transform { translation -5.0 -1.0  -6.0 scale 0.6 0.6 0.6 children USE Palm }
Transform { translation  5.0 -1.0  -9.0 children USE Palm }
Transform { translation 10.0 -1.0 -15.0 children USE Palm }


#
#  Bouncing beach ball
#
DEF Ball Transform {
    # animated translation
    children [
        Shape {
            appearance Appearance {
                material Material {
                    ambientIntensity 0.5
                    diffuseColor 1.0 1.0 1.0
                    specularColor 0.7 0.7 0.7
                    shininess 0.4
                }
                texture ImageTexture { url "beach.jpg" }
                textureTransform TextureTransform { scale 2.0 1.0 }
            }
            geometry Sphere { }
        }
    ]
}

DEF Clock TimeSensor {
    cycleInterval 2.0
    startTime 1.0
    stopTime 0.0
    loop TRUE
}

DEF Bouncer Script {
    field    SFFloat bounceHeight 3.0
    eventIn  SFFloat set_fraction
    eventOut SFVec3f value_changed

    # change 'vrmlscript' to 'javascript' for newer browsers
    url "vrmlscript:
        function set_fraction( frac, tm ) {
            y = 4.0 * bounceHeight * frac * (1.0 - frac);
            value_changed[0] = 0.0;
            value_changed[1] = y;
            value_changed[2] = 0.0;
        }"
}

ROUTE Clock.fraction_changed TO Bouncer.set_fraction
ROUTE Bouncer.value_changed  TO Ball.set_translation