VRML 2.0 Scene Grouping & Sensor Routing

Thoughts by Larry "Wingnut" Wendlandt on attachment issues and
sensor routing of VRML 2.0 scenes rendered from moos.


Let's see, where do we begin. I guess with a bit of overview. The new VRML 2.0 specification has something called sensors, which are events that a user can do to a vrml scene... like mousing-over a vrml object, or clicking on one, or dragging one. These actions produce EVENTS within the vrml browser. There are two kinds of events. EventOUTS and EventINS. Us mooers are going to want our moos to be able to listen for users to click something, or drag something, and update the object's view/location. Here's an example. You display your moo room, in vrml. Lets say there are two objects in this room... a box and a sphere. The box is over in the forward left corner of the room, and the sphere is floating in mid air just slightly off to the right of the center of the room, slightly closer to the near wall than room center, and hovering approximately 45% of the overall room height... above the room's floor. See how hard it was to describe where the sphere was in the room? WHERE... within a vrml SCENE... another object/scene is located... is called TRANSLATION. Notice how the sphere's height off the floor (y-axis translation) was so much easier to describe than its forward/back and left/right location in the above example. That's because I used a PERCENTAGE. I said it was 45% of the room's overall height... above the floor. If the room happened to be 10 meters tall, its a quick trip to calc that the sphere is 4.5 meters off the floor. If I had described the left/right location (x-axis translation) as 10% right of room center, it would have been much easier. For forward/backward location, I could have said that it was 60% nearer than room center. You can see that percentages is an easy way to deal with translations.

There is another feature of VRML called GROUPS. Groups can be thought of as CONTAINERS. The room in our example, is a GROUP. It is a vrml object, that contains two other vrml objects. The room COULD be an object inside a group of its own, like if it were a room in a multi-room apartment, which is a member of a group of apartments in an apartment building, which is a member of a group called a city, which is a member of a group called a planet, which is a member of... well, you figure it out from there. It may take some time to ponder all the possibilites of grouping when it comes to vrml scenes. Unfortunately, we might have to think about ALL of them here in this document.

When we start to try to calculate PERCENTAGES OF DISTANCES that a 'contained' object is... from the borders of its group, like we did with the sphere and the room... we need to know about a phenomenon called SCALING. Scaling is how things get their size adjusted/set. If the sphere is said to be 1 meter wide, and we scale it UP by a factor of 3, it will now be three meters wide. If we scale it down by a factor of 4, it will be .25 meters wide. But scaling should be VERY dependent upon the SIZE (border locations) of the object that CONTAINS it. When you drive your VRML semi-truck into somebody's home-in-a-thimble, the thimble owner will not want your semi-truck to squash their thimble in the overall scene. It'd be a bad scene. So, if the thimble is scaled at... let's say... .00013 % of its containing groups' width/height/depth... (a room 20 meters in all directions). And lets say your truck is scaled at .00016 % of its containing groups' size (a 12 mile diameter city). If your truck used ITS scale-to-its-group size and tried to apply it to the thimble's containing group, the truck would then swallow the thimble... an ugly scene. The truck will need to be scaled down in order to 'fit' into the thimble. Just like real life, you can't drive a truck thru the door of an outhouse without wrecking the scene, but you CAN bring a small-scale truck into the outhouse. So, upon one vrml object entering another vrml object/group, it will need to access the new locations scaling limits, and base its size on that... possibly ignoring all of its own scale-to-group settings.

Notice I said scale-to-group! Scale-to-group, heretofore called STG, is the secret to moving various sized objects into containers/groups. Room owners will probably have an STG setting on their rooms, and they won't allow objects to enter their room that burn up more than... let's say... 25 % of the container's overall space. So, if a room was 10 meters high (Y), 10 meters wide (X), and 10 meters deep (Z), the largest object allowed to enter the room, according to its owner-set STG setting... is 2.5 meters in any direction. There may also be STG settings for THE SMALLEST allowed object to enter the room, such as is the case with a screen door. :)

Since we/I have decided that scale-to-group (STG) settings will be in PERCENTAGES, when it comes time to scale an object so it fits in a container... we will probably need to go ALL THE WAY back to the PARENT grouping object, and in our example, that was the planet. ALL objects will have properties for preferred actual size too. Your truck, when viewed NOT in some container group... will not be subject to any STG from its container... cuz it has NO container other than the maximum allowed total size of the VRML browser's WORLD COORDINATE borders. So, you'll be allowed to set your truck length at 20 meters, your height at 4 meters, your width at 3 meters, what have you. These are ONLY for looking at the object when it is not part of a container/group. When it IS part of a group, the groups' owner must do one of these...

