VRML Behaviors
This paper proposes a way to add behaviors to VRML. It address mainly the extensions needed to VRML to author links to seperate behavior scripts.
This document is part of a collection of VRML2.0 history at http://www.mitra.biz/vrml/vrml2/mw_history.html
This version: Mitra <mitra@mitra.biz>, 25 Oct 95.
History and Dependencies
This proposal is a completely new rewrite of Mitra's behavior proposals. It replaces the previous papers for Behaviors [1] and Connectors, Sensors and Triggers [2].
This paper draws heavily on the proposals by Sony [6], [7] [8] and SDSC [9], and is an attempt to merge the best ideas from these and my own papers.
This proposal does not primarily address the API here. This proposal doesn't significantly constrain the API away from the general ideas that either SDSC, or my proposals cover. See the companion paper on APIs [3].
There is also a brief paper on a number of pseudo-nodes that allow behaviors to access browser state - this is independant from this paper. See Pseudo Nodes [4]
This paper also assumes that Separators change as anticipated for VRML1.1, and that the Interface proposal [5], or something like it, becomes part of VRML1.1.
Overview
Firstly - it appears that we are all looking for a Object-Oriented approach, but I think the proposals diverge from this to a certain extent. To be O-O the author should probably be thinking something like ...
An Object has:
- A collection of geometry, data and properties - essentially the existing VRML plus some parts of the Interface proposal.
- A collection of behaviors or methods
- A set of event handlers that link actions on the objects to behaviors/methods on this object or others.
If our O-O model is essentially that a Separator is our Object (since any lower level of detail may have been thrown away by the browser), then this could get fairly easy. Basically we have to:
- Indicate the set of behaviors associated with the object (or class)
- Attach a collection of event handlers to it
The various Nodes in all three proposals composite some or all of three sections,
- A way to specify which behavior file to use - this specifies a filename and a scriptType.
- A way to specify the function to call - specifies the procedure, and parameters
- A way to specify an event - specifies eventType (optional parameters)
One syntax to do this.
Separator {
behavior "" ; MFSTRING e.g. "http://foo.com/mycode.java"
scriptType "" ; SFSTRING e.g. "java", the default "" means a ScriptNode
events {} ; MFNODE list of EventHandlers
}
EventHandler {
eventOn "" ; SFSTRING Node name to watch, default to this Separator
eventType "" ; MFENUM PICK|WORLDIN|WORLDOUT|GRAB|DRAG|RELEASE|FIELD"
actionObject "" ; SFSTRING Node name to send method to
; defaults to this Separator
actionMethod "" ; defaults to Null Event
actionParameters [ ] ; MFFIELD e.g. [ SFColor 1 0 0 ]
}
Notes
- This Differs from SDSC in that it calls a method on the object, rather than calling the method with an object as a parameter - although of course it could be implemented that way in non O-O languages like Perl.
- The behavior is MFSTRING, this doesn't support multiple behaviors, it supports multiple locations for the same behavior in keeping with The URN proposal
- EventHandlers are on the events field of the Separator, they could be children of the Separator, but this structure is more in keeping with VRML1.1 Separators.
- Null Event
EventHandler { eventType PICK } is a null event for PICK and blocks propogation up the tree.
- SFFIELD/MFFIELD
Is a new data type, an SFFIELD is a field type followed by its value, or a USE of another field.
e.g. actionParameters [ SFColor 1 0 0 , SFLONG 1.234, SFSTRING "Fred", USE MyCar.color ]
This could be implemented using MFSTRINGS, but this just moves load-time parsing to run-time.
- EventOn
This field is only used when a EventHandler is specified seperately from the object it refers to, typically for example this would be used by an Alarm that wants to attach itself to a previously defined Door. In most implementations this would lead to the Node being added to the Doors event list.
Examples
The following examples are taken from various papers, and converted to this scheme, note that
most of the examples in all of the existing proposals get syntactically more complex with the Interfaces proposal, and VRML1.1 style separators.
A cube that changes color when picked and again when released
This is an easy example because the action is performed on the same object on which the event occurs.
DEF foo Separator {
behavior "change.tcl"
scriptType "tcl"
events {
EventHandler {
eventType GRAB
actionMethod "change_color"
actionParameters "SFCOLOR 1 0 0"
}
EventHandler {
eventType RELEASE
actionMethod "change_color"
actionParameters "SFCOLOR 0 0 1"
}
}
Cube {}
}
Turning the lights on when the switch is grabbed
DEF MyLight PointLight {
on FALSE
}
DEF MySwitch Separator {
events {
EventHandler {
eventType PICK
actionObject
actionMethod "set SFBOOL on TRUE" ; Trivial behavior
}
}
}
Inline behaviors
Inline behaviors can be specified as in Sony's proposal
They are pointed to by leaving ScriptType as the default, and specifying the name of a ScriptNode, or leaving it blank to point at some applicable one.
Open Issue: Where to put this? inline in the Behaviors, or a seperate node or what?
A tiny language can be embedded in the "actionMethod" field directly to describe some simple methods.
For example,
EventHandler {
eventType GRAB
actionMethod "set SFBOOL on TRUE"
}
Only the following syntax can be used for describing method.
- set FIELDTYPE FIELDNAME CONSTANT
- load URL
EventTypes
If the eventType field is to be an SFENUM then we need a complete list of possible events, the parameter field gives us some leeway to experiment later. This is a start of the list.
- PICK
When the mouse is clicked on the object
- GRAB,RELEASE
When the mouse is held down on the object, and when it is released.
The OS will decide whether the mouse-click is short enough to send as a PICK event, or whether to send GRAB and RELEASE. Also that DRAG events only occur inside GRAB,RELEASE pairs.
- DRAG
Sent when a GRAB-ed object is moved. The position and orientation of the object being moved are available as properties of the Separator.
- LOD_IN and LOD_OUT
When the object is active, and inactive. Typically a behavior may use these events to suspend behavior, or to reduce the CPU cycles this behavior absorbs - for example a mobile object might keep track of where it was, but suspend updating the geometry.
- ENTER and LEAVE
Are triggered when the users viewpoint enters or leaves the bounding box of the object.
- COLLISION
Triggered when the user collides with the object, note this is independant of the changes being made to the Separator to incorporate collision detection. The Collision event is triggered when the collision detection logic prevents the user entering an object. It is never called in conjunction with Enter and Leave.
- WORLD_IN and WORLD_OUT
(from Sony's paper) I believe these are when the world is loaded, and when it is unloaded. Note these are distinct from the Init and End methods which are called when the applet is loaded and unloaded.
- FRAME
Sent once per frame.
Field events
The EventHandler structure doesn't support events which require parameters in order to be triggered. So a small set of extra nodes will need defining for more complex events. The FieldEvent is one example of this, it allows a behavior to be triggered when a field changes value.
FieldEvent {
eventOn "" ; SFSTRING Node name to watch, default to this Separator
field "" ; SFSTRING field to watch
actionOn, actionMethod, actionParameters ; as for EventHandler
}
This could be extended to allow more complex tests - for example only trigger when this field goes to TRUE, however is is not clear that the added complexity is worth it, as compared to having the full power of a programming language available in the behavior. Typically the field being watched will be passed to the Applet in one of the actionParameters.
Timers
Two features facilitate timers indepndantly of functionality that may or may not be available in the language being used (e.g. Java probably has it, Perl probably doesn't).
_Time
A pseudo-object allows a behavior to read the time via GetField calls. The fields need more discussion, but there are probably several different time values that could be watched - so these are made available as seperate fields. The OpenInventor SFTIME type is specified, there might be a better class to use since SFTIME is specified in seconds, or alternatively a millisecond field could be added.
_Time {
realTime ; SFTIME - the time asserted by the machine's clock. This
; might not be accurate, especially on low-end machines.
wallClock ; SFTIME - in a simulation this is the time being simulated
; in most circumstances this will be the same as realTime.
elapsedTime ; SFTIME - time since this simulation started,
; or the world was loaded. (This might not be usefull)
}
TimerEvent
The TimerEvent can either be coded into a VRML file, or added by calls over the API.
One approach would be to add this via one of the ENUM's in the eventType field, however this would probably be hard to author correctly.
TimerEvent {
type NONE ; SFENUM ONCE|PERIODIC|CALENDAR
time 0 ; SFTIME either how often, or at what time, or in how long.
actionOn, actionMethod, actionParameters ; as for EventHandler
}
Further Work
Nasties
In the interests of full disclosure - I've spotted the following nasty features of this proposal that may need addressing.
- There is no way to have multiple scripts on the same object, or to specify which program file that an EventHandler should use.
Consider
- Handling key input - e.g. grabbing focus, and directing key events?
References
- Obsoleted VRML Behaviors - an API
Mitra mitra@mitra.biz
Adding behaviors to VRML - an API between scripts and the VRML
-
Obsoleted Sensors, Connectors and Triggers proposal
Mitra mitra@mitra.biz
Adds sensors to detect events like collisions and picking, connectors to tie fields together, and triggers to trigger an event from a field change.
http://www.mitra.biz/vrml/vrml2/vrml-trigger.html
- VRML - API
Mitra mitra@mitra.biz
Defines the API between the browser and external Interpreter
http://www.mitra.biz/vrml/vrml2/vrml-api.html
- Pseudo-Nodes
Mitra mitra@mitra.biz
Adding nodes to represent browser, world, and self characteristics
http://www.mitra.biz/vrml/vrml2/vrml-pseudo.html
- Interface proposal
Mitra mitra@mitra.biz
Adds an interface to VRML1.1 style separators.
http://www.mitra.biz/vrml/vrml2/vrml-interface.html
- Sony's extensions to the VRML 1.0 standard(V 1.2)
Kouichi Matsuda matsuda@csl.sony.jp, Yasuaki Honda, honda@csl.sony.jp
http://www.csl.sony.co.jp/project/VS/evrml1
- Comments on Interface Proposal and sensor/trigger proposal
Kouichi Matsuda, Yasuaki Honda, Rodger Lea, {matsuda, honda, roger}@csl.sony.co.jp
Sony Computer Science Laboratory Inc and Central Research Center
http://www.csl.sony.co.jp/project/VS/proposal/comments.html
- Sony's approach to behavior and scripting aspects of VRML: an Object-Oriented perspective
Kouichi Matsuda, Yasuaki Honda, Rodger Lea, {matsuda, honda, roger}@csl.sony.co.jp
Sony Computer Science Laboratory Inc and Central Research Center
http://www.csl.sony.co.jp/projects/VS/proposal/behascri.html
- Virtual Reality Behavior System (VRBS). A Behavior Language Protocol for VRML.
David Nadeau, John Moreland of SDSC
no date or URL on paper.