Version 1.8.1 of the Mesmerizer was intended to be a small bug-fix release. The original impetus for shipping it was to address a mostly cosmetic problem with outfits. If you have No9 outfits configured in your #RLV, but no Peanut outfit folder (i.e. you have a folder in #RLV called "> Outfits" but not one called "Outfits"), then listoutfits will show a "ghost" peanut folder that is identical to the genuine No9 folder. This only affects viewers using RLVa (e.g. Firestorm), and while it is mostly cosmetic, it's confusing. This release fixes that display issue.
While working on outfits, I discovered a potential out-of-memory issue with listing the contents of large RLV folders (extended with ~more folders) and as a result I adjusted the display code to operate on each folder part in isolation, rather than trying to read the entire extended folder into memory at once, as the code had previously done. Since a side-effect of listing a folder is to populate the symbol $rlvpaths, there is still a potential memory limitation, but it's much less easy to hit with reasonable folders than it was. I have ideas for how to address that remaining limit but they will have to wait for another release.
Enhanced Camera Control
While working on these bugs, I was reminded of a request I'd received about enhancing camera control. So version 1.8.1 adds two new camera commands: textures and fixate.
Replacing Textures
The textures command takes a single parameter - a texture key - and replaces the textures used to display all in-world objects except those that are worn by the subject with the given texture. This allows for the creation of numerous visual effects, most of them resulting in a very disorienting experience for the sub, especially when combined with some of the distortions and effects available via vision spheres or overlays. The normal textures can be restored with a textures "-" command.
Body-part fixation
Version 1.8.1 also introduces the fixate command. This command causes the sub's camera to become locked onto a target avatar (by default the issuer of the fixate command), at a specific point on the target avatar's body (by default the avatar's face). fixate takes a single parameter: a colon-separated list of key-value pairs. The simplest fixate command, one that simply takes all the defaults, is:
/99 fixate ""
This will cause the sub's camera to point at your face and track you if you move. If you move more than 30m from the sub, the camera tracking will end. You can also end it explicitly either by passing "-" to fixate (i.e. fixate "-"), or by using the existing freecam command.
Multiple options may be specified, each option being a key-value pair, as follows:
| Keyword | Description | Example |
|---|---|---|
| target | name or key of avatar to track | target=Nue Broome |
| part | body-part or offset to target | part=face |
| sitpart | body-part or offset to target when seated | sitpart=<0,0,-0.2> |
| camdist | Distance the camera should be from the target | camdist=1.5 |
| camheight | Height offset of the camera from the target avatar's center | camheight=0.3 |
| fov | Camera field of view in degrees. Default is 45 | fov=20 |
| range | Distance at which the fixation stops. Default is 30m | range=15 |
| resume | Whether to resume fixation if the target re-enters the range. Default is no | resume=yes |
The target keyword can specify the avatar to be targeted. You can use either an avatar name or key. If omitted, the command issuer will be targeted.
part specifies either a body-part by name (one of "feet", "crotch", "breasts" and "face"), or as a vector offset from the avatar's center. This vector should be thought of as specifying a fraction of the avatar's size, so an offset of <0,0,0.5> should point the camera roughly at the top of the target's head, while <0,0,-0.5> would aim the camera at the bottom of their feet. Since animations or poses can't be taken into account, the target precision is necessarily limited.
sitpart allows you to specify a different target offset for when the target avatar is sitting. If a body-part name is specified for part, then sitpart defaults to an appropriate value for that body part. sitpart can also be specified as "none", in which case the camera will be unlocked while the target is sitting.
camdist specifies the horizontal distance the camera should be placed from the avatar. The default is 2m. camheight specifies the height of the camera, again as a fraction of the avatar height, with a zero height (the default) being roughly level with the target avatar's midpoint. This means that a view of the face will be looking upwards, while a view of the feet will be angled down.
fov specifies the field of view in degrees. The default is 45 degrees.
range specifies the distance from the sub at which the target will no longer be tracked. If the target moves further away than the specified range or leaves the sim, the sub's camera will be unlocked. By default, this will end the fixation. However, if resume=yes is specified as an option, then the fixation will resume if the target comes back within range. This also allows you to enable fixation for a target that is not currently nearby (for example, in a login trigger or event). To do this, along with the resume=yes qualifier, if you want to specify a target avatar, you will need to use a key rather than a name. For example:
/99 fixate "target=7f1cfe79-71ae-4855-b766-754ec2e38bd7:part=face:resume=yes"
As before, either the freecam or fixate "-" commands will cancel an active fixation.
Environmental interrogation
Version 1.8.1 also includes the first of what I expect to be a family of "environmental interrogation" features - methods that allow Mesmerizer commands to gain access to information about the sub's surroundings.
Imagine you have a trigger "get onto the bed" with an action of something like "moveto ed3b2ea3-98b5-415e-baf5-0496727e6ffd sit ed3b2ea3-98b5-415e-baf5-0496727e6ffd". The intent is that saying "get onto the bed" will cause the sub to walk over to the object with the given key (presumably a bed) and then sit on it. This works fine. However, if you decide to switch the bed for a new one, then its key will change and the trigger will no longer work. You can use the object name instead of a key, but again different beds typically have different names. If the object is modifiable, you could change its name to "Bed" (and remember to change the names of all future beds accordingly), but that's not an option for no-mod beds. Also, if the bed is no-copy and you do this, then when you take it back into inventory, it will still be called simply "Bed", which isn't very descriptive.
Mesmerizer 1.8.1 addresses this with a new command - nearby - that looks for nearby objects whose names contain a given string. nearby takes two parameters - a variable name and a string - and will set the variable to a list of object names that contain the given string. For instance, the command:
/99 nearby beds bed
will set the variable "beds" to a list of the names of nearby objects that contain the substring "bed". The nearest such object will be listed first, so the compound command:
/99 nearby beds bed sit "$beds.1"
will sit on the nearest thing with "bed" in its name. The match is case-insensitive, and only scripted objects are returned. If an object name contains a colon, the colon will be replaced (in the beds variable) with a different symbol "꞉" that looks like a colon, but is actually a different unicode character. Mesmerizer commands that take object names will silently convert this character back to a colon, which allows this somewhat convoluted process to work transparently.
At the initial release, only a case-insensitive substring search is supported. In future I may add additional options to control the type of comparison (e.g. whole-word matching). If you have a need for a specific type of comparison, let me know.