A. Allow the object's entry at its owner's preferred size settings
B. Ask the object to scale itself to allowed group percentages before entry
C. Force-scale the object to allowed group percentages upon entry
D. Disallow object entry

An object's STG setting, will no longer be necessary once it LEAVES its current group, if indeed it was a member of a group in the first place. So, most likely, its NEW container/group will recalc its STG setting based on ITSELF, and ignore any former groups' STG. When a container object renders its contents (group members) into its VRML scene, it will pick up STG setting from either itself (thru an extra setting in a group's CONTENTS property, or from the object itself. I would suspect both the GROUP object AND the member object will contain SOME data about this stuff. The GROUP object will need enough info on the entering member object to test for scale limitations and calculate a proper scaling if necessary. The member object should know which group it belongs to (via a LOCATION property) and MAYBE it will need to know and STG for itself, though I'm not sure why an object would need to carry its STG with it. With OO systems... it is best that objects not force things upon other objects, like setting their STG values. Its better for containing/group objects to carry all data needed... ABOUT the MEMBER object itself, and the member object only defines a mechanism for other objects (groups objects) to read that data.

Now, back to sensors. VRML browsers will, most likely, eventually be able to display scenes/objects in multiple windows/frames at once, probably using different viewpoints. When it comes time to 'drag' an object to a different location within a container/group, having at least 3 view windows to the scene will make it MUCH easier to place objects in the wanted new position within the scene. Dragging an object, produces EVENTOUT events by the VRML browser. These eventouts will need to be sent to the moo, because the moo-produced scene will need to know WHERE each object is located (translated) in the room/group/container. That way, if Jim moves the cube from one side of the room to another, then Sally comes along and views the scene, the cube will be in the same location within the room for both Jim and Sally. Now, lets say their are 10 people viewing the room... all at once. When Jim moves the cube from one side of the room to the other, the moo must receive browser-sent EVENTOUTS (probably via a Java telnet port) and apply them to translation settings which the group object is holding about the location of the moved object. Then, the moo must generate EVENTIN commands to be sent to 10 VRML browsers... so that everyone who is viewing the room/group/scene... will see Jim move the cube across the room. The moo must be kept abreast of any changes ANY viewer makes to the scene, to maintain commonality amongst all viewers. Essentially, if someone tosses a wad of paper into the garbage can, everyone viewing the scene must see it happen, so we can all chat about it. Any sensor, beit drag, click, mouseover... that affects the view of a scene... MUST be sent to the moo. The moo will do the actual scene view adjustment, even for the EVENTOUT generating user's browser (the one who did the dragging, clicking, or mousing).

I just saw a piece of bad news in the ISO/IEC DIS 14772-1 VRML 2.0 spec. There is no support in there for object-to-object collision detection... only avatar viewpoint-to-object. So, unless we tell a moo room to keep track of, and test for, two objects trying to occupy the same space or bounding box, we're not going to be able to throw polyhedra at each other. There are no EVENTOUTS currently for object-to-object collision? What were they thinking? And what about gravity? How about mass, volume, and density? Hell no! FINE! We can take care of all those boring physics properties in the moo as well, can't we? After all, isn't that why we proggem' moo, so we can do stuff that the rest of the planet is years away from? No NOT chatting... building! :)

I recently built my first few VRML 2.0 objects on Sensemedia SnowMoo. One, is a VRML 2.0 ElevationGrid demo, where I layed out a 10x10 meter grid, and just slapped a couple settings in there, and did a mountain overlooking a nearby valley. Once it is rendered, its rendered, and the moo really doesn't know where the mountain is located ON the grid. It COULD know... by retrieving the data I used to place the mountain and valley. I am thinking that a good step toward simulated object-to-object collision, mass, volume, velocity, acceleration, density, surface elasticity, shock absorbtion, friction, gravity, impact rebound trajectories and spin, and anything else I might have left out... is to try to get a cube to tumble down that mountain, and eventually land at the bottom of that valley. I figure it will only take about 35 trillion calculations or so, and SnowMoo's CPU should be done with those calculations for the first VRML frame of the tumble... in about 6 days. :) The cube's trip all the way down the mountain and into the valley, should take about 7 months to complete, so bring food and camping gear when you go to view the tumble. I'm just kidding, of course, but I would suspect that the owners and wizards at my moo, will probably frown on these terrible cycle-eating mathematical formulas we're going to need to throw at the moo. And besides that, I know very little about math, so I am blatantly weak with the physics formulas, not to mention trying to get the moo's floating point system and math utilities package to even accept these formulas. As far as updating the browser for each frame of the tumble, there's really only about 16 bytes that need to be sent to each browser viewing the scene... for each frame. Approximately 8 bytes for cube translation, and about 8 for cube rotation. Naturally, if the cube or the landscape are to be dented or discolored at each impact point of the tumble, we will need to send more bytes to update those things as well. The cube could also accelerate as it tumbles, depending on physics properties of the cube and the landscape... and pieces of cube and mountain could be told to crumble into new polyhedra (addChildren) as well. There's also environmental factors we could bring into play, like wind. And I'm sure someone will try to put bowling pins somewhere near the base of the mountain.

