Evolution of CVE
The purpose of this document is to provide a context for ongoing and future
research and teaching on Unicon-based virtual environments.
In the beginning
There was Dr. J, playing lots of Everquest and wishing
that he were able to write programs like it. But MMO's take
years and millions of dollars.
- Naomi Martinez
-
Came out of the blue and wrote a
3D interface
for Unicon.
It featured OpenGL primitive shapes, materials and textures, and
simple lighting, but at a much higher level.
I assumed Unicon+Naomi would be too slow to do anything serious.
- Nolan Clayton
-
Worked on using Unicon network facilities to build a shared-view
collaborative editor,
Pegasus.
Pegasus kind of almost worked a bit.
(Nolan also made valuable cosmetic improvements to Unicon's IDE.)
Screen shots from these prototypes went into an NSF proposal to build a
virtual environment. And machines and 3D hardware kept getting faster.
Korrey Jacobs
Showed up at my
virtual environment interest group meetings, which started before the NSF grant came in. Korrey
wrote the first proof that using Naomi's 3D facilities, Unicon would work
for interesting virtual scenes with videogame-like high frame rates.
Since nothing but the camera moves, there is no Refresh() needed after
the initial render.
$include "keysyms.icn"
#
# main procedure
#
procedure main()
&window := open("Tha Crib", "gl", "size=800,750","bg=grey", "inputmask=k")
...
#render graphics
render()
#MAIN LOOP
camera()
end
#
# Render Graphics To Screen
#
procedure render()
#FLOOR
WAttrib("texmode=on", "texcoord=0,0,0,1,1,1,1,0", "texture=floor.GIF")
Fg("ambient black")
FillPolygon(-2.5,0,0, -2.5,0,-7.5, 2.5,0,-7.5, 2.5,0,0)
# WALLS
WAttrib("texture=walls.GIF", "texcoord=0,0,0,1,1,1,1,0")
Fg("diffuse blue")
FillPolygon(-2.5,0,-7.5, -2.5,5,-7.5, 2.5,5,-7.5, 2.5,0,-7.5)
FillPolygon( 2.5,0,-7.5, 2.5,5,-7.5, 2.5,5,0, 2.5,0,0) #RIGHT WALL
FillPolygon( -2.5,0,0, -2.5,5,0, -2.5,5,-7.5, -2.5,0,-7.5) #LEFT WALL
FillPolygon(-2.5,5,0, -2.5,5,-7.5, 2.5,5,-7.5, 2.5,5,0) #CEILING
#FRONT
WAttrib("texture=frontdoor.GIF", "texcoord=0,0,0,1,1,1,1,0", "fg=blue")
FillPolygon(-2.5,0,0, -2.5,5,0, 2.5,5,0, 2.5,0,0)
#COUCH
WAttrib("fg=black", "texture=cbottom.GIF", "texcoord=0,0,0,1,1,1,1,0")
PushTranslate(-1.70,0,-3.75)
Rotate(90,0,1,0)
FillPolygon(-1,0,0, -1,0.75,0, 1,0.75,0, 1,0,0) #bottom
WAttrib("texcoord=0.0,0.0,0.0,1.0,1.0,1.0,1.0,0.0")
FillPolygon(-1,0.75,0, -1,0.75,-0.75, 1,0.75,-0.75, 1,0.75,0) #cushion
Fg("red") #back rest
FillPolygon(-1,0.75,-0.75, -1,1.75,-0.75, 1,1.75,-0.75, 1,0.75,-0.75)
#left arm rest
PushTranslate(-1,0.8,-0.75)
WAttrib("texcoord=auto")
#cover the hole in the cylinder
PushTranslate(0,0.0,0.75)
Rotate(60,1.0,0.0,0.0)
DrawTorus(0.0,0.0,0.0,0.1,0.1)
PopMatrix()
Rotate(60,1.0,0.0,0.0)
DrawCylinder(0.0,0.0,0.0,0.75,0.2,0.2)
PopMatrix()
#right arm rest
PushMatrix()
WAttrib("texcoord=auto")
Translate(1,0.8,-0.75)
#cover the hole in the cylinder
PushMatrix()
Translate(0,0.0,0.75)
Rotate(60,1.0,0.0,0.0)
DrawTorus(0.0,0.0,0.0,0.1,0.1)
PopMatrix()
Rotate(60,1.0,0.0,0.0)
DrawCylinder(0.0,0.0,0.0,0.75,0.2,0.2)
PopMatrix()
PopMatrix()
#RIGHT WALL POSTER
WAttrib("texmode=on", "texture=Halle.GIF", "texcoord=0,0,0,1,1,1,1,0")
FillPolygon( -2.4,2,-3, -2.4,4,-3, -2.4,4,-4.5, -2.4,2,-4.5)
end
###############
#Set up the camera
procedure camera()
xdelta := ydelta := lookdelta := 0
repeat {
if *Pending() = 0 then {
if xdelta ~= 0 then elook := cam_move(xdelta)
if ydelta ~= 0 then elook := cam_orient_yaxis(ydelta)
if lookdelta ~= 0 then {
elook := lookx || "," ||
(looky +:= lookdelta) || "," ||
lookz
}
}
else case (ev := Event()) of {
Key_Up: elook := cam_move(xdelta := 0.05) # Move Foward
Key_Down: elook := cam_move(xdelta := -0.05) # Move Backward
Key_Left: elook := cam_orient_yaxis(ydelta := -0.05) # Turn Left
Key_Right: elook := cam_orient_yaxis(ydelta := 0.05) # Turn_Right
"w": elook := lookx || "," || # Look Up
(looky +:= (lookdelta := 0.05)) || "," ||
lookz
"s": elook := lookx || "," || # Look Down
(looky +:= (lookdelta := -0.05)) || "," ||
lookz
"q": exit(0)
-166 | -168 : xdelta := 0
-165 | -167 : ydelta := 0
-215 | -211 : lookdelta := 0
-Key_Up - 128 : xdelta := 0
-Key_Down - 128 : xdelta := 0
-Key_Left - 128 : ydelta := 0
-Key_Right - 128: ydelta := 0
-ord("w") - 128 : lookdelta := 0
-ord("s") - 128 : lookdelta := 0
}
myeye := "eye="||epos||","||elook||",0.0,1.0,0.0"
if myeye ~=== oldmyeye then {
write(myeye)
WAttrib(myeye)
oldmyeye := myeye
}
}
end
procedure cam_move(dir)
#variables holding the current eye position
#calculate new position
posx +:= dir*cam_lx
posz +:= dir*cam_lz
#store new eye position in the string epos
epos := posx||","||posy||","||posz
#update look at spot
lookx := posx + cam_lx
lookz := posz + cam_lz
return lookx||","||looky||","||lookz
end
#
# Orient the camera
#
procedure cam_orient_yaxis(turn)
#update camera angle
cam_angle +:= turn
if abs(cam_angle) > 6.283 then # if > 2 pi
cam_angle := 0.0
cam_lx := sin(cam_angle)
cam_lz := -cos(cam_angle)
lookx := posx + cam_lx
lookz := posz + cam_lz
return lookx||","||looky||","||lookz
end
My notes from a group meeting in January 2004 featured this code and said:
- need to build from data structure, not hardwired code
- build drawing tool, to generate the data structure
- Inspired by Korrey's work, we went and built a one-room demo for a room
(the PLEASE lab, for programming languages, environments, and automated
software engineering) in Science Hall at NMSU.
- Numerous students prototyped tools and extensions related to this prototype
- After the move to Idaho, the prototype became a series of progressively
more involved approximations of Janssen Engineering Building.