VRML JavaScript Tutorial
Thursday, April 15, 1999
Rev. Bob's Rectory
[lightly edited]
[Club Owner] revbob [405] : OK, everybody click on
Links [from my home] and click on the only link there
[Club Owner] revbob [405] : Nothing on there's very elaborate
so you can make that window smaller
[World Builder] spazzzz [205] : I need a bigger monitor.
[Club Owner] revbob [405] : So you can still see the chat
window
[Club Owner] revbob [405] : No kidding
[Club Owner] revbob [405] : It's all pretty small, trust
me
[Club Owner] revbob [405] : OK, now go to the first line
("Without a script") and click on the text link
[Club Owner] revbob [405] : OK, a couple of comments on
the file
[Club Owner] revbob [405] : This is a really crummy lightbulb
and a box
[Club Owner] revbob [405] : In the red, you've got a light,
turned off
[Club Owner] revbob [405] : Red print, that is.
I'm talking about the color of the text in the file -- I used that to highlight the important
stuff
[Club Owner] revbob [405] : And a little farther down
you've got a TouchSensor
[Club Owner] revbob [405] : And at the very bottom you
ROUTE the two of them together
[Club Owner] revbob [405] : Now confess -- y'all did this
once, didn't you?
[Club Owner] revbob [405] : And when you did, you'll discover
something bad
perA [613] : yes..
[Club Owner] revbob [405] : Go ahead and click back and
load the world on the same line
[World Builder] spazzzz [205] : I just crashed
[Club Owner] revbob [405] : Oh drat. It worked for me
last nite on my pitiful PC, so there's hope
[Club Owner] revbob [405] : Try it again, it might work
[Club Owner] revbob [405] : So when you click on the light
bulb it lights up,
[Club Owner] revbob [405] : but when you let go of the
mouse, the light goes off
[Club Owner] revbob [405] : And that isn't what you want.
[Club Owner] revbob [405] : And without scripts, there
really isn't any other solution
[Club Owner] revbob [405] : Wb spazz
[World Builder] spazzzz [205] : Yes VRML is Stateless, without
scripts.
[Club Owner] revbob [405] : So now click Back and get to the second line (first script)
[Club Owner] revbob [405] : And read the text
[Club Owner] revbob [405] : And there you see our first
script.
[Club Owner] revbob [405] : Let's back
up now and go to the line that says "Script lies between"
[Club Owner] revbob [405] : I'm going to pause for a cigarette
myself -- everybody lost in the navigation yet?
[Club Owner] revbob [405] : Silence either means assent
or else everybody's asleep
perA [613] : no..works fine
[Club Owner] revbob [405] : So the point I wanted to make
with this chart is that you stuff the script between the sensor
[Club Owner] revbob [405] : (in this case the TouchSensor)
[Club Owner] revbob [405] : and the effector (in this
case the light)
[Club Owner] revbob [405] : OK, go back and then click on "EventOuts"
[Club Owner] revbob [405] : The first thing you should
notice is that you have to declare the eventOut
[Club Owner] revbob [405] : In this case it's light_changed
[Club Owner] revbob [405] : Now look at the bottom and
notice that you route that eventOut to
[Club Owner] revbob [405] : the light's eventIn -- set_on
[Club Owner] revbob [405] : And finally, you have to do
something in the script that gives that eventOut a value
[Club Owner] revbob [405] : In this case, true
[Club Owner] revbob [405] : If you don'
[Club Owner] revbob [405] : Sorry, if you don't write
to an eventOut in your Script then no eventOut is generated
[Club Owner] revbob [405] : So look at the program logic
-- pretty simple.
[Club Owner] revbob [405] : Wait -- ignore that (sorry,
disorganized)
[Club Owner] revbob [405] : Go back and then click eventIns
perA [613] : but value that are incoming is already true
..right ?
[Club Owner] revbob [405] : eventIns come from someplace
(the ROUTE at the bottom)
[Club Owner] revbob [405] : I'll hit that in just a second
perA
[Club Owner] revbob [405] : and you have to declare them,
just like eventOuts
[Club Owner] revbob [405] : (the first red word)
[Club Owner] revbob [405] : And you also have to have
a function with the same name
[Club Owner] revbob [405] : No function with the same
name, nothing happens in your script
[Club Owner] revbob [405] : Spelling errors can get you
on both eventIns and eventOuts
[Club Owner] revbob [405] : OK, now go back and click "Passed Values" and we'll
hit your point perA
[Club Owner] revbob [405] : You get the *name* of the
function from the eventIn's name
[Club Owner] revbob [405] : You get the value that's *passed
to* the function -- in our example "value" but it can be any name
[Club Owner] revbob [405] : from the type -- and from
the *contents* of the eventIn
[Club Owner] revbob [405] : I trust that was perfectly
obscure
[Club Owner] revbob [405] : Here's why the light went
off on the first world when you let go of the mouse button
[Club Owner] revbob [405] : A TouchSensor sends *two*
events: one when you press the mouse --
[Club Owner] revbob [405] : that event has a a value "true"
[Club Owner] revbob [405] : -- and one when you release
the mouse --
[Club Owner] revbob [405] : that event has a value "false"
[Club Owner] revbob [405] : So what this script does is
that it only sends an eventOut when the value it gets from the TouchSensor is a true
perA [613] : ah..I get it
[Club Owner] revbob [405] : This kind of script is sometimes
called a diode
[Club Owner] revbob [405] : It only passes "true"
values
[Club Owner] revbob [405] : So now we're ready to go back, go a couple of lines up, and click on the world for that script
[Club Owner] revbob [405] : This time when you click on
the lightbulb, it goes on and stays on
[Club Owner] revbob [405] : Unfortunately, it doesn't
go off!
[Club Owner] revbob [405] : Not that useful.
[Club Owner] revbob [405] : No sweat, we just clicked
on the world for the first script
[Club Owner] revbob [405] : So now we're ready to look
at the second script, which fixes that
[Club Owner] revbob [405] : Go back and look at the text
[Club Owner] revbob [405] : Now the first thing you notice
is that we had to add a TouchSensor
[Club Owner] revbob [405] : (there's another way to do
this, with only one TouchSensor, but we get to that next)
[Club Owner] revbob [405] : I put it on the base of the
lightbulb, but it could be anywhere -- so long as it doesn't conflict with the first one
[Club Owner] revbob [405] : And going down a little farther,
you'll notice we added a script called turn_off
[Club Owner] revbob [405] : So the glass of the bulb goes
to turn_on, which only passes true
[Club Owner] revbob [405] : and the base goes to turn_off,
which only passes not true
[Club Owner] revbob [405] : OK, give
'er a try. And now I turn off the fire hose and you get to talk
[Club Owner] revbob [405] : Break time -- questions?
[Block Leader] cym [2550] : can anyone send me the log? I
am in 2d...
[Club Owner] revbob [405] : Sure, cym. In fact if you
like I'll bundle it up and stick it on the website after -- if I can figure out how
[Block Leader] cym [2550] : that'd be cool
perA [613] : nope..pretty clear so far
[Club Owner] revbob [405] : When you want to, click on
the world for the second script and see that you can turn
the light on and off
[Club Owner] revbob [405] : Anyhow, fire up the second
script world and in a minute we'll look at the text
for the third script
[Club Owner] revbob [405] : OK, the first line in red
is to indicate that we put our TouchSensor back where it was
[Club Owner] revbob [405] : and got rid of the second
TouchSensor
[Club Owner] revbob [405] : Now scroll down a bit and
you'll see that we've added something new to the Script -- a field
[Club Owner] revbob [405] : A field stores a "persistent"
state -- persistent for the time you're in the world
[Club Owner] revbob [405] : So what we do in the script
after we confirm that we got a mouse button down and not a mouse button up
[Club Owner] revbob [405] : Is that we look at the state.
[Club Owner] revbob [405] : If it's lit already, we turn
off the light, and write to the state variable "lit" for when we come back next time
[Club Owner] revbob [405] : Otherwise, do the opposite
[Club Owner] revbob [405] : Yes, I know you could have
checked the light's on_changed field instead of keeping a state variable
[Club Owner] revbob [405] : but I wanted to use this to
teach state variables
[Club Owner] revbob [405] : OK, go back and fire up the
world and see if it toggles the light on and off
[Club Owner] revbob [405] : And while we're at it, walk
over to the floor lamp behind me and to the right -- it has a script exactly like that -- click on it
[Club Owner] revbob [405] : OK, so our light is finished,
right?
[Club Owner] revbob [405] : Wrong! The block lights up,
but it doesn't look like the lightbulb is doing it
[Club Owner] revbob [405] : So now we show some of the
other things you can generate in a script
[Club Owner] revbob [405] : In this case, a couple of
EmissiveColors
[Club Owner] revbob [405] : Go look at the code for the final script
[Club Owner] revbob [405] : The first thing you'll notice
is that we had to give names to a couple of the Material nodes -- for the bulb glass and the base
[Club Owner] revbob [405] : Now before you look too closely
at the fields and eventOuts
[Club Owner] revbob [405] : in the script, look at the
code in the function
[Club Owner] revbob [405] : There are two ways to generate
an MFvalue
[Club Owner] revbob [405] : One is by using a constructor
-- "new"
[Club Owner] revbob [405] : And the other is by having
a field that you've set up beforehand and you just copy that field by assigning it
[Club Owner] revbob [405] : So I show both ways in the
script. Pick one
[Club Owner] revbob [405] : And now try out the world and see if it looks more realistic
[Block Leader] Goldeneye007 [2173] : hi everyone
[Club Owner] revbob [405] : Hiya Goldeneye -- we're about
done with the tutorial
[Block Leader] Goldeneye007 [2173] : great news, Mr. Crispen,
you are now a world builder!
[Club Owner] revbob [405] : Whoa!
[Block Leader] Goldeneye007 [2173] : I didnt even know about
a tutorial
[Club Owner] revbob [405] : Cool, and thanks.
[Club Owner] revbob [405] : No sweat, I'm going to re-run
it next week
[Club Owner] revbob [405] : watch the calendar
[Club Owner] revbob [405] : The rest of the examples are
just silly things you can read on your own.
[Block Leader] Goldeneye007 [2173] : hey, you teaching VRMLScript?
[Block Leader] Goldeneye007 [2173] : I know VRML, just not
the scripting
[Club Owner] revbob [405] : Yup'er
[Block Leader] Goldeneye007 [2173] : wow, cool!
[Block Leader] Goldeneye007 [2173] : Sign me up1
[Club Owner] revbob [405] : click on Links
[Block Leader] Goldeneye007 [2173] : wait, is it on weekdays?
[Club Owner] revbob [405] : Let me just finish by saying
a word or two about the other examples
[Block Leader] Goldeneye007 [2173] : okie dokie, sorry for
interupting
[Club Owner] revbob [405] : Depends, G. I'm around evenings
and weekends
[Block Leader] Goldeneye007 [2173] : ok, if possible, I'd
like weekends
[Club Owner] revbob [405] : OK, the first
example shows how you can use a special method called initialize()
[Block Leader] Goldeneye007 [2173] : well, I'll brb
[Club Owner] revbob [405] : and it shows something that
nobody bothers to tell you -- one function can call another
[Club Owner] revbob [405] : So I could have just set the
initial conditions and generated the eventOuts
[Club Owner] revbob [405] : but I was lazy and just called
the function [world]
[Club Owner] revbob [405] : The second
example shows one of the simpler Browser methods -- setDescription()
[Club Owner] revbob [405] : Nothing much [world]
[World Builder] spazzzz [205] : Sorry to interupt, what "page"are
we on.
[Club Owner] revbob [405] : However, with a Script and
SetDescription you have a complete emulation of the anchor
[Block Leader] Goldeneye007 [2173] : click on links
[Club Owner] revbob [405] : On the main page
[Club Owner] revbob [405] : I'm just generally introducing
the remaining examples
[Club Owner] revbob [405] : You can hit them later --
my tongue is getting sore, and your ears are no doubt getting sore too
[Club Owner] revbob [405] : The third
extra example, called "Getting silly" shows an old favorite of C programmers
that works in JavaScript too [world]
[Club Owner] revbob [405] : And the last
one is -- provided you don't examine it too closely -- intended to show you that I know
something about scripts
[Club Owner] revbob [405] : ;-)
[Club Owner] revbob [405] : Actually, it shows off a couple
of the math functions
[Club Owner] revbob [405] : And it also shows scripts
as filters which is a very cool idea -- use logic to set up a gate
[Club Owner] revbob [405] : And only when the logic is
true do the values get routed from the interpolator to the object
[Club Owner] revbob [405] : Otherwise, the script eats
them.
[Club Owner] revbob [405] : The thing to remember is that
all the movement comes from TimeSensors and Interpolators
[Neighborhood Leader] PopnFresh [1790] : hey
[Club Owner] revbob [405] : But the Script controls whether
any of it gets through [world]
[Club Owner] revbob [405] : Hey, popn
[Neighborhood Leader] PopnFresh [1790] : sup?
[Club Owner] revbob [405] : You just arrived in time for
the last sentence of my tutorial
[Club Owner] revbob [405] : I'm done!!!!!!
[Club Owner] revbob [405] : Yaaaaayyyyy!
[Block Leader] Goldeneye007 [2173] : I'm back
[Block Leader] Goldeneye007 [2173] : Hi pop
[World Builder] spazzzz [205] : Very Impressive Toot!
[Block Leader] cym [2550] : thanks for the tutorial revbob
[Block Leader] Goldeneye007 [2173] : woo hoo!I'm up to 50
K in CCs now!
perA [613] : thanks revbob ! looking forward to the next
tutorial :-)
[Block Leader] Goldeneye007 [2173] : thanks for the tutorial...oops,
I wasnt here, hee hee
[Club Owner] revbob [405] : I realize the tutorial went
at 200 MPH, so please feel free to corner me and ask
[World Builder] spazzzz [205] : ;-)
[Block Leader] Goldeneye007 [2173] : I have a question
[Club Owner] revbob [405] : And I'll have it again next
week -- the phone company willing
[Block Leader] Goldeneye007 [2173] : I know a little bit
about Script(TINY TINY bit)
[Block Leader] Goldeneye007 [2173] : so, I have a question
[Club Owner] revbob [405] : Well, that's all this toot
teaches -- a tiny bit
[Club Owner] revbob [405] : Shoot
[Block Leader] Goldeneye007 [2173] : how do you make it so
when something is clicked on, the script performs some funtion?
[Block Leader] Goldeneye007 [2173] : er, function
[Club Owner] revbob [405] : Aha!
[Club Owner] revbob [405] : I actually know that one.
[Block Leader] Goldeneye007 [2173] : lol
[Club Owner] revbob [405] : You route an eventOut from
something (e.g., a sensor)
[Block Leader] Goldeneye007 [2173] : I need to know this
for createVrmlFromString
[Club Owner] revbob [405] : to an eventIn you declare
in your Script
[Block Leader] Goldeneye007 [2173] : ok, but in the javascript
itself, what do you declare?
[Club Owner] revbob [405] : And then you have a function
of the same name that reads the value and does the action
[Club Owner] revbob [405] : Click links and head to the
page. I'll show you.
[Club Owner] revbob [405] : we should have done it this
way before
[Block Leader] Goldeneye007 [2173] : I cant see any VRML
files right now though
[Club Owner] revbob [405] : No sweat, you can see the
text
[Block Leader] Goldeneye007 [2173] : ok,cool
[Club Owner] revbob [405] : Seriously, Goldeneye, I've
got it all laid out there
[Club Owner] revbob [405] : Let me know when you're there
[Block Leader] Goldeneye007 [2173] : I'm there
[Club Owner] revbob [405] : OK, see where it says "breaking
down the script"
[Block Leader] Goldeneye007 [2173] : uh huh
[Club Owner] revbob [405] : Er, "breaking the script
down" Sorry
[Club Owner] revbob [405] : OK, click on the first link
in that list
[Block Leader] cym [2550] : you do Golden?
[Block Leader] Goldeneye007 [2173] : I'm there
[Club Owner] revbob [405] : "Script lies between..."
[Block Leader] Goldeneye007 [2173] : oh yeah
[Block Leader] Goldeneye007 [2173] : I'm there
[Club Owner] revbob [405] : OK, the red text shows the
script between the sensor and the light
[Block Leader] Goldeneye007 [2173] : right
[Club Owner] revbob [405] : Now back up and go to the
next one
[Block Leader] Goldeneye007 [2173] : alright
[Block Leader] Goldeneye007 [2173] : there
[Club Owner] revbob [405] : It shows that you declare
an eventOut in your script
[Club Owner] revbob [405] : You route the eventOut in
your route statement
[Block Leader] Goldeneye007 [2173] : I know that much dude
[Club Owner] revbob [405] : And in the function, you have
to set that value
[Block Leader] Goldeneye007 [2173] : that's not what I wanna
know
[Club Owner] revbob [405] : OK, now the third one
[Block Leader] Goldeneye007 [2173] : there
[Club Owner] revbob [405] : Ask again
[Block Leader] Goldeneye007 [2173] : ok
[Block Leader] Goldeneye007 [2173] : In the function(turn_on
in this one),
perA [613] : question..whats the diffrences between javascript
and vrmlscript ?
[Club Owner] revbob [405] : Ahhhhhhhh -- a "javascript"
URL is "supported" in the spec
[Block Leader] Goldeneye007 [2173] : do I just use value
for the statement "When this gets touched"
[Block Leader] Goldeneye007 [2173] : I know
[Club Owner] revbob [405] : A "vrmlscript" URL
isn't mentioned
[Club Owner] revbob [405] : Yes! In fact, that's the fourth
thing on the list
[Block Leader] Goldeneye007 [2173] : oh, I see now
[Block Leader] Goldeneye007 [2173] : yeah, I just saw that
[Club Owner] revbob [405] : You can name it "value"
or "gazorninplatz" or whatever
[Block Leader] Goldeneye007 [2173] : so, lemme ask something
else
[Club Owner] revbob [405] : Sure
[Block Leader] Goldeneye007 [2173] : if I put "function
touched {
[Block Leader] Goldeneye007 [2173] : (theres more to it
[Block Leader] Goldeneye007 [2173] : if (value) {
[Block Leader] Goldeneye007 [2173] : hmm...
[Block Leader] Goldeneye007 [2173] : how would I make it
do a createVrmlFromString?
[Club Owner] revbob [405] : The javascript interpreter
will create a new variable called value, since you didn't mention it in parens after "touched"
[Block Leader] Goldeneye007 [2173] : ok
[Club Owner] revbob [405] : Its value will (istr) be zero
-- or maybe random
[Block Leader] Goldeneye007 [2173] : what do I do to make
it use a createVrmlFromString ?
[Club Owner] revbob [405] : Ahhhhh.
[Block Leader] Goldeneye007 [2173] : This whole thing is
helping me understand Scripting a whole lot better
[Club Owner] revbob [405] : You call (in your function)
Browser.createVrmlFromString('some vrml text')
[Block Leader] Goldeneye007 [2173] : so, lemme review
[Block Leader] Goldeneye007 [2173] : after I declare the
function and value variable
[Club Owner] revbob [405] : and you route the output to
a grouping node's add_children event
[Club Owner] revbob [405] : right
[Block Leader] Goldeneye007 [2173] : I type "Browser.createVrmlFromString('VRML
Stuff')" ?
[Block Leader] Goldeneye007 [2173] : right?
[Club Owner] revbob [405] : In the function. Right.
[Block Leader] Goldeneye007 [2173] : but then, what do I
do to create the eventOut?
[Club Owner] revbob [405] : And that function returns
an MFNode
[Block Leader] Goldeneye007 [2173] : The Function itself
is an eventIKn
[Block Leader] Goldeneye007 [2173] : er, In
[Club Owner] revbob [405] : so you say theEventOut = Browser.createVrmlFromString('yadda
yadda')
[Block Leader] Goldeneye007 [2173] : wow, cool
[Block Leader] Goldeneye007 [2173] : Thanks so much dude!!!
perA [613] : so converting vrmlscript to javascript would
be the right thing to do..tried some software(TouchMore!) and it generated vrmlscript in scriptnode,
[Block Leader] Goldeneye007 [2173] : Woo hoo!
[Block Leader] Goldeneye007 [2173] : I owe ya one
[Club Owner] revbob [405] : theEventOut has to be of type
MFNode
perA [613] : is that very hard ? guess not..
[Block Leader] Goldeneye007 [2173] : we really need more
Scripters
[Block Leader] Goldeneye007 [2173] : I know
[Club Owner] revbob [405] : And you simply ROUTE it
[Block Leader] Goldeneye007 [2173] : I understand all other
parts of VRML
[Club Owner] revbob [405] : Btw, guys, I got wrapped around
the axle for the longest time on using directOutput
[Club Owner] revbob [405] : DON'T USE directOutput!!!!
[Club Owner] revbob [405] : Use ROUTEs and eventOuts and
eventIns
[Block Leader] Goldeneye007 [2173] : I just wont declare
it :)
[World Builder] spazzzz [205] : Why???? I use it.
[Club Owner] revbob [405] : You'll save yourself a world
of heartache
[Block Leader] Goldeneye007 [2173] : I never even think about
directOutput
[Club Owner] revbob [405] : Why? First of all, because
VRML browsers have been tested really thoroughly on the eventOut
[Club Owner] revbob [405] : And aren't tested much at
all on directOutput
[Block Leader] Goldeneye007 [2173] : Bob,the pic at your
home is all blurry
[Club Owner] revbob [405] : So you may find yourself spending
hours illuminating a browser bug
[Club Owner] revbob [405] : Yup -- that's me after too
much coffee
[Block Leader] Goldeneye007 [2173] : lol
[Club Owner] revbob [405] : Yeah -- eventOuts and ROUTEs
are pedantic, but they work more often
[Block Leader] Goldeneye007 [2173] : this is only a Script
tutorial, right?
[Club Owner] revbob [405] : Sure -- but since I was late,
I have to pay the price
[Club Owner] revbob [405] : Ask (or more satisyingly to
me, tell) anything
[Block Leader] Goldeneye007 [2173] : revbob, how much of
the Grand Piano did you make by hand?
perA [613] : why does spazz generate bboxcenter etc values,is
that nessecary ?
[Block Leader] Goldeneye007 [2173] : it's not nessacary,
but it makes the world load faster
[Club Owner] revbob [405] : I did the TextureCoordinates.
That's it.
[Block Leader] Goldeneye007 [2173] : oh, that's not bad
[World Builder] spazzzz [205] : I think It makes the browser
render faster too.
[Block Leader] Goldeneye007 [2173] : can you do Faces by
hand at all?
[Block Leader] Goldeneye007 [2173] : that's what I meant,
spazz
[Club Owner] revbob [405] : Alas, yes -- though Spazz
is keeping me away from that dreadful pursuit
[Block Leader] Goldeneye007 [2173] : lol
[Block Leader] Goldeneye007 [2173] : I can do small dinky
stuff
[Club Owner] revbob [405] : What a pain!
[Block Leader] Goldeneye007 [2173] : like a sword or something
[Club Owner] revbob [405] : Me too. I mean, the human
mind is onlyso big
[Block Leader] Goldeneye007 [2173] : Extrusions are the way
around Faces
[Club Owner] revbob [405] : A sword is bigger than I'd
try
[Block Leader] Goldeneye007 [2173] : Clean does all his complicated
faces by hand
[World Builder] spazzzz [205] : Ouch
[Block Leader] Goldeneye007 [2173] : he's awesome