Implementing all this, is going to be tough. But as we all know, when the going gets tough, the tough go shopping. So... I am currently shopping for a collaborator who knows mathematics and physics, and preferrably, also LambdaCore moo programming. There's no money in this, just love for the hobby.

A few more comments about GROUPS. When/if we manage to start bringing some physics properties into VRML, we need to think about how those properties will affect the group that a given object is a member of. If you try to place a 400 pound anvil into a room made entirely of sugar wafer cookies, chances are, that anvil is going to fall right thru the floor, and if that room is a 9th floor apartment of a building comprising entirely of sugar wafer cookie apartments, the anvil will most likely fall through ALL of them. Just like in real life... if you put TOO large of a cherry bomb in a toilet, you could crack the planet. So, when an object enters a container/group, the group management object(s) will need to pick up certain other properties from the entering object... and another type of scaling might need to take place... weight. If a spere is placed on a slanted floor, with gravit turned on, it will roll to the lowest point of the room. We will most likely follow the same 4 rules of entry scaling that are listed above. Even a simple property like spin (auto-rotation) could be a problem if the object entering the room/group is a large lawn mower blade, because it could chop you, and your chatty friends' avatars to bits upon entry.

Let's take a look at the main properties of physics of a real life object, if I can think of a few...

Shape - This is a given. If an object has ANY size, it has a shape, or it won't be seen. Shape is also a grouping node command in the VRML 2.0 spec. Just thought I'd add that. :) Shape is fairly unimportant as long as an object is hovering in mid space, and there is no wind. But a sphere with one flattened side... placed on an un-even floor, with gravity in the group and mass to the sphere... may roll a bit and stop with its flat side against the floor. It may also roll and never roll its flat side down... so it will roll all the way to the border of the group/room... depending on which direction the floor is slanted, and the roatation and translation of the object when it is placed into the room.

Size - Ah, we know about this one already. Or do we? The main thing to think about with size, is if we allow someone to scale-up an object that's inside a container. For example, if someone was allowed to scale-up an ice cube floating in a beverage glass... to... let's say... 20 meters wide, and if collision detection was active on both the glass, and the ice cube...then the glass would likely explode. Good effect, difficult to implement VRML-wise.

Mass - This is the quantity of matter in an object as measured in its relation to inertia... determined by dividing the weight of an object by its acceleration due to gravity. Yee hah!

Weight - the force of gravity acting on a body... determined by multiplying the mass of the object by the acceleration of gravity.

Inertia - The tendency of an object which is at rest, to remain at rest... or the tendency of an object moving in a direction, to continue moving in that direction... unless acted upon by an outside force.

Gravity - The force that tends to draw all objects near or on a spinning mass towards the center of that mass. Also called heaviness.

Currently, two LambdaCore moo properties take care of containment for text-based telnet display of LOOKs. They are .contents and .location. The container object uses .contents via putting an object's number in this list-type property. When it comes time to display the contents of a container, a verb called :tell_contents gathers the names of all the objects in the container's .contents property, and displays them in an 'English list' format. Correspondingly, all objects have a .location property that indicates which object, if any, is its container. So, the object's .location and the container's .contents work hand in hand, and are both updated when an object is moved to or from a container.

