Using SVE for Virtual Environment Applications
Using SVE for Virtual Environment applications
I. Introduction
- SVE: Simple Virtual Environment Library
- What is a virtual environment?
For our purposes - An immersive VE is a 3D space surrounding
the user which is drawn with real-time computer graphics and where
the view is determined by head position/orientation
- What does SVE do for you?
- rendering objects/polygons/lighting/textures
(low-level openGL, window system, doing persp. projection, etc.)
- tracking details
- hardware configurations
- handle events (mouse button, key press)
- default locomotion through the world
- lots and lots of built-in functions
- move objects, rotate objects, visibility, picking, materials,
collisions, matrices, etc.)
- What do you have to do?
- provide models (from Wavefront)
- provide application code
(interaction with the world routines, special rendering,
manipulating objects/materials/lights, etc.)
II. The simplest SVE program and what it means
#include "sve.h"
main(int argc, char *argv[])
{
SVE_init("my_app", SVE_NORMAL, argc, argv);
SVE_loadWorld("myworld.world");
SVE_beginEventLoop();
}
- This program loads in your model and lets you look at it and
fly around it
- these three statements must be included in every SVE program
- configuration flags
- SVE_NORMAL - flat shaded, no tracking (on screen), no textures
- SVE_LIGHTING - use lighting effects
- SVE_GOURAUD - use Gouraud shading
- SVE_TEXTURES - use textures if specified
- SVE_HMD - use the trackers and other VE hardware
- SVE_AUDIO - audio is on
- etc...
- these should be "or'ed" together
(e.g. SVE_TEXTURES | SVE_HMD
)
- world file
- list of objects, positions, and attributes
- objects are in a "tree" structure - parents and children
- simple example:
Simple Virtual Object File Format version 1.0
number of objects: 2
object name: couch
primitives file: couch.obj
transformation matrix:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
other attributes: 0
number of children: 0
object name: table
primitives file: table.obj
transformation matrix:
1 0 0 0
0 1 0 0
0 0 1 0
-5 0 0 1
other attributes: 0
number of children: 1
object name: lamp
primitives file: lamp.obj
transformation matrix:
1 0 0 0
0 1 0 0
0 0 1 0
0 2 0 1
other attributes: 0
number of children: 0
event loop: what SVE does over and over again
- Call Animation callbacks (if any)
- Get tracker data (if tracking) and set user position
- Get events (mouse, keyboard, stylus)
- Call appropriate event callbacks (if any)
- Call Frame callbacks (if any)
- Render scene
- Call Frame End callbacks (if any)
- callback: just a function that is called every time the
appropriate thing happens (frame is rendered, button is
pressed, button is released, etc.)
- SVE has default callbacks for keyboard, left mouse
button, middle mouse button
- callback prototype:
SVE_status myCallback(SVE_state state)
SVE_status is either EVENT_CONSUMED
(don't call any more
callbacks of this type right now) or EVENT_IGNORED
(move
on to the next callback in the list)
III. A more advanced example
This example program presents a spinning cube in a virtual
environment. It initially spins at 1 degree per frame. The
rate of spinning can be increased by pressing the right mouse
button, and decreased by pressing the left mouse button. This
example illustrates the use of mouse and animation callbacks.
#include "sve.h"
SVE_object cube;
int num_degrees = 1;
SVE_status spinCube(SVE_state state)
{
SVE_rotateObject(cube, num_degrees, 'y');
return(EVENT_IGNORED);
}
SVE_status increaseDegrees(SVE_state state)
{
if(SVE_IS_PRESS_EVENT(state->eventType) &&
((SVE_stateChangeEvent *)state->eventData)->pressed)
num_degrees++;
return(EVENT_CONSUMED);
}
SVE_status decreaseDegrees(SVE_state state)
{
if(SVE_IS_PRESS_EVENT(state->eventType) &&
((SVE_stateChangeEvent *)state->eventData)->pressed)
num_degrees--;
return(EVENT_CONSUMED);
}
main()
{
SVE_init("my_app", SVE_NORMAL);
SVE_loadWorld("cube.world");
cube = SVE_findWorldObject("cube");
SVE_addAnimationCallback(spinCube);
SVE_registerCallback(SVE_LEFT_MOUSE, decreaseDegrees);
SVE_registerCallback(SVE_RIGHT_MOUSE, increaseDegrees);
SVE_beginEventLoop();
}
IV. Distributed processes (servers)
- tracker server: gets info from trackers and sends it to the
main SVE application; must be run on the machine the trackers
are connected to
~vrgroup/sve/v2.0/bin/sgi/server-tracker
- audio server: plays sounds requested by the SVE application;
must be run on the machine where you want the audio output
~vrgroup/sve/v2.0/bin/sgi/server-audio
- event server: sends events to the SVE application; must be
run on the machine where you want to input events (mouse buttons,
key presses)
~vrgroup/sve/v2.0/bin/sgi/server-event
- specify which machines in your .sve.init file:
audioserver swift
eventserver swift
tracker 1 dunwoody fastrak /dev/ttyd2 2 SVE HMD
tracker 2 dunwoody fastrak /dev/ttyd2 3 SVE cursor
trackerhemi 1 0 0 -1
trackerhemi 2 0 0 -1
V. How the user is modeled
- SVE has a default object tree which is always attached to
the world, which represents the user:

- origin: spot on the floor - (0,0,0) for user coord. system
- user: user's position in the world - tracker transmitter
- hmd: position of user's head
- eye: position of user's eye - scene rendered from this POV
- other eye: 2nd eye - used for stereo rendering
- cursor: position of user's hand
- to move the user to a new spot in the world - move the origin
object
- to check if the hand is touching an object, check the cursor
object
- to find out if the user's view is somewhere, check the eye
object
VI. Important SVE functions
VII. Important SVE data structures
- SVE_state - current system state: pointers to important objects,
event information, flying speed, etc.
- SVE_object - object information: name, position, worldPosition,
geometry, boundaries, materials, visibility, etc.
- SVE_material - material information: name, texture, color, etc.
- SVE_point - 3 floats representing a position
- M_matrix - 4x4 matrix (position is in row 4)