Quote:
> David,
> Thanks for the extensive example, but i'm still confused about how to
> ROUTE the events to the script in a PROTO node. Let's say i replace the
> request_info function with a simple function: say_hello (arg1, arg2) {
> print('my name: ' + name); }. Then I declare a new MyBox, grouped with a
> TouchSensor, e.g. Group { children [ DEF ABOX MyBox {}; DEF ASENSOR
> TouchSensor {} ] }.
> Then how should i ROUTE events? something like ROUTE ASENSOR.touchTime
> TO ABOX.sc.say_hello ?
> Forgive my ignorance, and again TIA,
> Rob
it is only ignorance if you do not ask when u do not know.
firstly your simple Group node would not display anything...
a critical part of how a PROTO works is defined in the
vrml 97
specification:
" An instantiation is created by filling in the parameters of the prototype
declaration and inserting copies of the first node (and its scene graph)
wherever the prototype instantiation occurs. For example, if the first node
in the prototype definition is a Material node, instantiations of the
prototype can be used wherever a Material node can be used." (from section
4.8.3)
to you, this means that whenever you create a MyBox instance in code (as you
did with your example), it is like inserting the first node of the PROTO
definition into the code (in this case it is just a simple Box {} node). now
depending on how much VRML you have already done u may realise that a Box {}
node itself, does not render, it must be included as the geometry field of a
Shape {} node, so your code should look something like this:
Group {
children [
Shape {
appearance Appearance {
material Material {
}
}
geometry DEF abox MyBox {
}
},
DEF ts TouchSensor {
}
]
Quote:
}
just one thing i noticed in your code (apart from a significant lack of
indenting ;) was the use of a semicolon ';' between nodes in the child
field. i don't think this is correct vrml, most browsers will read code
without any seperator between nodes in an MFNode field, but the standard is
to use a comma ',' i think..
your next note about changing the function is not so easy. functions defined
inside the url field of a Script node are useless unless they are called
'initialize' or have the same name as an eventIn to that function (whenever
the Script node receives an event, it calls the function of that name). so
if u replaced the function with one called say_hello, then you would need to
add the line:
eventIn SFTime say_hello IS say_hello
to the Script definition, and you would need to add the line:
eventIn SFTime say_hello
to the PROTO interface definition. (you would also probably remove the
'eventIn SFTime request_info' and 'eventIn SFTime request_info IS
request_info).
the easy way would be to keep the same function name, and just change the
code inside it, then u wouldn't have to change all the eventIn definitions.
also if u changed the content of the request_info function to a simple print
statement, then the eventOuts (sizeID_out, name_out) and the ID field are
not used so you could remove there references in the PROTO and Script
interfaces.
so theres the setup, now the ROUTE. you have to think of a PROTO like a
black box, just like any other node. the only interaction you have with this
box is via the fields and events defined in the PROTO interface (the stuff
in between the square brackets after the 'PROTO <name>' section). so your
ROUTE would be as simple as:
ROUTE ts.touchTime TO abox.request_info
or
ROUTE ts.touchTime TO abox.say_hello
(depending on if u changed the function..)
so heres the total code:
#VRML V2.0 utf8
PROTO MyBox [
field SFVec3f size 2 2 2
field SFString name "default"
eventIn SFTime say_hello
]
{
Box {
size IS size
}
DEF sc Script {
field SFVec3f size IS size
field SFString name IS name
eventIn SFTime say_hello IS say_hello
url "javascript:
function request_info(sftime,tm){
print('my name: '+name);
}
"
}
Quote:
}
Group {
children [
Shape {
appearance Appearance {
material Material {
}
}
geometry DEF abox MyBox {
}
},
DEF ts TouchSensor {
}
]
Quote:
}
ROUTE ts.touchTime TO abox.say_hello