Ygdrasil changes list
Version 0.4
24 September 2004
- Added following commands to main program at command line:
- load(file) - load a scene file under local root
- create(type,[name]) - creates a node of class type with optional name under local root
- delete(name) - delete given node and all children
- Added following messages that can be directed to world (i.e. world.quit):
- graph[(node)] - print out scene graph from the root or optional node
- load(file,[node]) - load a scene file under local root or optional node
- save(file,[node]) - save to scene file from the local root or optional node
- create(type,[name]) - creates a node of class type with optional name
- delete(name) - delete given node and all children
- debug(type.message)|undebug(type.message) - set or unset debug message (or * for all) for a node name or type (or * for all)
- quit|exit - quits the application
- Changed 'createNode' message in ygNode to 'create'
- Changed naming convention for unnamed nodes
- new naming convention uses the node type followed by a unique number (i.e. switch ygSwitch1())
- creation of duplicate node names no longer produces an error
- Enhanced message passing facility
- graph printout now includes all non-default message variables including event triggers (i.e. when(enter,...))
- incomplete messages now use default values instead of generating error messages
- volume messages to ygSpace related nodes now create a canonical volume (i.e volume(sphere) is equivalent to volume(sphere 0 0 0 0.5))
- Enhanced event argumenting to include all node state variables
- argument variables use the message name followed by an optional argument number (i.e. $off give true/false, $position0 gives X position)
- examples:
- object(when(randomEvent,print(currently wall is $wall and floor is $floor))
- transform(when(randomEvent,print(current position X:$position0 Y:$position1 Z:$position2))
- CAVENavigator(when(randomEvent,print(currently fly:$fly collide:$collide))
- Added new ygScene node
- loads scene files in manner similiar to #include preprocessor directive
- saved files do not include nodes below the ygScene node
- initial messages given to a ygScene node are converted to the appropriate node name in the given scene file
- runtime messages can be given via the message message and also have their node names converted
- example:
- scene myscene(file(User),usernav.fly,userbody.height(4))
- node(when(randomEvent,myscene.message(usernav.togglefly)))
- Changed ygSpace volume debugging to allow debug message to be sent at any time
- Eliminated ygSimpleTransform in favor of a new ygTransform
- ygTransform now uses a similiar data structure to optimize network traffic
- all script references to ygSimpleTransform create a ygTransform node instead
- ygTransform now has a coordinates debug option to display the coordinate system
- Derived ygObject and ygTexture from a new class called ygGeometry
- ygGeometry base class includes draw(on|off|local|remote), cull(none|front|back), and wireframe(on|off)
- ygObject and ygTexture are no longer derived from ygTransform but create a parent ygTransform when given translation messages
- all script references to ygStaticObject now create a ygObject node instead
- Added ygCAVEHead node that creates a ygCAVETracker node and a ygHead child node
- Upgraded the sound server to use Bergen version 0.5
- 4 channel spatialized sound on SGI Indigo machines
- 2 channel stereo sound on Linux machines
- Changed the nodeTrigger related nodes to detect by actual class name instead of the alias used in the scene file
- this is the only change that requires existing scene files to be changed
- messages such as detect(node) and detect(object) should be changed to detect(ygNode) and detect(ygObject)
Internal changes:
- Changed ygNetKeys to ygNetMessages
- net messages are similiar to net keys except that they can be any combination of net key types
- all messages that represent state information are registered as ygNetMessages
- former netKey messages such as addNetKey have been changed to addNetMessage, etc.
- message variables are parsed from incoming messages before ygNode::message() is called
- this architecture creates a direct relationship between messages and node state variables
- allows for comparison between default and current state variables
- allows the graph printout to show all non-default state variables
- allows the save function to generate an accurate representation of the current scene graph
- allows the elimination of ygNode::acceptNetKey() method
- all incoming key/message changes are simply passed onto ygNode::message()
- Changed the networking to use QUANTA version 0.4
- the ygrepeater now blocks on UDP and TCP intercept() calls
- a shared library DSO is used to IRIX implementations and does not require a non-pthread version
- Added ygNode::updateDebug() as a virtual method to facilitate creation of debug related geometry
Version 0.3
8 May 2003
- Added YG_MESSAGE_PORT environment variable, to define the UDP port
number that yg will listen to for external messages. This defaults to
1967 (the port that the program sendMessage sends to).
- Eliminated separate bin & dso directories for Linux & SGI.
Now the directories are simply bin and dso,
and it's up to each site to make sure they have the right binaries
in them.
- Removed ygCAVEHead class (aka "CAVEHead" in scene files).
Added ygHead class to replace it; the new class is not derived from
ygCAVETracker. To add a CAVE-tracked head to an avatar, one must now
use:
caveTracker (sensor(0))
{
head ()
}
- Corrected ygUser's "message filtering" to not lose the
ygSimpleTransform messages - position, orientation, and updateInterval.
- Corrected ygSpace to not cause a core dump when resetting a scene
with debugging volumes (e.g. on triggers). (The core dumping was caused
by a bug in the Linux version of Performer's pfGeode class.)
- Changed format of commands that are accepted by the main
program (via the command line or UDP socket) to be the same as
node messages. Added optional arguments for 'graph' and 'stats'.
i.e., the commands now look like:
- texcheck - print number and total size of all textures in the scene
- texcheck(node) - print texture info for node and everything under it
- graph - print entire scene graph
- graph(node) - print sub-graph rooted at node
- stats - print timing statistics for entire scene
- stats(node) - print statistics for sub-graph rooted at node
- Added 'createNode' command to main program:
- createNode(type,name) - creates a node of class type, named name
- createNode(type) - creates a node of class type,
assigning it an arbitrary name (the generated name is printed)
- Added 'createNode' message to ygNode. Works the same as the command-line
function 'createNode', except that the new node is made a child of the node
that receives the message.
- Modified ygNode's 'event' message to allow an arbitrary number of arguments -
i.e., the event arguments no longer need to be grouped together in quotation
marks.
- Fixed ygEvent to return an empty string for non-existent event arguments.
Previously, non-existent arguments would cause a core dump. Now, for example,
something like
node (when(foo,print(a=$a)))
will print
a=
if it receives an event 'foo' with no argument 'a'.
- Moved source for pfTransform, pfBounds, & pfCull programs to separate
'tools' directory.
- Removed old XP-to-Yg translator program xptrans. The copy from earlier
releases should still be useable.
- Added different ygString::nextToken() function, that returns token in
pass-by-reference argument. Added new function ygString::previousToken();
works the same as nextToken(), but moves backward through the string.
- Added environment variable YG_PF_MULTIPROCESS, which can be used to
select the Performer multiprocessing mode to use. Its value is a list
of PFMP_FORK tokens, similar to the argument for pfMultiprocess(); they
can be separated by spaces or pipes ( | ) (the pipes are not required). e.g.
setenv YG_PF_MULTIPROCESS "PFMP_FORK_CULL | PFMP_FORK_COMPUTE"
If YG_PF_MULTIPROCESS is not set, then Performer's default multiprocessing
mode will be used (single process on single-CPU machines, fork CULL & DRAW
on multi-CPU machines) - the default is no longer to always fork CULL.
The shortcut macros, such as PFMP_APP_CULL_DRAW, are not available.
This option also supersedes the environment variable YG_PF_FORK_COMPUTE, which
is no longer used.
- Removed automatic use of C pre-processor on scene files. By default,
scene files will simply be read as is. To use cpp commands and comments
in a scene, you must now either preprocess the scene file by hand, or
setenv YG_CPP_COMMAND to the appropriate value ("/bin/cc -E" on IRIX,
"/usr/bin/cpp" on Linux (some Linux versions require a different command,
though)).
This was done because of recurrent flakiness with popen on
various systems - sometimes EVL's Onyx2 would have difficulty starting the
pre-processor subprocess; other SGI systems (e.g. ICC) don't have the compiler
installed; under Linux, sometimes not all of the pre-processor output is
actually read (this often manifests itself as the user avatar being missing).
It's recommended, therefore, that application developers pre-process their
scene files outside of yg whenever possible.
- Added functions vec2Args(), vec3Args(), and vec4Args() to ygMessage, to
return pfVec arguments more like the other functions (intArg() etc),
rather than through pass-by-reference, as in getVec2Args() etc.
- Made member variables of ygMessage (args, etc) private, and added functions
to return their values. The new functions are numArgs(), stringArg(#),
recipient(), recipientName(), delay(), and message().
The script 'updateClass' can be used to update most node classes that
need to be changed. It replaces msg.args.size() by msg.numArgs()
and msg.args[foo] by msg.stringArg(foo).
- Changed global class variables in ygWorld (World, FrameTime, FrameDeltaTime,
& FrameNumber) to class functions (world(), frameTime(), frameDeltaTime(),
& frameNumber()).
The script 'updateClass' will fix references to these variables in
node classes.
- Added "flag" message to ygWand.
- Added ygDataPacker class, as a replacement for CAVERN datapack class.
- Added thread-safe ygPrintf and ygFprintf functions.
- Removed ygNodeDB::init() call from main.cxx; this is now called
by ygPrePFConfig.
- Added ygHalt function, which replaces ygNet::halt() in main.cxx.
- Added "head" event argument to userTrigger's enter, exit, and firstenter
events.
- Modified ygMessage::writeString() to put double-quotes around each
message argument. This fixes a bug where single arguments with blank
spaces in them would turn into multiple separate arguments without the
quotes.
- Added "y" and "yes" as further values that will return 'true' in
ygMessage::boolArg().
- Fixed bug in Environment node - changes to the parameters (clip, skycolor,
fog) of an active Environment will now be properly applied on clients as
well as the master. Previously, the client side would not apply the changed
data, until the viewer exited & re-entered the Environment.
Internal changes:
- Changed indentation style in code. I now use 4 spaces per level
of indentation, and spaces only - no tabs.
- Replaced CAVERN socket classes by built-in yg socket classes.
- Changed ygCreateThread() & ygMutex to use plain pthreads in Linux,
rather than CAVERNsoft wrappers.
- Made the event name in ygEvent private. i.e. removed public variable
'event', and made it a private variable 'name_'.
- const'ed volume argument to ygWriteVolumeMessage and ygCreateVolumeGeoset.
- Moved CAVENav calls from ygCAVENavigator to ygCAVEViewer, which
looks for the local navigator to get the necessary data from.
- Changed modules/Makedefs.linux to use $(CC) instead of $(LD) to build
DSOs. Without this change, modules compiled with gcc3 fail to load -
dlopen gives the error "undefined symbol __dso_handle".
- Removed references to CAVElib-specific classes from ygDSOLoader.cxx;
their constructors are now added by a set of calls made from main.cxx.
This is so that ygDSOLoader itself does not need to be changed for the
FreeVR version.
Version 0.1.10
23 January 2003
- Revised networking to send key updates in batches. All new key
data is sent in one combined packet once per frame, or whenever the
64 kbyte buffer is filled. (To be precise, TCP and UDP communications
are batched separately.) Similarly modified the initial TCP download
to send all the keys in one large packet.
This makes networking incompatible with earlier versions - yg 0.1.10
will only run with other 0.1.10 clients and with the 0.1.10 ygrepeater.
This change should improve the performance under Linux. It seems that
Linux's TCP implementation makes all writes to TCP sockets synchronous,
whereas IRIX's TCP would buffer up the many small writes that yg
normally would perform.
- Added YG_DEBUG options net.tcpread, net.tcpwrite, net.udpread, &
net.udpwrite. These cause the NetClient to print information each time
data is read from or written to the TCP or UDP reflector socket.
- Added environment variable YG_NOCPP_COMMAND. If this variable is set,
the yg parser will simply open scene files directly, rather than opening
a pipe to a preprocessor command.
This option was added because, under Linux, the preprocessor pipe would sometimes
fail to return anything; this problem most often shows up in the form of a
user (avatar) not being loaded. When YG_NOCPP_COMMAND is set, scene files
should not contain any comments, #includes, or other preprocessor features.
You can run scene files through the C preprocessor manually, and give the resulting
file to yg.
- Added more information to the scene graph printout, which is invoked by the
'g' key or the 'graph' command. The new information consists of basic node data -
transformation values, switch state, etc.
- Fixed ground-following in CAVENavigator so that it should work better when
a user teleports.
- Corrected ygNode's "reliableKey" & "unreliableKey" messages to expect
one argument.
- Changed networking to default to reliable (TCP) communication for all keys
except matrix & coordinate keys. Setting the environment variable
YG_NET_DEFAULT_UNRELIABLE will cause all keys to default to unreliable (UDP).
- Reverted SGI version of networking to default to non-threaded; Linux
version defaults to threaded.
Added environment variable YG_NET_THREAD, which can be set to 0 to
force non-threaded mode, or 1 to force threaded mode.
- Removed "refresh" feature of networking for simplicity, since it isn't
really used.
- Fixed ygrepeater to exit with a message, rather than core dump,
if another repeater is already running on the same port.
- Modified ygUser to not print an error message when navigator messages
are received. This is equivalent to the fix from EVL's 0.1.5.
Version 0.1.7
15 October 2002
- Incorporated all changes from EVL's Version 0.1.5 (as of 3 Oct).
These include:
- Added 'heading' message and setHeading() function to ygCAVENavigator.
- Added 'buttonUp' flags to ygCAVEWand
- Added ambient & specular attributes to ygLight
- Added pfChanged(), setPFChanged() functions to ygNode.
- Added ygTexture class
- ygSound's event 'StopPlaying' changed to simply 'stop'.
'StartPlaying' event also changed to simply 'start' - the EVL 0.1.5
version lacks a 'start' event.
- Corrected ygVolUtil to use PFGS_WIREFRAME instead of PFEN_WIREFRAME.
- Added pfBounds, pfCull, and pfTransform programs to src directory.
Note: did _not_ include EVL changes to ygUser which eliminated other
inherited messages. The EVL version would get rid of the bogus
errors whenever navigator messages are sent to a User, but I don't feel
it's worth breaking the existing structure & losing use of certain messages.
- Changed PFUTEX_SHOW environment variable to YG_PF_SHOW_TEXTURES
- Added environment variables YG_PF_FORK_COMPUTE and YG_PF_INIT_SMOKES.
If these variables are set, the main program will fork a Performer compute
process and call pfuInitSmokes, respectively. These two features were needed
by Alive on the Grid, but are not needed for most other applications.
- ygPrePFConfig() automatically adds YG_PATH to Performer's file path, so
setting PFPATH to the same value is no longer necessary.
- Added environment variable YG_PF_DBASE_CONVERTERS. This variable can be
set to a space-separated list of model extensions (e.g. "flt iv obj"), and
ygPrePFConfig() will call pfdInitConverter for each extension listed.
- Removed most of the stuff from the 'modules' directory. It now contains
just 7 basic classes that should be enough for getting started. All other
modules should be distributed in a separate package.
- Back-ported some changes from my 0.2.1 development version:
- Modified ygEnvironment to better handle cases where 2 or more environment
nodes overlap. Previously it was possible to exit an overlap zone and not
have the correct environment activated (because the node that should be
applied thought that it already was). Now the correct environment will be
applied outside of overlap zones; inside an overlap, the last environment
node to run its app function still wins.
- Modified ygNodeDB / ygDSOLoader to have just the DSOLoader keep track of
constructor pointers. This change makes it possible for a module to list
built-in classes in its dependencies without causing problems (thus a module
writer doesn't have to keep track of which classes are built-in and which
aren't).
- Added optional second argument to "file" message of ygObject & staticObject.
The argument is a bool value which temporarily overrides the "cache" setting
(to allow loading uncached models with one message, instead of two).
- Added "reload" message to ygObject & staticObject.
- Made ygObject & staticObject include their cache-flag in their networked
data, so that clients will cache or not cache models the same as the master.
Version 0.1.6
20 September 2002
- Modified ygNetClient, so that the initial database download (downloadViaTCP())
is done over a different connection, rather than the TCP reflector connection
that is used for updates while the program is running. By default, this connection
is to the same host ($YG_NET_SERVER), with 1 added to the port number (i.e. 3501
or $YG_NET_PORT + 1). This can be changed by the environment variables
YG_NET_CACHE_SERVER & YG_NET_CACHE_PORT (although there's no reason to actually
use these variables at the moment).
ygrepeater has been modified so that now the main process is simpler, just a
UDP & TCP reflector. It passes copies of all incoming packets to a second thread
(through a large block of memory); this second thread takes care of parsing the
packets to keep a copy of the Yg database, and it creates the 'cache' socket
that downloadViaTCP() will connect to.
The result of this should be that when new clients connect, existing clients will
_not_ be frozen. The main reflector thread will continue on as normal. If the
download takes a very long time, the shared memory buffer used to send packets from
the main to the cache thread may run out of space, in which case any more data that
would have been sent to the cache thread will be dropped, but the reflector will not
block.
(Ugly tech detail: I created the class ygrepeaterQueue to handle passing data between
ygrepeater threads in a large malloc'ed buffer because all fancier IPC mechanisms -
pipes, message queues, sockets - have very limited buffer sizes, usually just a few
kilobytes of kernel memory. For our types of applications, it needs to be capable of
buffering up several megabytes of data.)
- Modified ygNet / ygNetClient to add reset() function. This is meant for cases
where the ygrepeater crashes and must be restarted, so that clients can reconnect
& re-synch without having to exit and start over from scratch. ygNetClient::reset
will close & reopen its TCP socket (UDP being connectionless, nothing needs to be
done), and then re-downloads the current state of the database, and uploads all of
the keys that the local client owns.
This function will be called in response to a 'netreset' command sent via sendMessage,
or typed at the command line.
- Modified the main program to read commands / messages from the keyboard (stdin),
in addition to a UDP socket.
- Added a function ygMakeValidNodeName(string), which will force a string to consist
only of letters, numbers, and underscores. All other characters are converted to
underscores. This function is applied to the base-string for all dummy names that
Yg assigns to unnamed nodes.
Previously, some hosts would produce nodes with names such as 'mediastudy1.fal.buffalo.edu771'.
Such names would cause problems when sending messages to the nodes (and caused problems
for the pyNode classes). Now, the name would become 'mediastudy1_fal_buffalo_edu771'.
Names that are explicitly defined in a scene file are not affected. e.g.
light foo.bar ()
will still create a node named "foo.bar". In the future a warning (or perhaps a fatal
error) should be produced for these names.
- Tweaked ygTokenStream to better catch/report unclosed parentheses. It will now
report the line number of the opening, unclosed parenthesis.
- Added ygNet::midframeProcess(). This function is called by ygNode::app(). If the
environment variable YG_NET_PROCESS_INTERVAL is set to a non-zero value, then
midframeProcess() will try to make sure that ygNet::process() is called once
every $YG_NET_PROCESS_INTERVAL seconds. This is meant to prevent the network sockets
from being overloaded with incoming data in a high-bandwidth application.
- To go along with midframeProcess(), changed ygNet::storeKey() to immediately pass
the data to ygNetClient::put*() if we're not running in threaded mode, rather than
copying the data into the queue and then reading it back out again later in the
same thread. This should space out the put()s better in high-bandwidth cases,
to hopefully reduce any loss of outgoing UDP packets.
Version 0.1.5
12 November 2001
- added function ygNode::isOfClass()
- added volumeType() function to ygVolume and all subclasses.
defined constants YGVOL_INFINITE, YGVOL_POINT, YGVOL_BOX, YGVOL_SPHERE, and
YGVOL_CYLINDER for return values.
- removed all dynamic_casts, replaced by calls to isOfClass() or volumeType().
This clears up the mysterious crashes that occur under some versions of Linux
& g++.
Version 0.1.4
- added --noview argument to main program, to run 'server mode'
- main program will accept multiple scene files on the command line,
so that a User file (for example) can be loaded separately, rather
than #included
- made main program remove all its nodes from the scene graph
when exiting
- added virtual destructors to volume and node classes
- added assignment operators to volume classes
- added check to ygNodeDB::create - prints a warning message when someone
creates two nodes with the same name
- added timing statistics collection to ygNode
- added ygServerMode() (and ygSetServerMode()) for AEC show development -
so people can leave out code that doesn't need to be executed on the
view-less server
- added ygFileRequest & ygFileServer for remote file uploads & downloads
- added showLocal command to ygObject (and corrected its behavior in staticObject
so that it won't crash if called before an object is loaded)
Version 0.1.3 and earlier
- 9 Aug 2001:
- modified network database refreshing to try to avoid calling acceptKey when
a key's data hasn't actually changed. done by comparing a checksum of the
old & new data. note: this is not done when a key is received the normal
way (as a result of netKeyChanged() on the master); in that case, acceptKey
is always called.
- added Ygdrasil version number to all headers, so you can verify that you're
using the correct ones
- 21 Aug
- 23 Aug:
- 24 Aug:
- added YG_NET_DEFAULT_RELIABLE environment variable. if this is set, all keys
(except matrices) will default to reliable transmission; otherwise, they
default to unreliable.
- 31 Aug:
- added ygSimpleTransform class - transformation that consists only of translation
& rotation.
- added COORD netkey type, for SimpleTransform
- changed ygCAVETracker & ygUser to be derived from ygSimpleTransform
- added 'cache' message to ygObject
- added filename() function to ygObject
- added several safety checks for NULL pointers to ygString
- changed "matrix" netkey name in ygTransform to "m", to reduce network traffic
- modified message sending in ygWorld - if a node does not exist locally, it will
not spend several seconds looking for it on the network, but just print an
immediate error message
Last updated 15 October 2002.
Res Umbrae home page