Space Viewport 2.0

Case Study: Space Viewport 2.0

Related Topics:
Space Viewport
Perspective & Other Depth Cues
Data Structures and Recursion

View controls:
Drag in viewport to pan
Drag on ‘radar’ to pan
Alt-drag in viewport to zoom
Click ‘follow’ to follow ship
Ship controls:
left/right arrows to turn
ctrl to thrust

Space Viewport 2.0source movie

This demo builds on the first version by giving universe elements a depth and rendering with some depth cues, and also storing the universe model in a tree rather than a list.

Depth & Perspective
The field of action is still two dimensional, but adding depth makes the visuals more interesting. It’s pretty simple to do. Each element is given a z coordinate which is used for perspective and for blendlevel (haze) and locz (z-axis blocking).

Notice how the method uniToView() which maps universe to screen coordinates now makes use of the perspective value. First the offset from the camera is found (vec – camVec), then perspective is applied, then zoom and shifting:

on uniToView(vec)
vec = (vec – camVec) * persp
loch = vec.x * zoomLevel + viewRect.left + viewRect.width/2
locv = vec.y * zoomLevel + + viewRect.height/2
return point(loch, locv)

Tree Structure for the Model
Instead of being stored in a list, the objects of the universe are now stored as a tree. The universe object is the tree root, and each object’s position is relative to its parent. The circling planets show how the tree structure simplifies the programming—the planet script doesn’t need to take into account how the sun fits into the rest of the scene. For more on using a tree and transforms in animation see 3D World and the other 3D quad demos.

Migrating to a tree structure was made much easier by inheritance. Simply making the treeNode script the ancestor of universeElement gave all the model objects the properties and methods of a tree node.

This demo is a relatively rare example of the use in Lingo of a series of inheritance, where a script’s ancestor itself has an ancestor. For example, ship inherits universeElement which inherits treeNode. Does it make a difference if universeElement and treeNode are reversed in the order? It wouldn’t to the ship script, but there are reasons to arrange it the way it is. Abstractly, according to the “is a” relationship of inheritance, universeElement is a treeNode but treeNode is not a universeElement. Practically, if you wanted a node just for grouping in the model you can now just use a universeElement object (because it inherits from treeNode).