4c4 < --- > 17c17 <
This document can be found at http://reality.sgi.com/employees/gavin/vrml/Newbehaviors.html. It was last updated on November 24, 1995.
--- >This document can be found at http://reality.sgi.com/employees/gavin/vrml/Behaviors.Dec1.html. It was last updated on Dec. 1, 1995.
101c101 < received. For example, the Transform node may receive "translation" events --- > received. For example, the Transform node may receive "setTranslation" events 103,105c103,107 < "rotation", "scaleFactor", ... events). <In my opinion, some fields should not be allowed to change after file-read; < for many browsers, allowing things like the fields of IndexedFaceSet or ShapeHints to change over time will just be too hard to implement.
--- > "setRotation", "setScaleFactor", ...etc events). >In Gavin's opinion, some fields should not be allowed to change after file-read; for > many browsers, allowing things like the fields of IndexedFaceSet or ShapeHints > to change over time will be hard to implement (perhaps IndexedFaceSets are tesselated into triangles at file-read time, > or normals calculated based on the creaseAngle of ShapeHints, or...).
117a120,121 >Routes are not nodes; ROUTE is merely a syntactic construct for establishing > event paths between nodes.
120c124,130 < read-in is covered below in the section discussing how scripts should be allowed to edit the scene. --- > read-in is covered below in the section discussing how scripts should be allowed to edit the scene. >Issue: Should you be allowed to ROUTE inputs to inputs as a way of 'slaving'
> inputs, so I'm connected to whatever is connected to something else? Gavin
> thought that was a good idea but changed his mind, because there are some
> nasty cases, like:
> ROUTE foo.in -> bar.in
> ROUTE bar.in -> foo.in # Uh-oh, what does this do...
We're making distinctions between fields, which can be given an initial value but cannot be changed except by the node that < they're contained in, and events, which (at least for the built-in nodes) < are requests to change fields. So, if we want our TwoColorChair to have < colors that can be changed, we'd need to expose the leg.diffuseColor 'eventIn' < and seat.diffuseColor 'eventIn' events. All of which may make for confusing < and wordy prototype declarations. Are there ever cases where you might want < to ONLY allow initial values to be set, and NOT allow them to be changed < later?
--- >We're making distinctions between fields, which can be given an initial > value but cannot be changed except by the node that they're contained in, > and events, which (at least for the built-in nodes) are requests to change > fields. So, if we want our TwoColorChair to have colors that can be changed, > we'd need to expose the leg.setDiffuseColor 'eventIn' and seat.diffuseColor 'eventIn' events. All of which > may make for confusing and wordy prototype declarations. Are there ever > cases where you might want to ONLY allow initial values to be set, and NOT > allow them to be changed later?
211c221 < We need some way of taking an SFNode eventIn and inserting it into the scene. --- > We need some way of taking an SFNode field and inserting it into the scene. 216c226,227 < # May also receive SFNode nodeToUse events to set nodeToUse --- > # eventIn SFNode setNodeToUse > # -- may also receive SFNode setNodeToUse events to set nodeToUse 333a345,347 >If it is necessary, the language field could contain something like "REMOTE:fortran" to specify both that a URL is being used, and the language contained in > that URL (for transport methods like ftp that do not provide the MIME type > of their content).
466,469c480,502 <What other API needs to be supported? I've glossed over the details of GET/SET/SEND; < certainly at least those are necessary. It might be useful to be able to < ask "ISROUTED("eventName") to see if anybody is listening to your "eventName" < events-- if not, the script might be able to save doing some work.
--- >By "API", I mean the actual code that the VRML world creator will type into > her Logic nodes (and not a lower-level API used to communicate between a > VRML implementation and a scripting language, although the lower level API > will likely be very similar to what is described here).
>At least the following will be necessary:
>What other API needs to be supported? It might be useful to be able to ask "ISROUTED("eventName") to see if anybody > is listening to your "eventName" output events-- if not, the script might > be able to save doing some work. Sensors might get simpler if events are time-stamped..
516c549 <-- Events generated from user-eventIn are always ordered, with earlier events --- >
-- Events generated from user-input are always ordered, with earlier events 518,521c551,554 < to user-eventIn events; something like events that are generated are time-stamped < with the same time as the last event from the event list... or something... < One of our goals is to be able to detect "bad fan-in"-- getting two events < with the same name that sort to exactly the same place in the message queue. --- > to user-input events; something like events that are generated are time-stamped with > the same time as the last event from the event list... or something... One > of our goals is to be able to detect "bad fan-in"-- getting two events with > the same name that sort to exactly the same place in the message queue. 537c570,575 < be queued up by the system if doing so does not change the user experience.
--- > be queued up by the system if doing so does not change the user experience > (for example, if the user is waiting for the definition of an EXTERNPROTO > to come across the network, a browser might allow the user to push buttons > that affect the EXTERNPROTO'ed object, queuing up the input events to the > EXTERNPROTO until its implementation was loaded and processing them when > it arrived). 539c577 <To support sources of eventIn from outside the virtual world (Logic nodes --- >
To support sources of input from outside the virtual world (Logic nodes 574c612 < wait for eventIn from somewhere in the real world OR (perhaps) --- > wait for input from somewhere in the real world OR (perhaps) 579c617 < set state of fields, send messages, based on VRML and real-world eventIns --- > set state of fields, send messages, based on VRML and real-world inputs 620c658,659 < -- Clone a node the script already has a pointer to (later)
--- > -- Copy a node the script already has a pointer to (later- issues of deep > vs shallow copy) 639,640c678,679 < PROTO Torus [ field SFFloat radius1 IS GenerateTorus.radius1, < field SFFloat radius2 IS GenerateTorus.radius2 ] --- > PROTO Torus [ field SFFloat radius1 IS GENTORUS.radius1, > field SFFloat radius2 IS GENTORUS.radius2 ] 652c691 < ROUTE GENTORUS.geometry -> NODEREF.nodeToUse --- > ROUTE GENTORUS.geometry -> NODEREF.setNodeToUse 659,661c698,700 < to maintain a pointer to a node it is eventOutting as part of either its < public or internal state. This allows a Logic node to make arbitrary changes < to one or more parts of the scene graph. --- > to maintain a pointer to a node it is generating as part of either its public > or internal state. This allows a Logic node to make arbitrary changes to > one or more parts of the scene graph. 675,676c714,716 < NodeReference { < nodeToUse = Logic { .... } . geometry --- > DEF __N NodeReference { } > DEF __L Logic { ... eventOut SFNode gometry ... } > ROUTE __L.geometry -> __N.setNodeToUse 702a743,787 >TimeSensors generate events as time passes. TimeSensors remains inactive > until their startTime is reached. At the first simulation tick where real time >= startTime, > the TimeSensor will begin generating time and alpha events, which may be routed to other nodes to drive continuous animation > or simulated behaviors. The length of time a TimeSensor generates events > is controlled using cycleInterval and cycleCount; a TimeSensor stops generating time events at time startTime+cycleInterval*cycleCount. cycleMethod controls the mapping of time to alpha values (which are typically used > to drive Interpolators). It may be set to FORWARD, causing alpha to rise > from 0.0 to 1.0 over each interval, BACK which is equal to 1-FORWARD, or > it may be set to SWING, causing alpha to alternate 0.0 to 1.0, 1.0 to 0.0, > on each successive interval.
>The minTick field specifies how often the TimeSensor will generate output events; output > events are guaranteed to be generated no less than one minTick interval apart. For example, setting minTick to 1.0 will guarantee that t TimeSensor will generate output events at > most once per second. By default, minTick is zero and a TimeSensor will generate time events as often as possible > (typically, as quickly as the world can be redrawn).
>pauseTime may be set to interrupt the progress of a TimeSensor. If pauseTime is greater than startTime, time and alpha events will not be generated after the pause time. pauseTime is ignored if it is less than or equal to startTime.
>If cycleCount is <= 0, the TimeSensor will continue to tick continuously, without a cycle > interval; in this case, cycleInterval and cycleMethod are ignored, and alpha events are not generated. This use of the TimeSensor > should be used with caution, since it incurs continuous overhead on the > simulation.
>Setting cycleCount to 1 and cycleInterval to 0 will result in a single event being generated at startTime; this can be used to build alarms and timers that go off periodically.
>No guarantees are made with respect to how often a TimeSensor will generate > time events, but at least one event must be generated if it is later than startTime and startTime was set to a time in the future.
>> FILE FORMAT/DEFAULTS > TimeSensor { > startTime 0 # SFTime (double-precision seconds) > pauseTime 0 # SFTime > minTick 0 # SFTime > cycleInterval 1 # SFTime > cycleCount 1 # SFLong > cycleMethod FORWARD # SFEnum FORWARD | BACK | SWING > # eventIn SFTime setStartTime > # eventIn SFTime setPauseTime > # eventIn SFTime setCycleInterval > # eventIn SFLong setCycleCount > # eventIn SFEnum setCycleMethod # FORWARD | BACK | SWING > # eventOut SFTime time > # eventOut SFFloat alpha > } >>
Oops, need to add a description of the SFTime field. We could use SFFloat's > for time, except that if we expect to be dealing with absolute times( from > Jan 1 1970 0:00 GMT perhaps) then 32-bit floats don't give enough precision. > Inventor writes SFTime fields as 64-bit double-precision values, but stores > time values internally as two 32-bit integers
733c818 < # eventIn SFBool enable --- > # eventIn SFBool setEnabled 748c833 < # eventIn SFBool enable --- > # eventIn SFBool setEnabled 758c843,847 < by being sent enable events. There are two types of PointingDeviceSensors; ClickSensor and DragSensors. --- > by being sent enable events. There are two types of PointingDeviceSensors; ClickSensor and DragSensors. >Pointing device sensors may be nested, with the rule being that the sensors > lowest in the scene hierarchy will have first change to 'grab' user input; > if user input is 'grabbed', sensors higher in the hierarchy will not have > a chance to process it.
797c886 < # eventIn SFBool enable --- > # eventIn SFBool setEnabled 830c919 < # eventIn SFBool enable --- > # eventIn SFBool setEnabled 855c944 < # eventIn SFBool enable --- > # eventIn SFBool setEnabled 881c970 < # eventIn SFBool enable --- > # eventIn SFBool setEnabled 906c995 < # eventIn SFBool enable --- > # eventIn SFBool setEnabled 934c1023 < # eventIn SFBool enable --- > # eventIn SFBool setEnabled 955,972c1044,1052 <TimeSensors generate events as time passes. TimeSensors remains inactive < until their startTime is reached. At the first simulation tick where real time >= startTime, < the TimeSensor will begin generating time and alpha events, which may be routed to the eventIn of other nodes to drive continuous < animation or simulated behaviors. The length of time a TimeSensor generates < events is controlled using cycleInterval and cycleCount; a TimeSensor stops generating time events at time startTime+cycleInterval*cycleCount. cycleMethod controls the mapping of time to alpha values (which are typically used < to drive Interpolators). It may be set to FORWARD, causing alpha to rise < from 0.0 to 1.0 over each interval, BACK which is equal to 1-FORWARD, or < it may be set to SWING, causing alpha to alternate 0.0 to 1.0, 1.0 to 0.0, < on each successive interval.
<pauseTime may be set to interrupt the progress of a TimeSensor. If pauseTime is greater than startTime, time and alpha events will not be generated after the pause time. pauseTime is ignored if it is less than or equal to startTime.
<If cycleCount is <= 0, the TimeSensor will continue to tick continuously, without a cycle < interval; in this case, cycleInterval and cycleMethod are ignored, and alpha events are not generated. This use of the TimeSensor < should be used with caution, since it incurs continuous overhead on the < simulation.
<Setting cycleCount to 1 and cycleInterval to 0 will result in a single event being generated at startTime; this can be used to build alarms and timers that go off periodically.
<No guarantees are made with respect to how often a TimeSensor will generate < time events, but at least one event must be generated if it is later than startTime and startTime was set to a time in the future.
--- >A visibility sensor generates visible/notVisible events, and can be used to make a script take up less CPU time when the things the script > is controlling are not visible (for example, don't bother doing an elaborate > walk-cycle animation if the character is not visible; instead, just modify > its overall position/orientation).
>There are some issues here about when visibility should be determined; I predict it will be a bit tricky to implement a browser > that doesn't suffer from "off-by-one" visibility errors, but we might just > leave that as a quality-of-implementation issue and not spec exact behavior > (I'm sure we won't require exact visibility computation, anyway...).
975,988c1055,1059 < TimeSensor { < startTime 0 # SFTime (seconds) < pauseTime 0 # SFTime < cycleInterval 1 # SFTime < cycleCount 1 # SFLong < cycleMethod FORWARD # SFEnum FORWARD | BACK | SWING < # eventIn SFTime startTime < # eventIn SFTime pauseTime < # eventIn SFTime cycleInterval < # eventIn SFLong cycleCount < # eventIn SFEnum cycleMethod # FORWARD | BACK | SWING < # eventOut SFTime time < # eventOut SFFloat alpha < } --- > VisibilitySensor { > enabled TRUE # SFBool > # eventIn SFBool setEnabled > # eventOut SFBool visible > } 990,993d1060 <Oops, need to add a description of the SFTime field. We could use SFFloat's < for time, except that if we expect to be dealing with absolute times( from Jan 1 1970 0:00 GMT perhaps) then 32-bit floats don't give enough precision. < Inventor writes SFTime fields as 64-bit double-precision values, but stores time values internally as < two 32-bit integers
1012c1079 < # eventIn SFFloat alpha --- > # eventIn SFFloat setAlpha 1024c1091 < # eventIn SFFloat alpha --- > # eventIn SFFloat setAlpha 1041c1108 < # eventIn SFFloat alpha --- > # eventIn SFFloat setAlpha 1053c1120 < # eventIn SFFloat alpha --- > # eventIn SFFloat setAlpha 1068c1135 < # eventIn SFFloat alpha --- > # eventIn SFFloat setAlpha 1082c1149 < # eventIn SFFloat alpha --- > # eventIn SFFloat setAlpha 1111c1178 < ROUTE LOGIC.color -> MATERIAL.diffuseColor --- > ROUTE LOGIC.color -> MATERIAL.setDiffuseColor 1126d1192 < isBeingClicked = USE CLICKSENSOR.isActive 1129a1196 > ROUTE CLICKSENSOR.isActive -> LOGIC.isBeingClicked 1152,1153c1219,1220 < ROUTE START.release -> TIME.start < ROUTE TIME.alpha -> INTERP.alpha --- > ROUTE START.release -> TIME.setStart > ROUTE TIME.alpha -> INTERP.setAlpha 1161c1228 < ROUTE INTERP.outValue -> TRANSFORM.translation --- > ROUTE INTERP.outValue -> TRANSFORM.setTranslation 1173d1239 < alpha = USE TIMESENSOR.alpha 1176,1177c1242,1243 < ROUTE TIME.alpha -> ROTATE_INTERP.alpha < ROUTE ROTATE_INTERP.outValue -> TRANSFORM.rotation --- > ROUTE TIME.alpha -> ROTATE_INTERP.setAlpha > ROUTE ROTATE_INTERP.outValue -> TRANSFORM.setRotation 1214c1280 < ROUTE TB.state -> LIGHT.on --- > ROUTE TB.state -> LIGHT.setOn 1225c1291 < [ eventIn MFColor ambientColor IS CONVERT.ambientIn, --- > [ eventIn MFColor setAmbientColor IS CONVERT.ambientIn, 1227c1293 < eventIn MFColor diffuseColor IS CONVERT.diffuseIn, --- > eventIn MFColor setDiffuseColor IS CONVERT.diffuseIn, 1229c1295 < eventIn MFColor specularColor IS CONVERT.specularIn, --- > eventIn MFColor setSpecularColor IS CONVERT.specularIn, 1231c1297 < eventIn MFColor emissiveColor IS CONVERT.emissiveIn, --- > eventIn MFColor setEmissiveColor IS CONVERT.emissiveIn, 1233c1299 < eventIn MFFloat shininess IS M.shininess, --- > eventIn MFFloat setShininess IS M.setShininess, 1235,1236c1301,1302 < eventIn MFFloat transparency IS M.transparency ] < field MFColor transparency IS M.transparency, --- > eventIn MFFloat setTransparency IS M.setTransparency, > field MFColor transparency IS M.transparency ] 1250,1251c1316,1317 < ROUTE CONVERT.ambientOut -> M.ambientColor < ROUTE CONVERT.diffuseOut -> M.diffuseColor --- > ROUTE CONVERT.ambientOut -> M.setAmbientColor > ROUTE CONVERT.diffuseOut -> M.setDiffuseColor 1279c1345 < eventIn SFVec3f currentPosition --- > eventIn SFVec3f setCurrentPosition 1282c1348 < ROUTE PositionReporter.position -> SEND_TO_SERVER.currentPosition --- > ROUTE PositionReporter.position -> SEND_TO_SERVER.setCurrentPosition 1308c1374 < ROUTE L.geometry -> NODEREF.nodeToUse --- > ROUTE L.geometry -> NODEREF.setNodeToUse