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