Lightballs
tested with
+
+
This tutorial deals about a PROTO with
a Script node which switches some of its properties. A PlaneSensor
will enable us to move the lightballs around. We will trigger a spotlight
once the balls are at certain positions.
The PROTO starts with a declaration of all its events and fields:
PROTO LightBall
[
exposedField SFColor LBColor 0.6 0.6 0
exposedField SFVec3f LBPosition 1 0 0
exposedField SFVec3f LBSize 0.5 0.5 0.5
field SFVec3f activePosition 1 0 0
]
We will have no eventIns or eventOuts since the PROTO
LightBall contains already all of its functionality. We would like to vary
the LightBall's size, color, position, and activePosition. The last item
determines where in the X-Y plane the LightBall will be active.
Next we build the geometry:
Transform {
translation IS LBPosition
children [
The translation is ISed and moves the LightBall instance to its
end position. The children of this node are listed:
DEF PS PlaneSensor { }
DEF ball Transform {
scale IS LBSize
children [
Shape {
appearance Appearance {
material Material {
diffuseColor IS LBColor
}
}
geometry Sphere { }
}
First we define a PlaneSensor PS. This sensor maps mouse movement into
translation in the X-Y plane. After you clicked on a PlaneSensor the
x-y coordinates of your mouse pointer can be used to move objects, typically
contained in the PlaneSensor's parent node. A ball is build with its
properties scale and diffuseColor ISed. Each instance
of this PROTO will have its own SpotLight:
DEF LBLight SpotLight {
color IS LBColor
location 0 0 1
on FALSE
}
]
}
]
}
It's color is also ISed. Initially the SpotLight is turned off.
To implement the PlaneSensor we need only one ROUTE:
ROUTE PS.translation_changed TO ball.set_translation
When the PlaneSensor is active it will send out an event
translation_changed which can be ROUTEd to the ball's
translation field.
Now that we have the geometry set up we can turn to the Script node:
DEF LBscript Script {
eventIn SFVec3f LBpositionCheck
eventOut SFBool LB_on
field SFVec3f activePosition IS activePosition
The eventIn 'ballPosition' represents the current position of the
LightBall and is compared with 'activePosition'. Once the LightBall
is in the target range an eventOut 'LB_on' is triggered which in turn
is used to turn on/off the SpotLight.
url "javascript:
function LBpositionCheck(pos) {
posX = pos[0];
activeX = activePosition[0];
if(posX > activeX) LB_on = TRUE;
if(posX < activeX) LB_on = FALSE;
}
"
}
ROUTE PS.translation_changed TO LBscript.LBpositionCheck
ROUTE LBscript.LB_on TO LBLight.on
The PlaneSensor's translation field is continuously ROUTEd and
passed as 'pos' to the function 'LBpositionCheck'. The function then compares
the x-value of the current position to the x-value of the 'activePosition'
field. In case we dragged the LightBall into the active region the Script
will trigger a TRUE for the SpotLight's enabled field and turn
the light on. The complete
LightBall Proto sums up our work
so far.
As a test for today's PROTO I thought that I can use the LightBalls
to demonstrate another issue in VRML: the lighting model, in particular the
fact that usually the light shed on an object is calculated at the vertices.
A plane build with one Box node has four vertices (corners) and
thus will have only very limited light/shading capabilities.
The scene starts with three basic nodes:
NavigationInfo {
headlight FALSE
}
DirectionalLight {
direction 0 -1 -1
intensity 0.5
}
Viewpoint {
position 0 0 10
description "first"
}
NavigationInfo tells the browser not to use the headlight since we
provide our own lights: DirectionalLight. The intensity is set
to a value of 0.5 which is about half way to full intensity. A
DirectionalLight node gives you parallel light rays along the
direction vector which we define to be in a 45 degree angle downwards in
the Y-Z plane.
Our LightBalls will illuminate two planes: one build from one single
Box node and the other one from four Box nodes:
DEF plate Transform {
translation 4 2 -2
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 0.3 0.4 0.5
}
}
geometry Box { size 8 4 0.1 }
}
]
}
Transform {
translation 0 -3 -2
scale 0.55 0.5 0.5
children USE plate
}
Transform {
translation 4.25 -3 -2
scale 0.55 0.5 0.5
children USE plate
}
Transform {
translation 0 -5 -2
scale 0.55 0.5 0.5
children USE plate
}
Transform {
translation 4.25 -5 -2
scale 0.55 0.5 0.5
children USE plate
}
You can see that I define the first Box as plate and then use it
four more times to build the second plane. By scaling and translating the
plates I end up with a tiled second plane. Look at the
LightBall source or the VRML
scence LightBall.wrl.
Finally we use our PROTO LightBall and make two instances of it:
DEF LB1 LightBall {
LBColor 1 0 0
LBPosition -2 0 0
LBSize 0.45 0.45 0.45
activePosition 5 0 0
}
DEF LB2 LightBall {
LBColor 0 1 0
LBPosition -2 2 0
LBSize 0.3 0.3 0.3
activePosition 1 0 0
}
This demo/tutorial was tested in Cosmo Player 1.0beta3 and after you loaded
the final scene LightBall.wrl
you can drag the lightballs around and test the lights on the planes. You
will notice that the upper plane will show light exposure only when you
drag the balls to the corners.
The red ball works only in the very right half of your screen. Both balls
will turn themselves off when you drag them to the left. As always here
is the entire
LightBall source

Copyright © 1996-98
Markus Roskothen. All rights reserved.