Introduction

This VR project models the gadget and popular executive toy known as Newton's Cradle. The device is a superb demonstration of the conservation of momentum in elastic collisions, as well as a fun thing to play with.

Specification

The cradle consists of a line of solid metal balls suspended from a frame, each ball held at the bottom of a V-shape of wire such that when it is swung, the axis of rotation is at right angles to the line of balls. When at rest (ie not swinging and hanging vertical), each ball just touches each of its neighbours.

The idea is to draw back one or more balls from the end of the line and release, allowing them to swing down and strike the rest of the line end-on. The impact is transmitted through the line to the other end, where an equal number of balls are propelled away in an outward swing, to fall back and repeat the process again. The result is a metronomic ticking motion that can be quite fascinating to watch.

My intention in this project is to model this behaviour realistically in a virtual world, allowing the user to intuitively pick up the balls with the mouse pointer and set the cradle in motion just as one would with finger and thumb in real life.

Design

The user is placed in a large museum hall with a tiled floor. The hall has galleries behind rows of columns down both sides, and a set of stairs at one end allows the user to view the hall from the upper galleries, also linked by a bridge across the other end of the hall. The upper galleries, bridge and stairs are all edged by chunky railings to prevent the user from inadvertantly stepping off and falling to their death (which would in any case be difficult to simulate).

The hall contains several showcases holding Newton's cradles, but the main exhibit is a large version suspended from the ceiling of the hall, each ball about a metre across. Each cradle has eight balls. As detailed in the specification, the user can pick up any ball and move it in either direction prior to release. All balls to the end of the line are pushed with the key ball as one would expect, and the user can move them as they wish, changing direction before release if they desire. Motion will subsequently run, halting when the user picks up a ball again (even ones in motion), and the process repeated.

The lights in the hall can be dimmed and raised using dimmer switches mounted on the walls below / near the relevant light fitting, the bulb colour reflecting the lights current brightness.

Implementation

There are three versions of the scene included here. The first is very realistic, fully textured and lit with multiple lights. This version looks very nice, but predictably slows down something rotten with all the light sources and texturing to do, sometimes requiring several seconds for a frame refresh even on a Pentium 400. The second version has only two lights, more basic geometry (see below for details) and no textures, running fast enough to allow fairly smooth navigation and ball motion. The third is a single Newton's cradle, with no environment, to more fully demonstrate the working model without any speed loss.

The complex version has several things over the simplified version. The most obvious is the texturing - implemented alongside the dual colour scheme in the proto fields to provide a tasteful design. It should be noted that smoothly varying, low contrast textures work best in VRML modelling due to the fact that the individual pixels in the textures become very noticeable when the avatar is close to the textured object. More subtle but most important is the complexity of the geometry making up the floors and walls. It is obvious that the most efficient way of implementing these is to use single large boxes or polygons. However I wanted the lighting to look moody, with pools of illumination surrounding the lamps, and the lighting model in VRML makes this difficult to achieve if the lamps are close to large polygons - the polygon is just given an average shade all over. To make the light fall-off look obvious the walls are composed of groups of twenty boxes fitting together to form a larger seamless box so each one is given a separate shade as they get further from the light source. The same trick is used for the floors - large boxes with pixel textures would be easiest, but each floor tile is actually a separate box. The final difference is simply the number of light sources; multiple lights slow the rendering down more than anything.

The hall architecture is built almost exclusively from boxes, because they are the easiest to visualise and place. This includes the columns, the floors, walls and gallery ceilings. Anything complex which appears more than once merits its own prototype.

Some of the most noteworthy prototypes include: Generic shape protos were created for cubes, balls and cylinders so as to avoid cluttering the code with repetitive geometry and material definitions. The arches and stairs are extrusion nodes with two-point spines. The galleries are identical each side of the hall, so it made sense to build a separate proto for the upper and lower galleries, composed of the columns, floors and arches. The floor tiles (complex version) are grouped into a 2x2 tile proto, which is used to build a hall-length flooring proto. This proto is later instantiated across the width of the hall and on the upper gallery. The level railing proto is a flattened cylinder on top of a row of posts on top of a base box. The staircase bannister proto is similar, but up a slope instead. The entire hall architecture is encapsulated in a proto, not for multiple instantiation but just to make it easier to modify the colour scheme (and textures in the complex version). The colours are linked by IS statements all the way down the hierarchy to connect everything to the fields.

Several protos include script nodes, one of which is extensive. These are the light switch and source proto, the single hanging ball and the cradle itself.

