Introduction
The RezMela system allows users to place icon objects on a map-like representation of a larger external area, and to manipulate icons already there. As this happens, full-sized world objects corresponding to these icons are placed and manipulated in the region itself. In this way, users can create large scenes of objects in a classroom-like setting and then go out and intereact with the objects in the scene itself.
Objects (and icons) can be complete linksets, and are not linked to the RezMela system. Together they form a library of objects which the user may browse and choose from.
Scenes may be saved to and loaded from notecards, enabling a complex scene to be saved and later created quickly and easily.
Construction
These are main component objects in the RezMela system:
1. Control board - Comprising the map representation, various control buttons, an object picker - the primary UI for the system.
2. Rezzor - A moving "cursor" object that traverses the scene under instruction from the control board, placing objects where needed.
3. Icons -Small representations of the library objects, to be shown on the map interface
4. World Objects - The full-size objects to be created in the scene
The construction of each object is discussed in more detail here:
1. Control board
1a. The root prim of the control board is a small, invisible prim which contains the following:
The RezMela controller script
A notecard (!RezMela controller config) containing configuration information
The icon objects for the library
For each object, an optional notecard with configuration information (named as the icon name + "C")
1b. The control board map is a large vertical unscripted prim called "createCommand".
1c. Another prim, a white square with a black border, is mounted on the lower front of the control board and contains the saved scene notecards, together with the RezMela notecard manager script
1d. Various control buttons for moving, rotating and removing objects, clearing the scene, loading and saving scenes, etc
1e. Menu prims, normally small and invisible, which expand and become visible to display the menu-on-a-prim interface for various functions.
1f. An "object picker" section, which comprises:
A preview pane showing the currently selected object
A grid of thumbails (with arrows to go back/forward between pages) representing available library objects
A larger grid of buttons representing categories
1g. A teleport map board, which when clicked teleports the user to the corresponding point in-world.
1h. Various prims to control the water level, wind direction and sun position.
2. Rezzor
The rezzor appears as a hand pointing downwards, with a glowing animated texture pointing down to the centre of the small root prim at the bottom.
The root prim is the active component, and comprises the RezMela rezzor script together with the library of objects. Each object has the same name as the corresponding icon with a "P" appended.
3. Icon
The icon objects are typically linked to a single, small, flat root prim representing the base (ground) position of the icon. This prim contains the "RezMela icon" script.
4. World object
World objects, like icons, are linked to a base root prim. This contains the "RezMela world object" script.
Configuration
System configuration is held in the notecard RezMela controller config in the root prim of the control board. It's an INI-type file, and contains the following data:
Information on objects is held in the following places:
1. Object configuration notecards.
These are stored along with the icons in the root prim of the control board, and have the same name as the icon with a "C" appended. They are the usual INI-style text files.
The following values are available:
Vertical
Center
AdjustHeight
(bool) True to make the object always be vertical despite terrain - for example, trees, buildings
(bool) True to force the object to the centre of the world - eg road layouts
(bool) True to make the object adjust itself vertically so the root prim rests on the ground (eg vehicles)
2. "Objects" list
This list is stored in the object preview prim, which displays the currently selected object's image. In the same prim are all the image files, and also the "object picker" script.
The objects are listed in their categories as follows:
[<category name>]
<object name 1>
<object name 2>
<object name 3>
...
Objects may appear in more than one category.
Communication
1. Comms: control board <-> rezzor
The control board and rezzor, being separate objects, communicate through a combination of chat (to establish comms) and osMessageObject once handshaking is established.
The control board periodically sends a ping message (on a hidden chat channel) that includes the rezzor object name as specified by the value for "RezzorName" in the RezMela controller config in the root prim of the control board. The rezzor object, meanwhile, until paired, listens on the same channel for exactly that string based on its own object name. So by matching the object name and "RezzorName" parameter, it is theoretically possible for multiple control boards/rezzors to exist in the same simulator. This, however, has not been tested.
Once communications have been established, the rezzor closes its listener and relies completely on osMessageObject/dataserver. However, if it discovers that the control board object is no longer in the simulator (by way of llGetObjectDetails() and OBJECT_POS), it drops back into listener mode and waits for another control board to PING.
2. Comms: object picker <-> control board
The communication between the object picker script (located in the object preview prim) and the main controller is via link messages. The object picker script processes any delegated touches (see 6. below) from the control board and looks for any clicks on prims that form part of that sub-system. If an object in the library is selected, a link message is sent back to the controller to tell it which object is the current one.
3. Comms: control board <-> icons
See section (5) below for discussion of object/icon identity.
All comms is conducted through osMessageObject/dataserver.
On being rezzed, the icon sends a signal back to the control board, quoting its unique number, and received a reply giving basic configuration data - glow amount, hover text colour and so on. From then on, the icon reports short and long clicks back to the control board, and responds to commands from the control board to move, rotate, be selected/deselected, to die, etc.
4. Comms: control board <-> world objects
See section (5) below for discussion of object/icon identity.
All comms is conducted through osMessageObject/dataserver.
The traffic is one-way, from the control board to the world object, and consists of instructions to the world object to move, rotate, and die.
5. The question of identifying icon and world objects
This is a small area of some minor complexity. It stems from the need to be able to tie together the icon object and the corresponding world object, especially since there may be many of the same type.
The fundamental issue is this: As usual in LSL applications, it is not easy to relate the data known about an object when created via llRezObject() and the object itself. There is the object_rez() event in the rezzing script, which provides us with the UUID of the object, but this is no help in tying individual objects to their other data. In other words, if you rez ten identical houses, how do you know which object_rez() event relates to which house? And bear in mind that each house will have an icon object (rezzed by the control board) as well as the house world object itself (rezzed by the rezzor).
The solution is this:
When the control board wishes to create an object/icon pair, it first creates an icon, passing it a unique identifier as the rez parameter. The icon then picks this up
from its on_rez() event, and echoes this back to the control board. This gives the control board script the UUID of the icon, related back to its other data. Then we can send to the rezzor object the details (name, position, etc) of the object to be rezzed along with the icon object's UUID.
The rezzor object also allocates a unique integer identifier when creating a world object. It passes this identifier to the object through the start parameter, and the world object script then reads that identifier in its on_rez() event, stores it and echoes it back to the rezzor, similar to the method for the icon. Now the rezzor knows which icon is which, and passes back to the control board the UUIDs of both (i) the original icon and (ii) the world object.
Thus the control board has all the data it needs to manipulate the corresponding icon and world objects together.
6. Delegated clicks
For clarity and simplicity, the control board has a modular approach for non-core features (as well as the object picker). Since the controller script resides in the root prim, and the modules (object picker, environmental control and possibly others) are in child prims, the onus is on the controller script to inform the linkset via link messages when a prim is touched that it doesn't directly process. These link messages have a numeric value of 40510 (pseudo-constant LM_DELEGATED_CLICK), a key value of the touching avatar's UUID, and a string value consisting of the prim name, the link number, the face and ST values, pipe-separated.
So a script in a child prim can watch out for clicks on prims that it uses (by name or by link number) and process them accordingly.
Stored scenes
It is possible to store the name, position and rotation of all objects/icons in a scene. These are stored as text data in a notecard.
File layout
Formally, the layout of saved data is:
RMSF,<version>
<name>|<position>|<rotation>|<extra data>
The string "RMSF" (RezMela Save File) is an identifier to allow easy distinction between these files and other notecards. The version number is analogous to an API version, and relates to the format of the file. Currently there has only been one version, "1". If there is a change in the notecard format that the script needs to be aware of, this number could be incremented and conversions performed where necessary.
Position is stored as a vector in metres and relates to the object's position in-world rather than on the control board map. This position is relative to the "WorldOrigin" value in the configuration file.
The rotation is stored as an Euler vector in degrees, and also relates to the world. However, there is no concept of "origin rotation" - north is always north.
Extra data is a string containing a ^-separated (separated by carat characters) list of strings. This data can have various uses depending on the type of object (for example, the URLs of pictures in picture boards, or the coordinates, zoom level and type of ground map.
Scenes prim
Purely to make it easier to manage, the scene files are located in their own separate prim, away from the icon objects and configuration notecards. In the same prim is the notecard controller script, which communicates with the menu script to load and delete notecards. Saving to notecard uses the old llTextBox() method.
Saving a scene
To save a scene, click the "Save scene" button, and enter the name for the scene in the dialog that follows.
Loading a scene
To load a scene, click the "Load scene" button and select the scene from the list presented, or the "[ Close ]" button to dismiss the dialog. If there are more scenes available than will fit on the menu, you can use the arrows to move up and down.
Deleting a saved scene
If you have a saved scene you no longer require, you can delete it by clicking the "Delete scene" button and selecting the scene from the list. As with the "Load scene" list, you can close the list by selecting the "[ Close ]" button, and go up and down where appropriate using the arrow buttons.
Using the object picker
To add an object to the scene, it is necessary to find the object you want to add using the object picker.
First, select the category from the buttons below the preview pane and thumbnails. As you select each category, the thumbnails update to show objects within the category and the first object is selected and shown in the preview pane. If there are more objects in a category than there are thumbnails to display them, you can use the arrows to the right and left of the thumbnails to move backwards and forwards. These arrows are only visible when there are more thumbnails in the appropriate direction.
Clicking a thumbnail selects that object, and it is now ready to be placed in the scene by the control board (see below).
Using the control board
This section discusses user features in the control board.
Creating objects
Use the object picker (see above) to select the object you want to add, and then click on the control board to place the object. The icon related to the object will appear on the control board, and the object itself will appear in-world.
Alternatively, you can place an object on top of another object (such as a car on a road) by clicking on the target icon to place it.
Selecting objects
An icon (and its associated object) may be selected in order to perform further operations on it. To do this, long-click on the icon; the icon will glow, and the hand pointer will point to the in-world object. To deselect the icon/object, long-click again on the icon.
Operations on selected objects
When you have selected an object, you can perform various operations on it. These are:
Move the object by clicking - click anywhere else on the control board, as if you're positioning a new object
Move the object precisely - click the "Move selected" button and enter the new world coordinates in the dialog box
Rotate the object - use the four rotation buttons for a fine or coarse rotation clockwise or anticlockwise
Remove the object - click the "Remove selected" button to delete the object from the scene
Clearing the scene
Click the "Clear scene" button to remove all objects in the scene
Hiding the pointer
Click the "Hide pointer" button to move the hand pointer out of the way. It will move to the position defined by "RezzorParkPos" in the configuration.
Board admin functions
There is a hidden menu available to the board owner only. It can be accessed by clicking the small red prim to the bottom right of the control board, near the saved scenes prim.
Clicking that menu gives the following options:
Texture
This changes the grid texture on the control board. Two textures are available.
Reset
If the control board crashes or has its script(s) reset for any reason, the "Reset" function will cause the control board and rezzor to delete any icons and objects left behind. This takes several seconds to accomplish, since the whole region is searched for objects. Note that objects that themselves don't have running scripts cannot be deleted in this way.
Check
This performs an integrity check of the object library (and potentially other areas of the whole system). any mismatches, missing icons/objects/notecards/etc, or other anomalies are reported to the control board object owner in chat messages.
Close
Use this to close the admin functions menu and return to normal operation.
Miscellaneous topics
Delegated deletion of world objects
In some circumstances, it's useful for an application object in the RezMela library to be able to perform cleanup operations, etc before being deleted.
For example, the Rock Pile object creates piles of rock objects on rezzing. In order to clear the scene, it needs to know when it is about to be deleted so that it can in turn delete the rocks it has created.
For cases such as this, it is possible for the application script to inform the World Object script that it requires "delegated deletion". It does that by sending a linked message with an integer value of -7044001. This switches on deleted delegation. From there on, the script should check incoming linked messages for the value -7044002. If that value is received, the application script should do whatever is necessary to clean up, and then delete the object itself.
The teleporter feature
By clicking on the teleporter map located to the left of the control board, the user is teleported to the corresponding location in-world. In addition, an object named "Teleport return" is rezzed and sent to a position above the user's head. By clicking this object (actually a sit), the user is transported back to their original location.
The object contains a script also called "Teleport return", which handles the movement to the target location and back to the user's original position, as well as housekeeping such as self-deletion.