NeonJax 3D

NeonJax3D World Compiler Manual

Electronic Documentation for NeonJax3D World Compiler

Version 1.0

July 9th, 2002

Copyright (c) 2002 by Richard Goedeken

A product of Fascination Software Co.

Legal Stuff:

This software (NeonJax3D SDK Version 1.0) is copyrighted software. I give you (the LICENSEE) permission to freely copy and distribute this software in any manner to anyone (the RECIPIENTS) as long as the following two conditions are met:

  1. The LICENSEE may not charge the RECIPIENTS more than us$1 over and above the media and duplication costs for copies of this software.
  2. Any copies made by the LICENSEE must retain all of the original files and the original file structure from the ZIP file distributed by Fascination Software. (

Fascination Software, and Richard Goedeken, are not in any way liable for any damages incurred by the use of this software. The user assumes full responsibility for the use of this software.


This file contains information regarding the usage of the NeonJax3D World Compiler.

The NeonJax3D World Compiler (J3DComp.exe) is a Win32 console program which translates special text files (J3D Scene Source Files) into binary .J3D files which may be displayed with the NeonJax3D Screen Saver. J3DComp.exe takes only two command line parameters: the filename of the input (source text) file, and the name of the output (binary .J3D) file. Look at the batch files in the 'Worlds\' directory for examples of usage. The Table of Contents for this file is given below:

  1. Basic Overview
  2. Data Types
  3. 'World' Object
  4. 'Palette' Object
  5. 'Path' Object
  6. 'Scene' Object
  7. CmdStream Commands
  8. NeonJax3D Engine Overview
  9. Specifications & Limitations

1. Basic Overview

The NeonJax3D Screen Saver has 3 classes of visual displays:

  1. Background - The NeonJax3D background is a lavalamp-like plasma display. It is not user-configureable.
  2. 3D Objects - NeonJax3D is capable of displaying arbitrary triangle-based objects, with user-designed palettes.
  3. 1000 Points of Light - this is a special object which consists of 1,000 separate white dots. It has morphing capability and can display 12 different user-configureable effects. Only one 1000 Points of Light object may be in a Scene.

The NeonJax3D Scene File format is a simple object-oriented C-like language for creating 3D demo scenes. The NeonJax3D World Compiler is case-sensitive and ignores whitespace. There are four main object types: World, Palette, Path, and Scene. There must be exactly one World object and one Scene object, but there may be between 0 and 32 Paths, and between 0 and 32 Palettes. The Scene object must be defined AFTER all of the other objects; it should be the last object. The objects are defined like this:

ObjectType {
   // ...
   // Object properties and data
   // ...
   } ObjectNameIfPathOrPalette;

World and Scene objects may NOT have names, but Path and Palette objects are REQUIRED to have names.

The object hierarchy is shown below for reference:

NeonJax3D Object Hierarchy

World objects contain 'Name' and 'Version' properties, and Object objects. I apologize for the confusing nomenclature. The World object contains the templates for the 3D objects. They are like blueprints - a representation of the object but not the object itself. The Scene object contains the actual 3D Items that are displayed in the demo. These Items are created from the blueprints (Objects) which are in the World object. Thus the user may have only one cube Object (in the World) but 3 cubes in the demo (in the Scene).

Each Palette object is collection of 513 colors (numbered -256 to 256) which may be used to color an Item (in the Scene) or a Poly (in an Object). Each polygon displayed by NeonJax3D is painted with the color in the palette index proportional to the angle between the polygon surface normal and the light vector. If they are facing each other, the polygon will be colored with Color 256; if they are facing the same direction (the back of the poly is lit) then Color -256 will be used. If the polygon surface normal is exactly perpendicular to the light vector, then it will be painted with Color 0.

The Path object contains Segments which describe curves in a line drawing. A Path may be used in one of the special effects for the 1000 Points of Light object. This effect is called Marquee and causes the army of points to march along the path like lights around a movie marquee.

The Scene is the final object; it uses the data declared in the other objects and puts everything together to define all of the Items in the demo and their movements through time. The Scene contains 'Name', 'Version', and 'Light' properties, and Item objects. The Items represent the actual 3D objects which will be in the demo. Each Item has an associated Palette and one or more CmdStreams. The CmdStream (Command Stream) defines the movement (and morphing for the 1000 Points of Light) for each object. There are 3 types of CmdStreams: Translation, Rotation, and Morph. Only the special Points object may have a Morph CmdStream.

If this is all very confusing, then just look at the example files and it will make sense.

2. Data Types

The NeonJax3D World Compiler uses seven data types, listed below:

Data TypeUsed ForExamples

Name Various object names Bob  Poly42    _Blue
Text World and Scene 'Name' property "Cool Scene 42"
Int Version property, command operands 12  -37  8192  0xffe3
Float Command operands 42.0  99.99  0.001
Duplet Path segment starting X,Y (42, 73)  (-1,440)
Triplet Vertex coordinates, command operands (-60,60,15)  (12, 0, 0)
TriName Polygon definitions (Va,Vb,Vc)  (AB,_,b42)

There are 36 reserved words that the NeonJax3D World Compiler recognizes. These may NOT be used as names. Names may be up to 32 characters and must start with an alphabetic character or underscore. Names may include digits, but the first character may not be a digit. The reserved words are categorized below:

    Top-level directives:
  • World, Palette, Path, Scene

    Lower-level directives:
  • Name, Version, Object, Vertex, Poly, Color, Segment, Light, Item, CmdStream

    CmdStream types:
  • Translation, Rotation, Morph

    Translation and Rotation Commands:
  • Move, Stay, Spline, Orbit, Spin, MoveSpin

    Morph Commands:
  • EmptyCube, FilledCube, Sphere, Corkscrew, GridCurve, RandomCloud, SnowField, GaseousSphere, BouncingCubes, Vortex, Marquee, SaturnRings

    Reserved Names:
  • Points

3. 'World' Object

Each NeonJax3D demo must have exactly one World object. The reference definition for a generic World follows:

World {
   Name "My World Name";
   Version 1;
   Object {
     // vertices and polygons
     } Object1Name;
   Object {
     // vertices and polygons
     } Object2Name;
   // ...

The Objects which are defined in the World are templates for the actual Items which will be displayed in the Scene. These Objects are by default 'unpainted' in their definition in the World. A Palette is associated with each Item in the Scene, and this Palette is used by default for display. An example Object definition is:

Object {
   Vertex A (0,-40,0);      Vertex B (-20,40,20);
   Vertex C (-20,40,-20);   Vertex D (20,40,-20);
   Vertex E (20,40,20);
   Poly(A,B,C);       Poly(A,C,D);
   Poly(A,D,E);       Poly(A,E,B);
   Poly(B,E,D);       Poly(B,D,C);
   } Pyramid;

Each Vertex directive is followed by a Name and a Triplet, with a semicolon at the end. The Triplet (see 2. Data Types) specifies the X,Y,Z coordinates of the Vertex. Each Poly has a single operand, which is a TriName (see 2. Data Types). This specifies the names of the three vertices in this triangle. Since NeonJax3D uses a right-hand coordinate system (see 8. NeonJax3D Engine Overview), the three vertices in a triangle must be defined in a counter-clockwise order when viewing the front of the polygon. This will assure that the surface normal is computed correctly and that the lighting is correct.

Each Poly may be assigned a Palette in the Object definition if desired. This allows Objects to be painted with more than one Palette. To use this feature, put a Palette Name after the TriName in a Poly definition, as demonstrated below. This Palette will override the default (Item) Palette:

Poly (Vert1, Vert32, Vert73) White;

There is no practical restriction on the number of Polys, Vertex's, or Objects in a NeonJax3D Scene file. The only limitation is file/memory size. However there are limitations for the total number of vertices, polygons, and Items in a Scene. (See 9. Specifications & Limitations)

4. 'Palette' Object

Palettes are used to paint all of the 3D polygons that NeonJax3D renders. Each Palette has 513 colors, which are numbered from -256 to 256. The color which will be painted on a given polygon is determined by the angle between the polygon's surface normal and the Light vector (See 8. NeonJax3D Engine Overview). The equation relating these quantities is:

  • PaletteColorIndex = -256 * DotProduct(PolySurfNormal, LightVector)

If the front of the polygon is directly facing the light vector, the polygon will be colored with Color 256; If the polygon's surface normal is pointing in the exact same direction as the Light vector (the back of the poly is lit) then Color -256 will be used. If the polygon's surface normal is exactly perpendicular to the light vector, then it will be painted with Color 0.

Each Palette must have at least one Color object. Every Color directive is followed by a Palette index (-256 to 256) and an RGB Triplet. Each color component (red, green, and blue) in the RGB triplet must be between 0 and 255. The NeonJax3D World Compiler will interpolate between Color indices which are defined. Thus it is not necessary to define all 513 Colors; just define the 'key' colors and the NeonJax3D World Compiler will do a piecewise- linear interpolation between them. An example Palette definition follows:

Palette {
   Color 0 (0,0,0); // -256 through 0 are black
   Color 85 (255,0,0); // +85 is pure red
   Color 170 (255,128,0); // +170 is orange
   Color 256 (255,255,0); // +255 is pure yellow
   } Fire;

Each palette must have a name ('Fire' in the example above). The NeonJax3D compiler enforces a maximum of 32 Palettes in each J3D Scene Source file.

5. 'Path' Object

The Path object defines a series of steps along a path, which can be split into multiple Segments. This Path is used for the Marquee effect for the 1000 Points of Light object. Paths are composed of one or more Segments. Each Segment has two operands; the first one is a Duplet (see 2. Data Types) which specifies the starting X,Y coordinates of the Segment. The second operand is a Text block which specifies the steps to be taken on the path.

Each step along the Path can go one of four directions: -y, +y, +x, or -x. This is like North, South, East, and West. The text operand in the Segment object must contain only the letters n,N,s,S,e,E,w, or W, and white space. The example Path below demonstrates an 11-pixel square Path centered at 0,0:

Path {
   } Square11;

The 'PathFind\' directory contains a DOS utility program (PathFind.exe) which can read 8-bit BMP images, trace their contours, and output the NeonJax3D World Compiler compatible Path source code. This can be cut and pasted into your demos! Read the NeonJax3D Path Crawler Manual file for more information.

6. 'Scene' Object

The Scene object must be the last top-level object in the demo. The Scene defines the Items which are present in the demo, and gives them Palettes and streams of commands to guide their movements through time.

The Scene object has 'Name', 'Version', and 'Light' properties, and Item objects. The reference definition for a generic Scene follows:

Scene {
   Name "My Generic Scene";
   Version 0x0;
   Light (0,0,10);

   Item Pyramid {
     Palette Fire;
     CmdStream Translation {
       // translation commands
     CmdStream Rotation {
       // rotation commands
     } PyrObj; // end of Pyramid

   Item Points {
     CmdStream Translation {
       // translation commands
     CmdStream Rotation {
       // rotation commands
     CmdStream Morph {
       // morph commands
     } PointsObj; // end of Points object definition
   }; // end of scene description

The Name directive is followed by a single text string. The Version directive has a single operand of type Int. The Light directive takes a Triplet operand. Triplets are made of integers (the decimal point is not allowed in a Triplet). The magnitude of the Light vector does not matter, however, because the vector is normalized before it is used. The NeonJax3D engine does not use a point light source; the light comes from everywhere at the same angle. The direction of the incoming light is given by the Light vector. In the example above, the light is going in the +z direction (into the monitor).

The Item objects define the actual 3D shapes which will be in the demo. Each Item has an associated Palette (except the Points object) and one or more CmdStreams. All unpainted polygons in the specified Object will be colored with the Palette specified in the Item. The CmdStream objects define the movement of the Items through time.

There are 3 types of CmdStreams: Translation, Rotation, and Morph. Only the special 1000 Points of Light object may have a Morph CmdStream. As the demo is displayed, each Item sequentially executes the commands given in each of its streams. When an Item reaches the end of one of its command streams, that stream immediately starts over from the beginning. Control flow is linear - there are currently no commands for branching or looping. The definitions of the commands which may be used in the CmdStreams are in the section below titled 7. CmdStream Commands.

The Scene may contain up to a maximum of 256 Items. The total number of polygons in a Scene must be no more than 32,768. The total number of vertices in a Scene must be no more than 16,384.

7. CmdStream Commands

The Translation CmdStream type controls the 3D position of the Item, has 4 different commands, and one command (Orbit) which has two forms. The first parameter after each command directive is the number of frames for which the command will execute. The parameters which follow vary with the command. An example Translation CmdStream is presented below:

CmdStream Translation {
   Stay 100;
   Move 60 (0, -256, 512);
   Orbit 240 (25, -200, 400) 0.0 2.2; // Pc, Alpha(z), V(theta)
                                      // [degrees] [degrees/frame]
   Orbit 120 Star1 0.0 2.2; // Object Name, Alpha(z), V(theta)
                            // [degrees] [degrees/frame]
   Spline 120 (128, 0, 512) (0, 256, 400) 60 60;
           //      P1             P2      F1 F2

The Stay command causes the Item's position to stay stationary for the number of frames given by the first parameter. The Stay command has no extra parameters.

The Move command causes the Item to move with a constant velocity to the specified point. The Move command has one extra parameter, which is the destination point (a Triplet).

The Orbit command has two forms: the first causes the Item to orbit around a specified point, and the second causes the Item to orbit around another Item. The second parameter for the Orbit command is either the specified point to orbit (in a Triplet), or the name of the Item to orbit. The third parameter is an angle called Alpha(z) which determines angle of the path along which the Item will orbit. The range of the Alpha(z) parameter is: (-360,360). The fourth and final parameter for the Orbit command is the speed at which the item will orbit, called V(theta), in degrees per frame. If an Orbit command goes for 120 frames and orbits at a speed of 3.0 degrees per frame, then it will end at the point at which it started.

The Spline command does a two-stage spline movement using two specified points and two Int frame counts. Parameters 2 and 3 are 3D points (Triplets), called P1 and P2. Parameters 4 and 5 are Int frame counts, called F1 and F2. The Spline movement progresses through stage 1 starting at its current position and velocity, and ending at point P1 with its acceleration equal to zero (constant velocity). Stage 2 begins at point P1 with a calculated velocity (the end velocity from stage 1) and no acceleration, and ends at point P2. Stage 1 lasts for F1 frames, and stage 2 is F2 frames long. F1 plus F2 should equal the first parameter (the total frame count).

The Rotation CmdStream type controls the 3D angular position of the Item. This CmdStream type has 4 different commands. The first parameter after each command directive is the number of frames for which the command will execute. The parameters which follow vary with the command. An example Rotation CmdStream is presented below:

CmdStream Rotation {
   Stay     60;
   Spin     60 -6.0;            // [degrees/frame]
   Move     120 0.0 -90.0 45.0; // Phi(x)    Phi(y)    Theta(z)
                                // [degrees] [degrees] [degrees]
   MoveSpin 120 4.5 90.0 0.0;   // V(Theta(z)) Phi(x) Phi(y)
                                // [degrees/frame]  [degrees]  [degrees]

The angular position of each Item in the Scene is stored in three parameters. The first two, called Phi(x) and Phi(y), are like spherical coordinates. They specify an axis of rotation. The third angular parameter, called Theta(z), specifies the amount of rotation to apply to the Item around the current axis of rotation. For more information on this, see 8. NeonJax3D Engine Overview.

The Stay command causes the Item's angular position to stay stationary for the number of frames given by the first parameter. The Stay command has no extra parameters.

The Spin command has a single extra parameter, called V(theta). This parameter specifies the angular speed (in degrees per frame) at which the Item will rotate around its axis of rotation. The Item's axis of rotation will remain stationary during this time. If a Spin command lasts 50 frames and spins at 7.2 degrees per frame, the Item will end up in the same orientation in which it began.

The Move command causes the Item to move with a constant angular velocity to the given angular position. The three extra parameters for the Move command are Phi(x), Phi(y), and Theta(z). These are Floats and are interpreted to be in degrees.

The MoveSpin command causes the axis of rotation to move to a given angular position, and moves the Theta(z) position parameter at a constant rate. The first extra parameter for the MoveSpin command is called V(Theta(z)). This specifies the rotational speed of the Item to be applied to the Theta(z) position during the command, in degrees per frame. The last two parameters in the MoveSpin command are Phi(x) and Phi(y) and specify the angular position to which the Item's axis of rotation will move with a constant velocity.

The Morph CmdStream type controls the special effect to be applied to the 1000 Points of Light object. Each Morph command has two stages. During the first stage, the points morph between the old effect and the new effect. The second part of each Morph command executes the desired special effect. The morphing between effects is accomplished via a spline interpolation. The initial position and velocity are given by the final frame of the old effect, and the final position and velocity for each point are calculated from the initial state of the new effect. In this way the transitions between effects are as smooth as possible.

This Morph CmdStream type has 12 different commands. The first TWO parameters after each command directive are frame counts. The first parameter is the number of frames for which the Points will morph as described above from the previous effect to the new effect. The second parameter is the number of frames for which the new effect will execute. The parameters which follow these two vary with the command. An example Morph CmdStream is presented below:

CmdStream Morph {
  EmptyCube     60 1500 20;     // Point Spacing [pixels]
  FilledCube    60 120 20;      // Point Spacing [pixels]
  Sphere        60 120 100      // Minimum Radius [pixels]
                       120      // Maximum Radius [pixels]
                       15.0     // Velocity Theta(R) [degrees/frame]
                       8        // Radial Points [count]
                       125;     // Axial Points [count]
  Corkscrew     60 120 100      // Minimum Radius [pixels]
                       200      // Height [pixels]
                       1.5      // Minimum Velocity (Theta) [degrees/frame]
                       0.5;     // Minimum Velocity (Z) [pixels/frame]
  GridCurve     60 120 400      // Side Length [pixels]
                       1000     // Radius [pixels]
                       20       // Stationary Frames [count]
                       40;      // Moving Frames [count]
  RandomCloud   60 120 100      // X Size [pixels]
                       100      // Y Size [pixels]
                       100;     // Z Size [pixels]
  SnowField     60 120 448      // Initial Field Size [pixels]
                       0.285    // Scale Factor [degrees/pixel]
                       0.375    // Maximum Sin Acceleration [degrees/frame^2]
                       0.25     // Positive Threshold [coefficient]
                       -0.25    // Negative Threshold [coefficient]
                       0.625    // Maximum Force [pixels/frame^2]
                       0.00976; // Friction Coefficient [coefficient]
  GaseousSphere 60 600 150      // Radius [pixels]
                       20       // Points [count]
                       0.5      // Minimum Velocity [pixels/frame]
                       7.5      // Maximum Velocity [pixels/frame]
                       0;       // Minimum Radius [pixels]
  BouncingCubes 60 120 800      // Arena Size [pixels]
                       70       // Cube Size [pixels]
                       8        // Inter Points [count]
                       0.2539   // Gravity Strength [coefficient]
                       0.39868  // Outer Spring Coefficient [coefficient]
                       0.07629  // Outer Damper Coefficient [coefficient]
                       0.58313  // Inner Spring Coefficient [coefficient]
                       0.07019; // Inner Damper Coefficient [coefficient]
  Vortex        60 120 120      // Minimum Radius at top [pixels]
                       30       // Maximum Velocity (Theta) [degrees/frame]
                       2.0      // Minimum Velocity (Final Z) [pixels/frame]
                       10.0;    // Maximum Velocity (Final Z) [pixels/frame]
                                // vortex height is always 256
  Marquee       60 120 NukePath // Path Name
                       1.0      // Velocity [steps/frame]
                       200;     // Number of Points [count]
  SaturnRings   60 120 20       // Ring Height [pixels]
                       100      // Minimum Ring Radius [pixels]
                       200      // Maximum Ring Radius [pixels]
                       80       // Planet Radius [pixels]
                       1.0      // Planet Rotation Velocity [degrees/frame]
                       0.25;    // Minimum Ring Velocity [degrees/frame]

The EmptyCube effect causes the points to stay stationary in a cubic arrangement. The points will be on a grid surrounding the surface of a cube. The distance between adjacent points is given by the Point Spacing parameter.

The FilledCube effect creates a 10x10x10 cube which is filled with the Points. The distance between adjacent points is given by the Point Spacing parameter.

The Sphere effect creates a grid of points on the surface of a sphere and modulates the size of the sphere in a sinusoidal fashion. The Points are laid on the surface of the sphere in a series of stacked rings of varying radius. The number of rings is given by the Axial Points parameter, and the number of points on each ring is given by the Radial Points parameter. The product of these two quantities must be less than or equal to 1000. The Minimum Radius and Maximum Radius parameters give the size boundaries for the sphere as it changes size. The Velocity Theta(R) parameter gives the speed at which the sphere pulsates. At 20.0 degrees per frame, the sphere would go through a complete size cycle every 18 frames, or over 3Hz at 60 fps.

The Corkscrew effect gives each point a radius and a height value, and moves it around in a circle in the X-Y plane, and down in the Z direction. The radii of all of the points are distributed evenly within a range. The minimum (inner) radius is given by the Minimum Radius parameter. The thickness of the cylinder is equal to half of the Minimum Radius. The height of the cylinder is given by the Height parameter. The Minimum Velocity (Theta) parameter specifies the minimum angular speed of each point, and the Minimum Velocity (Z) parameter sets the minimum downward (+Z) speed of each point. The actual velocity (Z and Theta) for each point is chosen randomly in a range between the minimum and twice the minimum.

The GridCurve effect places all of the points on a large square grid (31 x 31 with a few left over). The points stay stationary in the X and Y plane but move in the Z direction to 'bend' around the surface of a sphere. In this way the grid is modulated to curve around a sphere. The Side Length parameter specifies the length of each side of the grid. The Radius parameter gives the radius of the imaginary sphere around which the grid will be bent. This parameter should be larger than the Side Length parameter. The timing of the grid's movement is handled by the Stationary Frames and Moving Frames parameters. The GridCurve effect executes a 2-phase cycle. First, the grid will be still (and flat) for Stationary Frames number of frames. Then the grid will curve through a complete sinusoidal cycle in Moving Frames number of frames. This 2-phase cycle is executed for the number of frames specified in the second parameter of the command.

The RandomCloud effect is simply a 'cloud' of randomly-placed points which move in small random steps. The three extra parameters specify the size of the cube in which the points are initially confined.

The SnowField effect simulates a set of particles which are confined to a plane and being acted upon by an underlying force field. The force field is a sum-of-sines vector field which changes with time. It is very similar to the background effect for NeonJax3D, but the force field is a vector field, and each point in the field has direction. The Initial Field Size parameter specifies the length of any side of the initial field of points. When the effect is running the points are allowed to spread out into an area with twice the side length, or 4 times the area. The Scale Factor specifies the scaling factor for the lowest frequency sine component in the force field. In order to make the effect look un-patterned, the product of the Initial Field Size and the Scaling Factor should be less than 180 degrees. The Maximum Sin Acceleration parameter controls the maximum rate at which the phase velocities of the sine components may be varied. The Positive and Negative Threshold parameters are used to create a 'dead zone' where the force field will not act on the particles at all. The Positive Threshold must be in the range [0,1], and the Negative Threshold must be in the range [-1,0]. The Maximum Force parameter specifies the maximum amount of force which may be exerted per frame on any point by the force field. The Friction Coefficient controls the amount of frictional force which will be applied every frame. Many of these parameters are very sensitive to variation. It may be easiest to start with one of the examples provided and tweak the values to see their effects. It is difficult to tune the parameters of this effect to get a good quasi-stable but dynamic state. It has the tendency to be either too dead (over-damped) or too chaotic (under-damped).

The GaseousSphere effect simulates a set of particles which act like oxygen molecules in a balloon. Each point travels with a constant velocity until reaching the edge of the sphere, where it ricochets while maintaining the same speed. The Radius parameter specifies the radius of the sphere containing the points. The Points parameter controls the total number of points displayed. The Points parameter must be greater than 0 and less than or equal to 1000. The Minimum and Maximum Velocity parameters give the range of point velocities. The actual velocity for each point will be randomly select in the range between these two values. The Minimum Radius must be greater than or equal to 0 and must be less than Radius. If this parameter is greater than 0, then the Points are initialized in such a way that they never enter any portion of the sphere where the distance to the center is less than Minimum Radius. In this way the points can be made to skim around the inner surface of the sphere rather than travel randomly in all directions through it.

The BouncingCubes effect simulates several cubes which behave similarly to cubes of gelatin. This effect simulates gravity and causes the cubes to bounce around within a virtual arena. The Arena Size parameter specifies the length of each side of the arena. The Cube Size gives the length of each side of each cube. Each cube automatically requires 8 points, for the 8 corners. Additional points can be added to the line segments between the corners. The Inter Points parameter controls the number of points between each pair of corners. The total number of points required for each cube is 8 + Inter Points * 12. The total number of cubes is floor(1000/PointsPerCube). The allowed range of Inter Points is [0,15]. The GravityStrength parameter controls the strength of the applied gravity. The BouncingCubes effect simulates the bouncing of the cubes by using struts: springs and dampers. There are 12 Outer Springs and Dampers which are placed between each pair of adjacent corners. There are also 4 Inner Springs and Dampers which are placed between the four pairs of opposite corners. The Spring and Damper in each pair are placed mechanically in parallel with each other. The Outer Spring and Damper Coefficients, and the Inner Spring and Damper Coefficients, adjust the properties of these struts to achieve the desired effect. This effect is also difficult to tune properly. Since most quantities are stored as integers, there are severe oscillations which can result from round-off type errors if the parameters are not properly set.

The Vortex effect is like a funnel or a whirlpool. Each point starts at the top (the mouth of the vortex, Z=0) with a random radius between Minimum Radius and 25% more than Minimum Radius, and proceeds downward in a spiral with an exponentially decaying radius. The height of the Vortex is always 256. The Maximum Velocity (Theta) parameter specifies the maximum angular velocity for a point, which is reached at the bottom (Z = 255). The Minimum and Maximum Velocity (Final Z) parameters control the range of possible final Z velocities for the points (at Z=255). The actual velocities (angular and Z) for a point are scaled back from the randomly pre-selected Final values. Both the angular and Z velocities are smaller at smaller Z levels (near the mouth of the vortex), and greater at higher Z levels (near the neck of the vortex).

The Marquee effect uses the Path objects to display line drawings in a movie marquee-like display. The Points march around the path referenced by the Path Name parameter. The Velocity parameter determines the speed of all of the points, in steps per second. The Number of Points parameter specifies the total number of points displayed for this effect. It is important to control the point spacing to make this effect look good. For example, if a Path has 1200 steps and you do a Marquee effect with 200 displayed points, then the points displayed will be 6 steps (or pixels) away from each other. The effect may not look good if this point spacing value is too low or too high. The Number of Points parameter must be greater than 0 and less than or equal to 1000. Path definitions may be created from two-color 8-bit BMP images with the PathFind.exe program. See the NeonJax3D Path Crawler Manual for more information.

The SaturnRings effect simulates a planet with rings. 250 Points are used to form the planet, and the remaining 750 Points zip around the belt of the planet to form the ring. The planet also rotates independently from the frame of reference of the Points object. The Ring Height parameter sets the thickness of the planet's ring, in pixels. The Minimum and Maximum Ring Radius parameters control the width and the inner radius of the ring. The Planet Radius parameter specifies the radius of the planet, in pixels. The Planet Rotation Velocity parameter gives the angular speed of one component of the planet's orientation state. The other two components of the planet's orientation state are incremented by a small value every frame. The Minimum Ring Velocity parameter controls the range of velocities of the points in the ring. Each point's angular velocity is randomly chosen in the range between the Minimum Ring Velocity and 5 times the Minimum Ring Velocity.

8. NeonJax3D Engine Overview
(a.k.a. Crash Course in 3D Graphics)

This section gives some of the low-level details of the NeonJax3D engine. The NeonJax3D screen saver engine is about 10,000 lines of MMX-enhanced assembly language code wrapped with a few thousand lines of C for interfacing with Windows. It was designed to be small and fast.

The 'camera' in the NeonJax3D world is placed at the origin (0,0,0) and is looking in the +Z direction. The 'up' vector of the camera is -Y. This means that the NeonJax3D coordinate system mimics the traditional raster graphics coordinate system. The center of the screen is (0,0,0) and X increases to the right, while Y increases down.

NeonJax3D uses a right-hand coordinate system. The rule of thumb (the right-hand rule) says that if you curl your fingers from +X to +Y, then your thumb will be pointing in the +Z direction. This means that Z increases INTO the monitor. Since the camera is located at (0,0,0), and the objects must be in front of the camera, the objects should have positive Z values in order to be visible. Any polygon or point with a Z value smaller than 32 or so will not be drawn. The perspective transform is calculated such that an object with a Z coordinate of 256 will have a 1:1 ratio between its world space coordinates and its screen coordinates. At Z = 128 an object will move 2 screen coordinates for every world coordinate, and with a Z coordinate of 512, the object will move 1/2 of a pixel on the screen per world coordinate moved.

A surface normal is a special 3D vector which is perpendicular to a plane. Surface normals are used for calculating the colors of polygons. Each polygon has its own surface normal vector which is rotated along with the polygon itself. NeonJax3D uses unit surface normals, so the length (magnitude) of each surface normal is one. Each polygon (triangle) has two sides, called the inside and the outside. NeonJax3D uses backface culling so polygons which are showing their inside side are not drawn. Only the outside of a polygon is shown. To make this scheme work properly, it is necessary to designate which side is the inside and which side is out. This is done in NeonJax3D by defining the vertices for each polygon in a certain order. The Poly directive (in an Object in the World) defines a polygon and specifies the names of its three vertices. To correctly define the polygon in a way which specifies the correct inside/outside orientation, the three vertices must be ordered in a counter-clockwise direction as a viewer is looking at the outside of the polygon.

Every polygon in the NeonJax3D demo is hit by light coming in the same direction. This direction may be defined by using the Light property of a Scene. The default Light vector is (0,0,1) which causes the light to move in a +Z direction. This creates very even and direct illumination. Polygons which are parallel to the monitor surface and facing the camera will be painted with Color 256 when using the default Light vector. If the Light vector is set to (0,0,-1) then polygons which are parallel to the monitor and facing the camera will be painted with Color -256.

The angular orientation of each Item in the Scene is controlled by 3 state variables, called Phi(x), Phi(y), and Theta(z). The first two are like spherical coordinates; they specify an axis of rotation. The Theta(z) variable specifies the amount of rotation to apply to the object around the axis of rotation. If the Theta(z) value is 0, then the object will not be rotated at all regardless of the values of Phi(x) and Phi(y). Refer to the diagram below:

NeonJax3D Axis of Rotation Angular Position Parameters

The diagram above shows the coordinate system of NeonJax3D, and the calculation of an axis of rotation. The axis of rotation starts in the -Z direction (0,0,-1) which is shown as point 1. The first operation is to apply a rotation of -Phi(x) about the X axis. This means that (using the right-hand rule) positive values of Phi(x) will cause the axis of rotation to be rotated UP. In the diagram Phi(x) is equal to 45 degrees and the new axis of rotation (shown as point 2) is (0,-0.707,-0.707). The second operation applies a rotation of -Phi(y) about the Y axis. Consequently, positive values of Phi(y) will causes the axis of rotation to be rotated to the RIGHT or counter-clockwise. The diagram shows the axis of rotation at point 3 after a rotation with Phi(y) equal to 135 degrees. The final axis of rotation will be at (0.5, -0.707, 0.5).

The Theta(z) value specifies the quantity of rotation which is applied to the Item around the axis of rotation. You may use the right-hand rule to determine directionality. Continuing with the diagram above, if the viewer's hand is at the origin and points the thumb in the direction of the axis of rotation, the fingers will curl in the direction of rotation which will be applied for positive Theta(z) values. In this case, the Item will rotate counter-clockwise around the axis of rotation (point 3) by Theta(z) degrees. This rotation is with respect to the object's center. All of the objects in the example files are centered around (0,0,0).

The Phi(x) value is valid from -90 to 90 degrees. The Phi(y) and Theta(z) values are both valid between -360 and 360 degrees.

9. Specifications & Limitations

Maximum Objects 65535
Maximum Scene vertices 16384
Maximum Scene polygons 32768
Maximum Palettes 32
Maximum Paths 32
Maximum Items 256


FS Home Page