The goal of a VR application is to represent a subset of reality.

A VR application is a 3D game, just without the game-like objectives-dynamics.
Since there is a lot more work done in games then their is in VR, and I know a lot more about games, I am just going to talk about games.
My goal in teaching you guys is to get you all working in some kind of 3d world, so that each of you feels comfortable doing something.
I will explain some of the architecture used in many game engines and graphical packages, and explain some detail about the different systems used in those engines.
Primarily I am trying to get people to work with this stuff, and not just hear about it, so I'll include nice demos of everything that I expect people to try.

Dual Representations

Two representations of the universe are contained within games.

1) An internal representation models different aspects of reality, including as how things move and interact.

2) An external representation displays the information from the internal model to the user.

First of all lets just do something.

This involves just the external representation, as this object will have no actual interaction with the game universe.
Load up the game and type:

sel /game/vis moves to the root of the scenegraph
new n3dnode asteroid creates a new n3dnode named asteroid as a child of the current node
sel asteroid selects the asteroid making it the current node
gen_mesh lib/asteroid/data/asteriod.n3d creates a nmeshnode that contains the mesh (set of polygons).
gen_tex lib/asteroid/data/asteroid.bmp creates a ntexarraynode that contains the texture
gen_shader simple creates a simple shader for this object
save saves this object to a file named asteroid.n for later use.

For ambience type

gen_skybox stars creates a skybox, using images from the directory "stars"

So what did that do?

It created a little tree composed of 4 nodes.

Since this tree is placed inside /game/vis (which is the root of the scenegraph) it gets displayed to the screen.

Explanation

NOH

Instantiations of most classes live somewhere in the NOH, or named object hierarchy.

Think of it as naming an object every time you new them, and then putting those names in a big tree.

Soon you have something very similar to a directory tree, where all the objects are easily accessible.

The part of the tree we created looks like

game
  vis
    asteroid
      tex
      mesh
      shader
This tree has a whole bunch of uses
  1. Objects can be quickly and easily referenced by name
  2. The structure of the tree itself is used to link objects.
  3. entire sections of the tree represent different parts
  4. This allows for easy persistence - pointers cant be saved/loaded from files, but named references can be.
  5. Readability - named references can be read much easier then pointers

All of this will make a lot of sense after working with it a little bit.

Simple Graphical Classes

We created 4 classes, each doing its part towards drawing the object on the screen.
n3DNode contains the location of the object, and forms the root of the tree for each node.
nTexArrayNode holds an array of textures - the array is neccessary for multitexturing
nMeshNode holds a mesh - a set of polygons that define the object.
nShaderNode is a huge class with tons of options that controls how the object is drawn to the screen.

Scenegraph

How do you keep track of all the objects you want to draw to the screen? The first way is just using a list, each object exists in the list and the list is walked each frame.

The best way to do it is using a scenegraph, which is the logical extension of this list.

SceneTree

Since many objects are hierarchical, i.e. a car & wheels, so we can use a tree to better represent things.

In this tree transformations at each node of the tree are passed down to children. The car contains the location of the car, the wheel just know their offset from the base of the car. As the car moves so do the wheels, even though the position contained in the wheel does not change. Using a list each wheel would have to continually determine the location of the car and place itself accordingly.

SceneGraph

The SceneTree becomes a SceneGraph when we begin to reuse information. It is wasteful to keep 4 wheels, when the only difference between them is their transformation. By using a simpler class containing just this transformation, and making the entire wheel the children of several transformations we can be more effecient.

This is implemented with a matrix stack. Each node has a very simple algorithm to draw itself

  1. Multiply my transformation matrix by the matrix on top of the stack, and push it on the stack.
  2. Draw myself
  3. Recur this function onto my children
  4. Pop the matrix off the top of the stack.

Lets look at the internal representation

Okay after much explanation we have created something, and explained how it is getting drawn.
The next step is to look at the internal representation.
Objects in the game are represented by entities living under /game/ent.
Each of these entities keeps a link to its corresponding node in the scenegraph that lives under /game/vis
That node looks just like the node we created before.
The entity however is very different as it has to act and interact with the world and not just get displayed.

