Cybertown Mall Cybertown Revival

Tutorial 9 of 10

ADVANCED CODING

CREATOR NOTEby Morning.star, published with permission

COLLISION

Transparency is one of those attributes that can be used for purposes not so obviously - like creating an invisible barrier to prevent users from accessing an area they shouldn't. I use this sometimes to create otherwise unattractive barriers on windows I want to prevent someone from unexpectedly falling through - something useful in modular home pieces.

Likewise, collision coding can useful in creating alternative solutions. Take the following option for creating a door. The nice things about non-animated doors is that you never have to wait for them to open, you never miss being able to get through them because they opened & closed too fast, & you never have to find yourself slamming into them. And BONUS, there's less coding for them so you save on filesize as well. Making doors that look like doors but permit an av to walk through involves just 2 simple lines of Collision coding & 2 sets of closing brackets at the end.

Group { children [
Collision { collide FALSE children [

Simply put that at the very top of the piece you want to have be non-collidable & add 2 sets of matching brackets like these ]} at the bottom of the piece & you have yourself a door that will never slam in your face. If you are DEFing identical doors into different positions in your building, just make sure that the finishing brackets are placed after all the DEFd pieces so that the attribute applies to all of the doors not just the 1st one :

Group { children [
Collision { collide FALSE children [
Transform { children [
Transform { translation 0 0.25 0 children [
DEF Door Shape { appearance Appearance {
material Material { diffuseColor 1 0 0 }}
geometry Box { size 2 3 0.1 }}
]}
Transform { translation -10 1.5 0 children USE Door }
Transform { translation 10 1.5 0 children USE Door }
Transform { translation 0 1.5 10 children USE Door }
]}
]}
]}

Have a look at the 'FC 2 Secret Garden' door here in the club as an example of a door using non-collision coding. I intended it to have a dual purpose - to be used as a simple decor piece in a home ( suggesting the existence of a door where there is none, ergo Faux Door ) & to be used in the Grand modular home pieces as alternatives to the existing pocket doors.

  • * * * * * * * * * * * * * * * * * * *

CLICK & DRAG ANIMATION

Click & drag animations have endless uses & can be fun, like the example of 'Art Studio 1' included in the club. Here is the coding for one of the squares you can click & drag around that graph in the object :

Transform { translation 0 -0.49 0.02 children [
Group { children [
DEF Square1 Transform { translation 0 0 0 children [
Shape { appearance Appearance { material Material { diffuseColor 0.75 0.75 0.75 }}
geometry Box { size 0.18 0.16 0.02 }}
]}
DEF Square1Drag PlaneSensor {
minPosition -2.26 -0.593
maxPosition 2.26 0.593 },
]}
ROUTE Square1Drag.translation_changed TO Square1.set_translation
]}

As you can see, this coding involves yet another sensor - the PlaneSensor This is the sensor that allows us to drag a piece around in a space defined by the minPosition & maxPosition. The coding here allows us to SHIFT the piece up & down, & left & right.

Another creaton of mine 'Santa with Star' uses a PlaneSensor to ROTATE a Grouped piece. You'll also find it in the club. The coding for this is quite a bit more complex in that it requires the addition of Script. Here it is, although I've simplified it by just including 3 of the moving parts - the hand & cuff & star. Note that you must DEF the Group or piece, & include rotation 0 0 0 0 in the translation coding :

DEF Anim Group { children [
DEF Star1 Transform { translation 0 0 0 rotation 0 0 0 0 children [
Group { children [
Transform { translation -0.39 -0.65 0.53 children [
Shape { appearance Appearance { material Material {}}
geometry Extrusion { creaseAngle 2 beginCap TRUE endCap TRUE solid FALSE
crossSection [
0 1, 0.38 0.92, 0.71 0.71, 0.92 0.38, 1 0, 1 -1,
-1 -1, -1 0, -0.92 0.38, -0.71 0.71, -0.38 0.92, 0 1, ]
spine [ 0 -0.05 0, 0 0.05 0, ]
scale [ 0.06 0.1, 0.06 0.1, ]}}
]}
Transform { translation -0.393 -0.653 0.38 rotation 1.75 0 0 1.57 children [
Shape { appearance Appearance {
material Material { diffuseColor 1 1 1}}
geometry Cylinder { radius 0.08 height 0.1 }}
]}
Transform { translation -0.32 -0.5 0.55 rotation 1.75 0 0 1.57 children [
Shape { appearance Appearance {
material Material { diffuseColor 0.3 0.26 0.2 emissiveColor 0.3 0.26 0.2
specularColor 0.6 0.52 0.23 ambientIntensity 0 shininess 0.7 }}
geometry Extrusion { beginCap FALSE endCap FALSE solid FALSE
crossSection [
0 0, -0.15 0.05, -0.3 -0.1, -0.1 -0.1, 0 0, -0.1 -0.1, 0 -0.3, 0.1 -0.1, 0 0,
0.1 -0.1, 0.3 -0.1, 0.15 0.05, 0 0, 0.15 0.05, 0.2 0.3, 0 0.15, 0 0, 0 0.15, -0.2 0.3, -0.15 0.05, 0 0, ]
spine [ 0 -0.02 0, 0 0 0, 0 0.02 0, ]
scale [ 0 0, 0.4 0.4, 0 0, ]}}
]}
]}
DEF Drag1S Script {
directOutput FALSE
mustEvaluate FALSE
field SFRotation newRotation 0 1 0 0
eventOut SFRotation spin
eventIn SFVec3f translationIn
url [ "javascript:
function translationIn(value)
{
newRotation[3]=value[0]/2;
spin=newRotation;
}
",
]}
DEF Drag1 PlaneSensor { autoOffset TRUE enabled TRUE
maxPosition 1.2 0 minPosition 0 0 offset 0 0 0 }
ROUTE Drag1.translation_changed TO Drag1S.translationIn
ROUTE Drag1S.spin TO Star1.set_rotation
]}
]}

**THE CURSED ANIMATION !**

We've covered a couple of ways to activate an animation - prox sensor, touch sensor. A little known or used but interesting variation on the touch sensor is the curse-over variation which doesn't require clicking to activate the animation. However, this sensor does require the inclusion of PROTO coding along with all the rest of the usual animation parts & ROUTES. The 'Beach Shower' in the club uses one. I find this sensor a little 'touchy' though, so I rarely use it. What I mean by 'touchy' is that it's easy enough to activate but if you're not careful to get your cursor out of its path you'll keep re-activating it ad infinitum. I also used it on the faucet in the Mod Kitchen where it's in a better, more confined space & therefore less likely to be unintentionally activated. It does start & stop with each 'wave' over though.

Here's the PROTO coding. It goes at the VERY TOP of the wrl file coding - just under the 1st line & BEFORE the WorldInfo. If you're going to use it, be careful to copy it exactly as is :

PROTO BooleanEventToCurrentTime [
eventIn SFBool trueFilter
eventIn SFBool falseFilter
eventOut SFTime currentTime ]{
Script {
directOutput TRUE
eventIn SFBool trueFilter IS trueFilter
eventIn SFBool falseFilter IS falseFilter
eventOut SFTime currentTime IS currentTime
url "javascript:
function trueFilter( bval, curtime ) {
if( bval ) currentTime = curtime;
}
function falseFilter( bval, curtime ) {
if( !bval ) currentTime = curtime;
}"}}

Down the line comes all the coding for the piece to be animated, the rest of the animation parts, & the ROUTES - all of this goes in AFTER the WorldInfo. In the example below, I am using a ScalarInterpolator to control the transparency of the object. The 1st pass over of a cursor activates the animation & because the animation is on a toggle, the 2nd pass over stops it. Note that the material must be DEFd & that here I've set the transparency at 1 because I want the object to appear. One could reverse the animation & make an object disappear too in which case you would need to adjust the ScalarInterpolator accordingly.

Group { children [
Transform { translation 0 0 0 children [
Shape { appearance Appearance {
material DEF Mat1 Material { transparency 1 }
texture ImageTexture { url "yourtexture.jpg" }}
geometry Box { size 1 1 1 }}
]}
DEF TS1 TouchSensor {}
DEF Clock1 TimeSensor { cycleInterval 20 loop TRUE startTime -1 }
DEF SI1 ScalarInterpolator {
key [ 0, 0.4, 0.5, 0.6, 1, ]
keyValue [ 1, 1, 0, 1, 1, ]}
DEF S1 Script {
field SFNode tproc USE Clock1
field SFBool state FALSE
field SFTime pause 0
eventIn SFTime toggle
eventOut SFTime triggerStart
eventOut SFTime triggerStop
eventOut SFTime triggerStartInt
eventIn SFBool activated
eventIn SFTime cycle
directOutput TRUE
url "vrmlscript:
function activated( active, curtime ) {
if( active ) {
triggerStart = curtime;
state = TRUE;
}
else {
triggerStop = curtime;
state = FALSE;
}}
function cycle( curtime ) {
triggerStartInt = curtime;
}
function toggle( stime ) {
if( state )
{
state = FALSE;
pause = stime - tproc.startTime_changed;
tproc.enabled = FALSE;
}
else {
state = TRUE;
tproc.set_startTime = stime - pause;
tproc.enabled = TRUE;
pause = 0;
}}"}
DEF Flash BooleanEventToCurrentTime{}
ROUTE TS1.isOver TO Flash.trueFilter
ROUTE Flash.currentTime TO S1.toggle
ROUTE Clock1.fraction_changed TO SI1.set_fraction
ROUTE SI1.value_changed TO Mat1.transparency
ROUTE Clock1.isActive TO S1.activated
ROUTE Clock1.cycleTime TO S1.cycle
]}

Go on ... wave that wand ! You know you want to *grin*.

  • * * * * * * * * * * * * * * * * * * *

FOUNTAINS

Once upon a time, there was script one could use to animate texture. Yes, honey ... script. But then the big bad wolf came along & put an end to that convenience for objects in CTR. Now, if you want to make a fountain, it's a lot harder to make one that's convincing. Oddly, however, using that script in a world still works. Go figure. Anyway, the only ways I've come up with to approximate the movement of water for a fountain you can see in 2 creations in the club : the 'Serenity Fountain' & the 'Gunmetal Waterfall'. Have a look see. Both activate by clicking the water itself. The 'Serenity' is easier to do in that all it involves is moving the water up & down with a PositionInterpolator. You could make it a bit fancier by combining that with a subtle shift in transparency using a ScalarInterpolator.

The 'Gunmetal' is a whole different story. For that animation, I did something completely unexpected. I scaled a circular Extrusion 1 meter thick with no top or bottom on it, applied rotation 0 0 1.75 1.57 scale 2 1 0.25, put texture on it, & animated the object itself with an OrientationInterpolator 360 rotation.

DEF FOI OrientationInterpolator {
key [ 0, 0.25, 0.5, 0.75, 1, ]
keyValue [
0 0 0 0,
0 1 0 -1.57,
0 1 0 -3.14,
0 1 0 -4.71,
0 1 0 -6.28 ]},

Then I built a housing around it ... & the rest is VRML history. Sometimes you gotta think outside the conceptual ... Box LOL !

Back to top

Written by Morning.star, reproduced unedited and published with her permission. Eleven documents. Morning.star has written many more and they will be added over time; this is not the complete set and does not claim to be.