Here in my early days of writing vrml 2.0 spec LambdaCore verbs, I am fighting with containers and their relationships to grouping nodes. Without multiple-inheritence objects, I keep coming back to having a vrml scene, no matter WHAT type, as a single object... as opposed to having GROUPER objects that keep track of child groups (or contents). If indeed, any object IS fully ready to be a grouping manager object all on its own, then 'contents' is going to take on a whole new meaning. When an object is moved into a room/container, the group manager verbs on both objects will probably need to interact. Lets say a user teleported a very complicated scene, such as a highly-detailed city... into a room. This action could drastically slow down all operations in the room. And each of those buildings in that newly contented city, could have contents, and those could have contents... which could be each cities. If the browser were required to render EVERYTHING, we'd never get out of that room uncrashed. Now... there is a VRML node called LOD, standing for level of detail. Simply put, any object in a scene can have multiple renderings associated with it. Which rendering the browser uses to render the object, is based on viewer distance from object. So, looking at a building from 1500 meters or more, the building could be simply a cube. From 750 - 1500, the building might be rendered as a cube with texture-mapped windows on the side of it. At less than 750 meters, the building is rendered in all its glory. This LOD stuff will come in handy as we get cluttered vrml moo rooms... and we might even need to REQUIRE LOD before an object can enter.

Let's take some more examples for a drive. You hear a knock on your room door, and peek out to see Avante's Avulsion Avatar... which appears to be a large, multi-armed, high-detail, object-crushing hulk. Your door knocker reports that the AAA has 35,000 polys, within 45 grouping nodes, 85 texture maps, 600 lights, 200 views, and a Java-based interactive cockpit and chat sauna. YOUR room... is a plush Galaxina-class generic room, decked to the hilt. Everything is the room is either high-gloss gold, or glass... that is... where you haven't fabric-textured. The tiny patterns on the drapes, are actually cavewall scrawls, each depicting a different chronological era in your life. Just entering this room with a cubert (a cube-shapped avatar), you can cause permanent damage to your data lines. :) Now, AAA wants to come in. What do we do? Good question. If the room cares about its lag, I suppose it would request that the AAA take on a LOD as low as it can stand... preferably a cubert. The AAA could refuse, but COULD offer to drop to a 2000 poly model, upper torso only (probably keep much of the weaponry that way) :). You, or your room, could refuse again, or allow it. Good generic avatars could have pre-knock warnings that tell the avatar's owner that e is trying to enter a high-detail area... and to consider LOD'ing or cuberting before entry. Rooms might even be able to report the browser capabilities of folks who are already in the room, so knockers know which, if any, viewers will and won't be able to see the entering avatar in all its glory, or visually at all.

Ok, lets take the worst case scenerio. You let AAA into the room, at its normal detail. POOOM... the door crashes to the dirt, and in walks 75 tons of greasy, smelly, object-crushing horror. Your room's grouping manager verbs send eveyone's browser an addChildren event, and everyone's browser starts the arduous task of rendering the view of this nightmare... under the parent grouping node for your room. Your chat gang starts dropping like flies, as one browser after another runs out of memory. Small animals run for cover, and the sun gets dimmer. Avante is sad, cuz e didn't get to show off the gorgeous AAA. You, the room owner is sad, cuz this thing trashed your room, and slung all your chatters offline. Nobody wins. How do we avoid this problem? Hell, I dunno. I'm still trying to figure out what an interpolator does. :)

One way to beat it, is to use cuberts most of the time, and only drive your AAA into low detailed rooms and battlegrounds. If someone wants to view the AAA, their browser would release the memory used to render the already-gawdy room (by closing the view) and then open a view of the AAA... bounded in a simple box, or levitated in a colored background sphere or textured cube-room. (call cube box rooms 'cubesteads'? Check def of 'bestead'). ANYWAY... such foolishness, eh? Let's cruise onward.

I have a feeling that... one of the more poular things to do in a virtual reality 3d environment amongst friends... is to 'whiteboard' 3d objects and talk about them... while rotating around them or flying thru them. Naturally, to get the smoothest motion with many avatars around, and not considering the detail of the whiteboarded scene... you'll want everyone flying cuberts in a cubestead. So, nothing is in the room, except a cube for each user who is in the room, and the scene of central attention. A viewing room, sotospeak. If you think about it, its exactly the same as everyone being in a room. You can critique a room by being in it... for interior design, or view it from helicopter view... for exterior architecture chat. Its when you are IN a high-detail container, looking at some other high-detail container/object when the problems arise. Most likely, here in the early days of VR, it will be the simple-yet-fascinating... or the LODized objects that will be most popular.

Stay tuned... we're just getting started.

This document changes often, and is not to be republished for commercial gains.

Copyright (c) 1997 Larry "Wingnut" Wendlandt

Mail Wingy

Wingy's Off-Moo Homepage

Wingy's Directories

Wingy's Tent