Okay so lets create an entity for the asteroid we created before.
We need to reload the asteroid file from before (if we closed the game), and create an internal representation (entity) that corresponds with it.

sel /game/vis we want the asteroid to be loaded into the vis tree
get asteroid.n loads the asteroid from the file we saved before
sel /game/ent moves to the entity tree
sn nentity asteroid is a combination of sel and new. It creates and selects an object
setvis /game/vis/asteroid tells the entity where its visnode is, in our case the asteroid we created before.
sv pos 0 2 0 sets the variable pos (position) attached to that entity to 0 2 0
var displays all the information about the selected entity

Explanation

Entity Model

Each entity class is designed as a wrapper to hold data, it also connects to the vis node, and handles a few miscellanous things. Too add interesting behaviors we add classes called aspects as children of it in the NOH.
The result is a kind of powerful dynamic multipleinheritence, whereby game objects can gain modular methods and characteristics on the fly.
This seems much more complicated then it really is, so we'll skip over any further explanation for now.

Lets make it move

By adding aspects to the asteroid we can make it do whatever we want.

new nphysics physics This will add a rigid body physics model to the object
sv torque 0 0 10 Applies a torque to the object around the z axis.
var Shows all the new variables associated with the object since we attached the physics model

The asteroid should spin around the z axis for a while and then come to a rest.
It comes to a rest because the default physics settings include drag.
To get it to behave more like an asteroid in space lets change that.

sv rfriction .01 reduces the rotational friction so the asteroids looses 1% of its velocity every second.
sv torque 1 3 5 applies torques around all 3 axis's, to get a more natural spin.

For stabilities stake we still maintain some rotation friction, but it should spin virtually indefinitely this time.
Now Lets give it a push, and see how it moves

sv friction .01 reduces the linear friction so it looses 1% of its velocity every second.
sv force 0 0 10 applies a force along the z axis.

Now it should move forward slowly at a nice even pace, to keep it from getting away lets set it so that its position will wrap around.

new nAreaWrapAround wraparound wraps its position around a specified area.

Lets do it in script.

To get much further we need to move from using the console to scripts, as typing it into the console quickly becomes tedious.
Instead of just typing everything into giant initialization files, a unifed system for storing entities, aspects, and all their data.
Functions can then be used in initialization scripts to create the game world.
In nebula/data/lib there is a folder for every kind of entity.
Information about each entity is stored there, and the gen_ent function is used to create them.
I included a directory for this asteroid, as we can just start using it.

gen_ent asteroid creates an entity/vis node of type asteroid pair out of the library.

No console at all

nebula/data/scripts (refered to as scripts from now on) contains all the scripts.

go.tcl is the main script called when the engine is loaded, at the end of it just before game.start add:

gen_ent asteroid
Then run the game, now it should load up automatically.
Now lets create a bunch of asteroids, first change the gen_ent asteroid line to:
loadscript asteroids.tcl

Run it again and it should load a bunch of asteroids.

Go into asteroids.tcl, and uncomment (remove the #) the two lines. 
Now it should create a whole bunch of asteroids, each moving around at random speeds.
There is no collision model at this point, so they will pass through each other, lets fix that.
in data/lib/asteroid.ent.tcl (before the sel..) add: 
  new ncollisionnode collision
  cs collissionshape asteroid
  cs collisiontype object 

This file contains all the aspects and variable settings for the asteroid entity, by adding the collisionnode we give asteroids the ability to collide.
Rerun it, and this time the asteroids should bump into each other and bounce around.

If you are feeling brave you can try to import my aircraft model (platform) from my research project and try to fly it around and avoid the asteroids.

set ent [gen_ent platform] creates a platform entity and stores its name into ent
/game/camera.sref attachedto $ent sets the camera to follow the ent created above
/ui.ss selected $ent sets the interface to move the platform, instead of the camera.
new nareawraparound $ent/wraparound forces the plane to wrap around too