The light source proto has fields controlling the location of the dimmer buttons (geometry and sensors), the location of the light source and the lighting parameters. This is mainly to make adding and moving the light sources easy during development, but also keeps the structure of the code clear. The touch sensor events are routed to the relevant functions in the script node. These functions examine the current lighting values to make sure the light is not already at the maximum or minimum, update them and (using direct output) change the light source intensity and the bulb globe colour accordingly.

The Newton's cradle is composed of two scripted protos. The first is the single hanging ball object. The geometry for this is simply two thin cylinders forming the supporting wire, a small ball connecting them and the main ball itself. A plane sensor is installed in the ball so that the user cannot pick it up by the wire. A plane sensor was used as opposed to the rotation-oriented cylinder sensor because the latter does some strange things when dragged a long distance, making control of the movement sketchy. By contrast the plane sensor is much more stable, and the ball can easily be made to rotate towards the pointer (which looks more intuitive). A proprties proto is included because the cradle proto needs access to the fields, which the script node in this proto cannot access. The fields are therefore linked to the proprties node via IS, which the script node can directly address. These properties include angular speed, acceleration, current angle and whether the sensor is active or not. The script node in this proto is used only to take care of the dragging motion when the sensor is active, updating the current values. It uses trackpoint_changed to calculate the required angle with the arctangent function. The tracking boolean variable enables the script (and the parent proto) to see when the dragging actually starts and thus avoid using the wrong current angle.

The second, and most heavily scripted, proto is that of the cradle object, which provides a ball environment to oversee each ball's motion. A group node contains the list of ball instantiations and the sound node which provides the impact sound effect. A time sensor provides a continuous cycle by which to run the animation. The script node does all the work of the simulation. Basically the time sensor output is routed to an update function, which does two main things. First, if any of the balls' sensors are currently active, ie if the user is dragging one, it resets all the unaffected balls (if the dragging has only just begun) and makes sure the balls outward of the key ball follow its motion so that it pushes them out ahead of it. It does this by looking at the number of the key ball and which way it has been dragged when the dragging starts (when tracking is false), and assigns the start and end ball numbers to a loop. All subsequent dragging in this direction causes the loop to assign the key ball's rotation to the rest of the line as well. If the dragging goes the other way and crosses the zero (vertical) point it re-assigns the loop limits to use the balls the other side of the key ball. Second, if none of the balls are being dragged it maintains the animation. The currently moving balls are all updated by a loop which calculates first the acceleration (from the current angular displacement, as per simple harmonic motion), then uses this to obtain the velocity, which in turn gives the position increment. The balls position and variables are then updated. When the ball passes the zero (vertical) point on a downward swing (as dictated by comparing currentAngle to lastAngle), all currently moving balls are zeroed and an equal number of balls at the other end of the array are given the equivalent angular speeds. At this point the collisiom checking subroutine also moves the sound node to the point of impact and sends the current time to the audio clip's startTime exposedField, thus providing the sound effect.

Appraisal

The whole model is successful on several levels, less so on others. On the whole I am satisfied with the modelling, but there are several things I would alter or add if there were time and processing power. The rear end of the hall looks a little blank; ideally I would have liked to have some sort of entrance vestibule leading to an outside of some sort, including doors and exterior modelling etc. This is plainly quite an extensive task and eventually there was not time. The ceiling needs some work, maybe better texturing, and the side walls would benefit from some sort of gargoyle or boss mounted between the gallery floors and just below the ceiling. The Newton's cradle object looks better than I had dared hope and I think is extremely successful. The only downside is the slow animation - there is just a little too much in the scene for the computer to do, so the faster the processor the better. The lights work well too, but I would have like to add some more interaction to make the scene more convincing. It is also worth noting that it is possible for the user to walk over the railings when walking diagonally downstairs - building these railings was fiddly enough to start with so I didn't really spend any time trying to correct this. Using the self-assessment calculator I give myself 68%.

Conclusion

In conclusion, the project was a complete success - I have completed the task I set out to do with almost no shortfall. The cradle works perfectly and the museum environment looks convincing and interesting. The only problems are with the speed and my personal niggles about the level of modelling detail.

References

A full reference guide to VRML 97 can be found at
http://www.vrml.org/Specifications/VRML97/index.html

The Cosmo 2.1 VR plug-in (for all well-known web browsers) can be downloaded from
http://www.karmanaut.com/cosmo/player/

The project was coded using VrmlPad, a shareware utility designed specifically for developing VRML. This can be found at
http://vrmlpad.parallelgraphics.com/