Wednesday, 17 August 2016

Avatar Complexity Oddities

Linden Labs has rolled out their new "Avatar Complexity" in their most recent viewer code, and most third party viewers have either already followed suit or will do so very soon. In testing it, I've discovered some very counter-intuitive aspects to it that all creators should be aware of.

What is Avatar Complexity?

This is a new evaluation that a viewer does of each avatar it has to display for you, and loosely speaking it gives you a general measuring guide for how difficult it is for a graphics card to display that person on your screen. Basic "Ruth" has a complexity of 1000. As you add some hair, clothing, shoes, jewellery, etc, the avatar becomes progressively more difficult for the viewer to draw, and the complexity value rises.

The exact calculation used (currently) can be found in the LindenLab documentation here as can instructions for how to see your values in-world.

The new viewer code has a sort of "scene culling slider" which checks the complexity of each avatar before drawing it for you. If the complexity is too high, it draws it as a very simple (and ugly!) jelly blob instead. The only exception is your own avatar...you will always appear fully rendered on your screen no matter how insanely high your complexity value is.

This "too high" cut-off value depends on the graphics setting you use, so if you have a fairly new graphics card you're likely able to run in Ultra graphics mode and only avatars with a complexity in excess of 350k will be turned to goo. If you have a somewhat older or less powerful card and can only run in Very High or High graphics mode, that number drops down towards 200k. For very underpowered cards running in Medium graphics mode, it's closer to 100k. There is a slider that allows you to override the cutoff, either raising or lowering it as desired.

Note that this has absolutely zero impact on the region simulator you're in. The data all gets sent to each viewer and this in no way reduces the server load. All it does is provide a mechanism for increasing your own personal viewer's frame rates if there are a lot of very complex avatars in the same region you're in.

My suspicion is that Linden Labs was sick and tired of hearing how laggy their region servers are when in many cases it's simply the user's graphics card incapable of sustaining a decent frame rate when there scene gets complex. Now they can point to a number and say "see, that avatar is way too complex so it's their fault and the lag is only due to your graphics card's performance, not our region." And that's true in many cases.

I also suspect they hope that by having these number visible to users, it will put some pressure on creators to be somewhat more prudent when making things. As a merchant you'll be able to point to your amazing new Product X and boast about how low a complexity value it has. If that means creators are making more efficient products (mesh in particular) then so much the better.

That's the theory. In practice, though...

A Number is Only Meaningful if it's Accurate

Here's the funny thing about using metrics: they're only as accurate as the method you use to calculate those numbers. The initial implementation of the Linden Lab viewer calculation isn't, or at least not when it comes to mesh.

Without getting into specifics (yet) I can assure you that the numbers you'll see in viewer are incorrectly misrepresenting the complexity of meshes. I'll assume that they're in the right general ballpark for a single prim or sculpty, but there's definitely something weird happening when it comes to mesh, causing it produce some artificially high values depending on how it has been created and textured.

As a general Opensim user, you should be aware of this before you start pointing fingers at someone and criticizing them for creating or wearing something that's too complex. Sure, maybe they are. But maybe they aren't and it's simply the viewer miscalculating the value.

Some Details

Let me give you an example:

My own in-world body is an all-mesh one. In Blender it's just under 30k triangles (15k verts) which is just a little under 4x as complex as the basic Ruth avatar (roughly 8k triangles/4k verts). Yes, it's definitely going to be harder for a graphics card to render so I fully expect it to carry a not-insignificant complexity value. It also uses 7 different materials (arms, legs, torso, face, lips, eyes, eyelashes) which is two more than the SL avatar uses, although the actual texture count is comparable...I simply break it up into more pieces for my own convenience.

Here's where it gets strange.

When I first uploaded it as a single mesh and put the textures on it, it reported as having a complexity of just over 30,728. I was expecting it to be somewhat high, but not that high. After some reading and experimentation, I discovered that the culprit was the 252 triangles of my eyelashes which use a texture that has an alpha (transparency). If you refer to my calculation link above, you'll see that having an alpha results in a 4x multiplier being applied to it and it seemed that the entire mesh was being hit with this penalty instead of only the portion of it that was using the eyelash texture.

I did a second upload, this time with the eyelashes as one object and everything else as a separate object. After putting the identical textures on it to my first test, suddenly my reported complexity was down to 13,796.

There is absolutely no different between them in terms of the work required by the viewer or your graphics card to draw either of them on the screen. They're 100% identical.

And it gets even stranger because next I broke my entire body into pieces, uploading each as a separate object, then wearing them all. Again, completely identical in all respects, but now the complexity was being reported as 10,364.

So the viewer is reporting three rather wildly different numbers for what are in all respects identical in terms of the metric they're supposedly supplying.

Which one is right? More importantly, which one is useful?

[Side note: just before you say I'm crazy to be wearing a body with 10k complexity, try putting on your favourite flexi-prim hair. I bet that more than half of the hair styles being commonly worn in the metaverse are over 20k which is double what my body is....]

From a simulator and asset-server point of view, the single-mesh object of the complete avatar is far, far more efficient. It's one request and one block of data to send. As the mesh is progressively broken up into more and more pieces, the burden on the simulator increases because each piece is a separate call to the asset server and a separate send to the viewer. Further, for the viewer to animate the avatar it has to move each of those mesh pieces separately on its own "rig" bound to the body, so (to a very small degree) it's actually more work for the viewer to have more pieces to have to do this for. And yet that complexity values being show reflect the opposite.

The exact same issue applies to all mesh objects that you might wear so that includes clothing or even unrigged mesh items. If it has a texture with an alpha, glow, bump map, or specular map (or basic glossyness setting) the penalty is applied to the entire object.

The Take-Away

There is already a Jira in Linden Labs' system to have them review this, and hopefully they'll adjust the code to have it only affect the actual surfaces (triangles) with that texture on them.

Until they do, though, you should be aware that some avatars are going to be reporting some much higher values than they really ought to be, so temper your criticisms of the wearer or creator, at least for the time being.

For the creator, it's a tougher call. Right now if you work with mesh, you'll get the lowest values by breaking up your work at least into 1 object per material and make it a linkset. You can get even lower by going wild and breaking it up into hundreds of little pieces to get even lower values. However, by doing so you'll be adding to the load of region simulators that are often already under strain, so perhaps find some happy middle ground and pass the word around that you shouldn't believe the numbers just yet....

Wednesday, 3 August 2016

RELEASE: Paramour Clubmaster Dance Machine v2.1

I'm happy to announce the release of the Paramour Clubmaster Dance machine v2.1.


This is a minor revision/update and is in most ways identical to version 2.0 in terms of features and contents. The new version contains only the following two changes:

Shorter Script

An issue was discovered where certain viewers (notably the current version of Singularity) were truncating the main danceball script if it was opened or edited using that viewer. Firestorm users were unaffected.

To resolve this problem required reducing the overall script length (technically, reduce its character count) which posed a problem as it was already as "lean" as it could be without making it unreadable for people interested in modding it. However, since very few people modify the set-up and those who do are typically able to do their own error-checking, I decided to remove the entire debugging and error-checking utility which was optional (and disabled by default) in version 2.0. In doing so, I was able to bring the script down comfortably under Singularity's limit without in any way affecting normal performance.

Less Spam

I've had a few requests to reduce the chat spam when a couples poseball self-destructs due to someone not sitting on it or having vacated it. I've altered the poseball script to stop it from saying anything at all, now, and will simply notify the other ball's occupant instead. Otherwise it will be silent.

Do I Need To Update my v2.0 Ball?

If you use Firestorm to edit scripts and don't mind a bit of chat spam from the couples poseballs, no. There are no other changes to functionality or contents and you can continue using v2.0.

Where Can I Get the New One?

The main place to obtain a copy is to pick one up from my Paramour Shopping region in RefugeGrid. You can get there by hypergridding to:
RefugeGrid.com:8002:Paramour Shopping
You'll find the boxed version of the danceball in the middle of the three pyramid-shaped buildings, on the wall beside the assorted club dance items. While you're here, have a look around and see if there's anything else you'd like.

As always, my products are free so don't hesitate to come and get one. If you really enjoy my products and want to help me a little with the cost of keeping the shopping region available, I'd encourage you to make a donation (even a very small one) to RefugeGrid...there's a sign on the wall of the building that you can click to take you to the web page where you can do so securely. Believe me, every little bit helps immensely and is very, very much appreciated!

EDIT: I had one person who picked up a copy earlier today from my shopping region who discovered upon getting home that it wasn't full perm. If that happens to anyone else, you can try taking a new copy or you can go ahead and use God Mode to force permissions...the danceball, script and animations should all be full perm.

Tuesday, 2 August 2016

IMPORTANT NOTICE re Paramour Dancemaster v2.0 Danceballs

A couple of recent issues I've been trying to help people solve with the Paramour Dancemaster v2 Danceball have uncovered an interesting issue: if you open and edit the main script using the Singularity viewer, it truncates the script at line 937 which then causes it to fail to work and there is no (easy) solution. This is caused by a character limits for script length that appear to be shorter in that viewer than they are with Firestorm or Kokua.

I will be preparing a new version of the script that trims out my instructions, comments, formatting, and changes variable names to be very short (and non-intuitive) variable names to bring the total script length down under the Singularity limit. In the interim, please do not edit and save this script using the Singularity viewer. You may safely use Firestorm (which I use) and I believe Kokua would also be fine.

I will post a notice once the new version is ready.

Weight Transfer Utility Settings for Blender v2.77a

In a previous tutorial post I went into considerable depth about Blender's weight transfer utility. That post was written under Blender 2.76 when that particular function in Blender was under revision in the code base and was subsequently changed somewhat under Blender 2.77 (currently Blender 2.77a at the time of this writing).

Here are my new recommendations:


As a reminder, the "quick steps" for weight transfer are as follows:
  • In Object Mode, select the object that will be acting as the source of your weights. This will either be your base avatar model or a piece of clothing that you have already weighted to fit and move perfectly.
  • Hold down the shift key and now select your target object -- the one you want to transfer your source's weights to. This should now display in the 3D View as having both items selected, with the target having a bright orange outline to indicate it's the primary active object of the selection (your source object will have a somewhat duller, redder outline).
  • Switch into Weight Paint Mode and your target object should be the one you see. It will be completely black if you use my recommended option setting to have "Show Zero Weights" set to "Active" (otherwise it should be a dark blue).
  • On the Toolshelf, in the Tools tab, click the Transfer Weights button
  • Immediately after doing so and before doing anything else at all  look at the most recent action settings area and you'll see the "Transfer Mesh Data" options shown in the above image.
Remember that as soon as you take any action you'll lose the ability to change those settings and would have to re-do the transfer.

The data we want to transfer is Vertex Group data, and we want to be creating new data. The "Vertex Map" option is the critical one in terms of how Blender goes about calculating the weights for the new mesh. In the vast majority of cases you will want to use Nearest Face Interpolated since it will typically give you the best starting point for this type of application. It will rarely be perfect, but generally requires a lot less tweaking afterwards than the other methods do. You can refer to the Blender Wiki for details of what each of the methods are and how they go about calculating the resulting data -- they were the same under 2.76.

The part that changed between 2.76 and 2.77 is the options needed for the Source Layer and Destination layer. Under 2.76 they were a bit bugged and confusing whereas now under 2.77 they've been cleaned up and make a lot more sense.

Your Source Layer setting needs to be By Name for a full mesh weight transfer, and your Destination Layer needs to be set to All Layers. Mix mode remains the same and should be set to "Replace" so it overwrites any existing weight group data in the target mesh.

I then strongly recommend following the transfer up with a "Normalize All" and a "Clean" as per my previous tutorial's suggestions.

Happy weighting!

Sunday, 8 May 2016

RELEASE: Paramour Skirt Builder Utility

It gives me pleasure to announce a new release: a flexi-prim skirt-building utility based on the very popular opensource "primskirtbuilder" by Daltonic.


This utility comes about as a request from Isis Ophelia who had a copy of the original SL script and asked whether I could adapt it to work under Opensim. After some rewrites I was able to make it work, although there is currently a bug in Opensim that requires a dialog work-around. This new release is the product of that work and is released under the same GPU license as the original.

The utility is essentially a "super loop-rez" script used to help make flexi-prim skirts. In addition to doing all the nasty math necessary to rez a nice flared circle of prims, this version of it also supplies special control prims to make the creation process even easier.

When you touch or sit on the main controller pad, you will be asked to choose how many prims to use for the skirt, and then rez them. The utility then rezzes the initial skirt as well as two special controller prims. One prim is used to change the shape, size, texture and flexi settings of the skirt's prims, and the other is used to change the shape and arrangements of the prims (the waist width in the x and y directions, the "saddle" shape, and its "poof" angle). When you change a control prim, it is updated immediately for the skirt.

Once you're finished, simply click "link" and the utility assembles and links your finished skirt.

You can pick up a copy for free from my shopping region:

RefugeGrid.com:8002:Paramour Shopping

You'll find it in the central pyramid-shaped building, on the wall with other boxed products.

EDIT:

 
A few people have asked me about good starting parameters if you switch to a cylinder shape. It will depend a bit on what you're making and how many prims you're rezzing but here is a starting point that you might find useful:
  • Size: make the x and y sizes approximately the same...I'll often begin with 0.5m
  • Path Cut: start 0.35 to end 0.65
  • Hollow: 95% (or 99%)
  • Taper: -0.5 to as much as -0.8 for both taper directions

This will give you the traditional arc-inward segments that are used for many flexi-prim skirts.

If you switch back to a cube you'll need to revert those settings back to zero them.
 

Monday, 28 March 2016

Release: "The Dancer" Series 11-16 Statues

This morning I've added the next 6 statue versions corresponding to my "The Dancer" series of renders in G+.

As with the previous ones, these are textured with a slightly cream marble and are full perm to scale or change the base, and you may change the texture to anything else you like.







Note: by Opensim standards these are not particularly light meshes (each statue is about 100k tri  for figure, hair, dress, and plinth combined) and would not be suitable for very high traffic areas. I suggest keeping them phantom, too, and just put an invisible prim cube on top of it if you need to collide with them.

You will find the entire series currently displayed in the eastern pyramid structure at RefugeGrid.com:8002:Paramour Shopping and, as always, they are free.

Enjoy!

Tuesday, 22 March 2016

Release: "The Dancer" Series 06-10 Statues

This afternoon I've added another five statues to the Dancer series in my shopping region, corresponding to the last 5 renders I posted in the album in G+ (#06-#10).






Like the first five, these are marble-textured versions at a resolution that doesn't completely make Opensim explode, though they're not all that light at about 100k tri per.

You'll find all ten statues, free, in the eastern pyramid at RefugeGrid.com:8002:Paramour Shopping

Friday, 18 March 2016

Release: "The Dancer" Series 01-05 Statues

I've recently begun work on a new series of dance renders in Blender -- as anyone who has been following me in G+ will have seen. The response to them has been very positive so I spent some time over the last day or two to make lower resolution versions of each to use as statues in Opensim. Today, I'm releasing the first five of the set.






Caveat: while they're significantly lower resolution than the ones I'm using for my Blender renders, they are not low res by Opensim standards. The combination of figure, hair and dress for each statue is a little under 100k tri and would be unsuitable for higher traffic regions or servers with limited bandwidth. (For the curious, my render versions are well over 3 million quads/6 million tri for each render.)

Each statue is in 3 pieces -- body & hair, dress, and plinth (base) -- and is full perm to scale and texture any way you like. I supply it with a yellowish-white marble.

Body and hair are separate materials zones and could be given different textures/tones. You can unlink and remove the plinth if you'd prefer to use a different one (or none at all). You could remove the dress, too, although the portions of the figure underneath it haven't been tweaked/remodeled/optimized so there could be some unsightly creases or bends that are normally hidden by the dress.

As always, the statues are free and available in my shopping region at RefugeGrid.com:8002:Paramour Shopping. Currently they're inside the pyramid structure that you'll see to your right when you follow the path to the base of the hill from your arrival point. For those who haven't visited before, you'll also discover over 150 other statues scattered throughout the region, in addition to my club items, NPC items, and art painting collection. It's all free.

Enjoy!

Sunday, 21 February 2016

RELEASE: Paramour Polemaster Lite Dancepole

It gives me great pleasure to announce the release of the new "Paramour Polemaster Lite" multi-user dancepole.


This is a reworked version of my regular Polemaster dancepole but designed for very high volume regions (typically clubs) where you want to squeeze every possible bit of performance out of the simulator. By stripping out some features of the regular version and changing a few others, the "Lite" version will now typically use 0 sim resources when not in active use, and then use only 1/20th of the resources when active.It still has all of the core features of the main version...multi-user, synched animations, sequences, etc..

What's Different?

  • All of the key features remain the same as the regular version. The dancepole still has all of the same animations as the regular version (141 of them!), playing in sequence, and supports as many users as you want to try to squeeze onto it (by default it's set to a maximum of 4 dancers but you can go wild and shoehorn dozens on there if you want to). The pole is 100% NPC compatible.
  • The Lite version has been tested works perfectly under both Opensim 0.8.x and the development version of Opensim 0.9 (requires a script setting change to adjust for the different sit target offset).
  • The dialog menu is gone. Some of the controls are still in the script's user settings, but can't be changed on the fly. Others have been removed when they are no longer relevant.
  • Particle effects have all been removed since they incur a simulator load penalty.
  • The main dancepole is a new, single-piece, low-poly mesh with 5 material zones that you can texture any way you want.
  • The cage is a lower poly separate mesh. If you aren't going to display it, simply unlink and delete it so your sim doesn't have to send that data to your visitors. If you might want to change it back to a cage verison on a regular basis, simply make it transparent instead.
  • The 8 little potlights on the base can be hidden or displayed via a setting in the script. In the regular version the individual colour of each is controlled, but that adds to the overhead so in the Lite version they're all always changed to the same colour each time and are a single "face" of the new pole's mesh.
  • Optionally, there's a setting in the script to make the dancepole a colour-changing neon that will match the potlights (if visible). The mount at the base and the ball at the top remain metal (or whatever texture you give them). Making it neon will cause it to use slightly more resources due to the lighting changes necessary.
  • The lighting gantry and 4 spotlights are gone. Instead, there is a separate spotlight object supplied (it's inside the dancepole's inventory) that you can rez and position wherever you want. Then enable the controller script (a setting in the main controller) and the dancepole will change the spotlights' colours too (though of course each spotlight adds a little bit to the load on the sim). If you aren't using them, just disable the setting and it will use no resources at all.
  • If you want to mimic a spotlight effect without the spotlights, there's an optional setting to have the pole itself act as an area light (even if it isn't neon). The effect isn't perfect, though, and it's only a little bit lower in load so in most cases I'd suggest just using a single spotlight instead.
  • The base can be hidden via an optional setting in the script, leaving only the mounting bracket at the base of the pole.
  • Animation and positioning handling were streamlined a little bit to optimize them. Functionally it's identical.
  • By default, when the dancepole isn't in use by someone the lights will freeze at their current colour settings and the script will become dormant, using zero frame time until someone begins to use it, You can change this via a script setting if you prefer to have it continue even when not in use (although it will then use a small amount of sim resources even when not being danced on).
Depending on exact configuration and options, the Lite version uses about 1/20th of the total frame time of the regular version (and the regular version is still quite sim-friendly) during use, and by default uses no resources at all when nobody is dancing on it.

If you want the extra fancy features of the regular one, it continues to be available and fully supported. The Lite version is simply an optional model for high volume clubs (or people who love the neon pole :p).

Where Can I Get It?

As with all my products, the Paramour Polemaster Lite is completely free and distributed under Creative Commons Attribution-Non-Commercial-ShareAlike 4.0 International license.

You can see it in action in one of its configurations in my Hedonism club region (those ones aren't set for sale). Get your own boxed version from my shopping region. Simply do a map search for:
RefugeGrid.com:8002:Paramour Shopping
You'll find it on the wall in the middle of the three pyramid-shaped buildings.

Monday, 15 February 2016

UTILITY SCRIPT: NPC Appearance Sorter

I had a request from someone for a simple script to let you look through NPC appearance notecards to figure out what they were so I wrote this little utility which could be useful for others.

To use it:
  • Rez a prim in a region where NPCs and the necessary OSSL functions are enabled 
  • Add one or more appearance notecards to the prim
  • (Optional) add an animation to the prim -- otherwise the NPC will play the default SL stand.
  • Add a new script and copy the script, below, into it, and save
  • Touch the prim to begin
* * * * * * * COPY EVERYTHING BELOW HERE INTO THE SCRIPT * * * * * * *

// PARAMOUR NPC SORTER
// by Aine Caoimhe (Mata Hari)(c. LACM) February 2016
// Provided under Creative Commons Attribution-Non-Commercial-ShareAlike 4.0 International license.
// Please be sure you read and adhere to the terms of this license: https://creativecommons.org/licenses/by-nc-sa/4.0/
//
// *** THIS SCRIPT REQUIRES (AND WILL ONLY WORK) IN REGIONS WHERE THE SCRIPT OWNER HAS NPC ENABLED AND OSSL FUNCTION PERMISSIONS ***
//
// This is a simple script for previewing a series of NPC appearance notecards.
// The NPC is rezzed and sits on the object containing the script. Using the dialog you can scroll through appearances and (optionally) delete any you don't want.
//
// INSTRUCTIONS
//
// - Place this script in a prim (I use a generic prim sphere)
// - Add appearance notecards to its inventory (names don't matter...just don't add any notecards that aren't appearances)
// - Optional: add one animation to the prim that you want the NPC to play...if you don't, it will use the generic SL "stand" instead
// - Touch the prim and follow the dialog instructions
// - Adding a new appearance notecard or changing the animation inside it requires a script reset to pick up the changes
//
// KNOWN BUG:
// There is a known bug currently in Opensim (I reported it in Sept 2014 http://opensimulator.org/mantis/view.php?id=7325) where NPCs will often not display
// the animation until some time after told to. They will eventually display it if you wait, or you can also trigger it by changing them to a different appearance.
// There are other work-arounds but for this script I kept it simple.
//
// * * * * * * * * *
//  USER SETTINGS
// * * * * * * * * *
integer ownerOnly=TRUE;             // TRUE = only owner can activate it...FALSE = anyone can...I recommend restricting to owner so nobody else can delete any of your notecards
vector sitPos=<0.0, 0.0, 2.0>;      // sit target offset to use..adjust to whatever suits the object
float dialogTimeout=120.0;          // time (in seconds) to wait before removing the dialog listener if no response has been received
integer showFloatyText=TRUE;        // TRUE = display the current appearance name as floaty text above the prim...FALSE = only show it in the dialog menu
vector textColour=<0.0,1.0,0.0>;    // vector colour to use for the floaty text (if being used)
//
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// DON'T CHANGE ANYTHING BELOW THIS LINE UNLESS YOU KNOW WHAT YOU'RE DOING
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
key user;
key npc;
integer myChannel;
integer handle;
string anim;
list appear=[];
integer ind;

showMenu()
{
    handle=llListen(myChannel,"",user,"");
    llSetTimerEvent(dialogTimeout);
    string txtDia="Currently showing: "+llList2String(appear,ind)+"\n("+(string)(ind+1)+" of "+(string)llGetListLength(appear)+")";
    list butDia=["< PREV","DONE","NEXT >"];
    if (npc==NULL_KEY)
    {
        txtDia="\n\nREZ rezzes an NPC";
        butDia=[]+butDia+["REZ"];
    }
    else
    {
        txtDia+="\n\nKILL removes the NPC";
        butDia=[]+butDia+["KILL"];
    }
    txtDia+="\n\nDELETE will delete the current appearance notecard and advance to the next one\n\nGIVE hands you a copy of the appearance notecard";
    butDia=[]+butDia+["DELETE","GIVE"];
    llDialog(user,txtDia,butDia,myChannel);
}
rezNpc()
{
    string show=llList2String(appear,ind);
    if (show=="")
    {
        llRegionSayTo(user,0,"ERROR! There are no apperanaces in inventory!");
        user=NULL_KEY;
        return;
    }
    npc=osNpcCreate("NPC","Model",llGetPos()+<0,0,2>,show,8);   //flag 8 = access perms compatible with both Opensim 0,9 parcel perm changes and all previous Opensim versions
    llSleep(0.25);  // ugly but necessary delay before sitting...give NPC time to register properly
    osNpcSit(npc,llGetKey(),OS_NPC_SIT_NOW);
}
setAppearance()
{
    if (osIsNpc(npc)) osNpcLoadAppearance(npc,llList2String(appear,ind));
    llSetText(llList2String(appear,ind)+"\n("+(string)(ind+1)+" of "+(string)llGetListLength(appear)+")",textColour,(float)showFloatyText);
}
startAnimation()
{
    if (!osIsNpc(npc)) return;
    llSleep(0.25); // need to sleep for 0.25 just to give the sit animation a chance to register, but this may still not be long enough to work around the long-standing Opensim bug
    list anToStop=llGetAnimationList(npc);
    osAvatarPlayAnimation(npc,anim);
    integer stop=llGetListLength(anToStop);
    while (--stop>=0) { osAvatarStopAnimation(npc,llList2String(anToStop,stop));}
}
buildAppear()
{
    appear=[];
    ind = llGetInventoryNumber(INVENTORY_NOTECARD);
    while (--ind>=0) { appear = []+[llGetInventoryName(INVENTORY_NOTECARD,ind)]+appear;}
    if (llGetListLength(appear)) ind=0;
    else ind=-1;
}
default
{
    state_entry()
    {
        if (llGetInventoryNumber(INVENTORY_ANIMATION)>0) anim=llGetInventoryName(INVENTORY_ANIMATION,0);
        else anim="stand";
        llSetClickAction(CLICK_ACTION_TOUCH);
        myChannel=0x80000000 | (integer)("0x"+(string)llGetKey());
        user=NULL_KEY;
        buildAppear();
        if (ind==-1)
        {
            llOwnerSay("WARNING: No appearance notecards found in inventory. Disabling script.");
            return;
        }
        if (sitPos==ZERO_VECTOR) sitPos=<0,0,0.00001>;
        llSitTarget(sitPos,ZERO_ROTATION);
        // if NPC found sitting, make this my NPC
        npc=llAvatarOnSitTarget();
        if (npc!=NULL_KEY)
        {
            if (!osIsNpc(npc))
            {
                llRegionSayTo(npc,0,"Sorry, this item is for NPCs to sit on only");
                llUnSit(npc);
                npc=NULL_KEY;
            }
            else
            {
                setAppearance();
                startAnimation();
            }
        }
    }
    timer()
    {
        llSetTimerEvent(0.0);
        llRegionSayTo(user,0,"Dialog timed out.");
        llListenRemove(handle);
        user=NULL_KEY;
    }
    on_rez(integer foo)
    {
        llResetScript();
    }
    changed(integer change)
    {
        if (change & CHANGED_OWNER) llResetScript();
        else if (change & CHANGED_REGION_START) llResetScript();
    }
    touch_start(integer num)
    {
        key who=llDetectedKey(0);
        if (ownerOnly && (who!=llGetOwner())) llRegionSayTo(who,0,"Sorry, only the owner can use this");
        else if (ind==-1) llRegionSayTo(who,0,"ERROR: no appearance notecards found. Please add some, then reset the script.");
        else if (user!=NULL_KEY)
        {
            if (who==user) showMenu();
            else llRegionSayTo(who,0,"Sorry, this item is already in use.");
        }
        else
        {
            user=who;
            if (npc==NULL_KEY)
            {
                rezNpc();
                startAnimation();
            }
            if (user!=NULL_KEY) showMenu(); // can become null key if no appearance were found in inventory
        }
    }
    listen (integer channel,string name, key who, string message)
    {
        llListenRemove(handle);
        llSetTimerEvent(0.0);
        if (message=="DONE")
        {
            user=NULL_KEY;
            return;
        }
        if (message=="REZ")
        {
            rezNpc();
            if (user==NULL_KEY) return; // user becomes null key when no appearances exist
        }
        else if (message=="KILL")
        {
            if (osIsNpc(npc)) osNpcRemove(npc);
            npc=NULL_KEY;
        }
        else if (message=="GIVE")
        {
            string card=llList2String(appear,ind);
            if ((card=="") || (llGetInventoryType(card)!=INVENTORY_NOTECARD))
            {
                llRegionSayTo(user,0,"ERROR: unable to find the expected card...resetting the script to pick up the necessary inventory changes");
                llResetScript();
                return;
            }
            llRegionSayTo(user,0,"Give you the appearance notecard: "+card+"\nYou will find it in your notecards folder or your suitcase's notecard folder depending on whether you're in your home grid or not");
            llGiveInventory(user,card);
        }
        else if (message=="DELETE")
        {
            string card=llList2String(appear,ind);
            if ((card=="") || (llGetInventoryType(card)!=INVENTORY_NOTECARD))
            {
                llRegionSayTo(user,0,"ERROR: unable to find the expected card...resetting the script to pick up the necessary inventory changes");
                llResetScript();
                return;
            }
            llRemoveInventory(card);
            llRegionSayTo(user,0,"Appearance notecard deleted: "+card);
            appear=[]+llDeleteSubList(appear,ind,ind);
            if (llGetListLength(appear)==0)
            {
                llRegionSayTo(user,0,"There are no more appearance notecards in inventory. Removing NPC (if any) and resetting script");
                if (osIsNpc(npc)) osNpcRemove(npc);
                npc=NULL_KEY;
                llResetScript();
                return;
            }
            if (ind>=llGetListLength(appear)) ind=0;
            setAppearance();
        }
        else
        {
            if (llGetListLength(appear)==1) llRegionSayTo(user,0,"There is only one appearance in inventory...can't change appearance");
            else
            {
                if (message=="< PREV") ind--;
                else if (message=="NEXT >") ind++;
                else
                {
                    llOwnerSay("ERROR! Unexpected menu response: "+message);
                    return;
                }
                if (ind<0) ind=llGetListLength(appear)-1;
                else if (ind>=llGetListLength(appear)) ind=0;
                setAppearance();
            }
        }
        showMenu();
    }
}

Friday, 12 February 2016

RELEASE: Paramour Table Dancer 2.0

I'm happy to announce the release of my Table Dancer 2.0 burlesque table-dancing set which, I think, now completes more than two months of work to make all of my core Paramour products support the changes made to Opensim 0.9 while still keeping them fully compatible with existing 0.8.x grids and regions up to and including the current official 0.8.2.1 version.


The new version of the Table Dancer is a major overhaul of the original:
  • The table is now a "1-prim" mesh object, custom-made to fit the main table-dance sequence and has 5 separate material surfaces, letting you texture it any way you like (using face select in your editor). The original table was a simple 15-prim object.
  • The system is now powered by PMAC 2.0, making it even more efficient than the original custom script and also very easy to add more dances, remove dances, or adjust positions.
  • Includes the same 20-minute looping sequence that was in the original. The table is configured to use this 42-animation sequence by default and plays it using the new auto-sequencing feature.
  • Unlike the original table, you can also stop at any animation to keep playing it...and each animation is self-looping. Then just re-engage auto when you're ready to resume.
  • I also included more than 60 additional animations, grouped into four different (very roughly) sequenced sets. These are animations from my Clubmaster dance ball that are generally of a "burlesque" nature and where the dancer doesn't move too far. They're all pre-positioned to have you dancing on the table top (if you have a very tall avatar you might find that a few don't "fit" you and extend beyond the table).
  • The system is completely compatible with NPCS and works in both Opensim 0.9 and all Opensim 0.8.x regions but requires that OSSL functions are enabled for the owner.
Like all of my products, the Table Dancer 2.0 set is free!

You can pick up a copy from my shopping region at: RefugeGrid.com:8002:Paramour Shopping

Thursday, 11 February 2016

RELEASE: Paramour Country Line Dance Floor v1.1 (Updated)

This morning I updated my Country Line Dancing Floor product to make it compliant with the assorted changes made to Opensim 0.9 and put the new version out in my shopping region. While I was at it, I also made a couple other changes/enhancements. Here's what's new:

  • NPCs are now compatible with the changes made to Opensim 0.9 parcel permissions. If you restrict access to your parcel and are using a build of Opensim 0.9 from January 5, 2016 or later, simply ensure that the line dancing floor is set to the same group as the parcel and NPCs will no longer be evicted. If you use a version of 0.9 prior to that (and possibly some of the short-lived 0.8.3 builds) you will need to set your parcel to public access. Opensim 0.8.x is unaffected and I kept the floor fully compatible with those regions too.
     
  • The change to Opensim 0.9's sit targets was already something the floor could easily be adjusted for, so no update was required for that.
     
  • The floor now includes all of the new NPCs that are in the most recent release of my Paramour Clubmaster danceball system (more than 20 different NPCs now, thanks to community donations!)
     
  • I added a new option to help you figure out which (if any) NPC notecards aren't displaying correctly in your grid. This is common since your grid won't be able to display any NPCs that it doesn't already know all the assets for, so now you can set a "debugNPCS" option to have it show the appearance notecard name as the NPC's name instead. This lets you quickly identify and delete any notecards that can't be displayed in your grid.
     
  • I began using a different per-avatar capsule height adjustment method in the PMAC system which I find is a little better at adapting positions to accommodate different avatar heights. I ported that method into the line dance floor so this should help to keep people's feet a little closer to the ground (although it's never possible to get it exactly perfect).
There are no other changes so there's no great urgency to update your system if you're happy with your current one. If you do, you can just drop the new script into your old one if you've made changes/customizations to it (after also copying over any special settings you need to preserve from your old one).

Just a reminder: you can use this product for any group dancing system where you want everyone nicely arrayed. Just swap out the country line dance animations for whatever dance animations you want to use, set a suitable timer value, and reset the script. You can also add your own NPCs any time you want (without a script reset). You're also perfectly free to change the texture to something else you prefer.

As always, it's free!

You can get it from my shopping region: RefugeGrid.com:8002:Paramour Shopping

Wednesday, 10 February 2016

MAJOR RELEASE: Paramour Multi Animation Controller (PMAC) v2.0 and More!

It gives me great pleasure to announce the simultaneous release of five new products, just in time for Valentine's Day:
  • The next generation of the Paramour Multi-Animation Controller: PMAC 2.0 which is supplied in the same sort of "builder's kit" format as its predecessor. This is a full-featured and highly efficient alternative to systems like MLP and even includes the easy-to-use MLP-to-PMAC conversion script by +Seth Nygard 
  • The new "PAO-NC Multi-Props 2.0" add-on for PMAC that replaces the NC Props 1.x add-on by +Neothar Cortex  and extends its functionality to allow rezzing of multiple props (the original version only supported just a single prop).
  • A new update to my PAO Msg Object add-on that now extends functionality by allowing you to target objects by name instead of UUID if you prefer. You can even use a single message to trigger multiple objects with the same name.
  • A new add-on "PAO Simple Messenger v1.0" which is a variation on the PAO MsgObject add-on.
  • The new "Paramour Chair Dancer 2.0" system, an overhaul of my old version of the product that adds several dozen more animations and is now powered by PMAC2.0
The three updated/new add-ons are included in the PMAC 2.0 Builder's Kit.

To provide full details for each of these would require an enormous blog post so I'll only highlight the most important changes to each. All of them make use of Opensim's OSSL functions so you'll need a region where those are enabled for you.

Paramour Multi-Animation Controller - PMAC 2.0 Builder's Kit

This product contains the core PMAC2.0 system which has all of the features of PMAC 1.0 and then adds a host of new capabilities, most of which I detailed in my recent sneak peek preview post. It also makes the system compatible with the changes made in Opensim 0.9 while preserving compatibility with earlier versions as well.

If you have an existing PMAC 1.0 product you can simply replace the core script and it will work...no additional changes are required.

Here is a quick list of the key changes in the new system:
  • NEW: added a new integrated add-on to (optionally) allow variable auto-timed sequences
  • NEW: added a new integrated set of remote control commands that can be called from another script in the PMAC object or even from a script in a remote prim or HUD
  • NEW/TWEAK: PMAC2.0 now supports more than 9 concurrent users/positions (with a couple minor limitations for more than 12).
  • TWEAK: added a compatibility update for NPCs to allow them to work correctly in Opensim 0.9 parcels with access restrictions while also continuing to fully support them on 0.8.x regions
  • TWEAK: added a new  configuration option to have PMAC be "silent"...effectively shutting it up unless it encounters an error (not that it was chatty before, but now it can be made even less so)
  • NEW: added a new configuration option to indicate whether it's only the owner who can access the new remote control commands
  • TWEAK: a few minor tweaks to improve performance or handle corner cases that could produce unexpected results
  • TWEAK: the configuration notecard data is string-trimmed so it won't generate errors if you accidentally include leading/trailing spaces in your notecard
  • SUPPORT: all PMAC 1.x add-ons that I know of are fully compatible with PMAC 2.0, without any modifications required.
  • NEW: for your convenience, the new builder's kit now includes all existing add-ons that I'm aware of: the MLP-PMAC converter by +Seth Nygard , the Content-Giver by Aaack Aardvark, as well as the series of other add-ons that I have written.
  • NEW: the NC Props 1.x add-on by +Neothar Cortex  has now been updated/replaced with the new PAO-NC Multi-Props 2.0 add-on and is included in the builder's kit.
You can find links to more information and tutorials in the PMAC section of my post list. The full details are included in the product's extensive documentation.

PAO-NC Multi-Props 2.0 Add-On for PMAC

Shortly after the release of PMAC 1.0, +Neothar Cortex  wrote and release his excellent NC Props add-on for the system, allowing an animation to rez a single prop to go along with it. Both he and I have subsequently had requests to expand this add-on's capabilities to allow it to rez and manipulate multiple props so that was on the "to do" list for this release. Neo ran out of time and gave me the go-head to write the update, myself, though obviously I leaned heavily on his previous work since there was no point re-inventing the wheel.

Highlights:
  • This add-on can rez as many props as you want on a per-animation basis.
  • If a subsequent animation uses the prop, it is moved to its new desired location. If not, it is removed.
  • The original NC Props 1.x add-on is fully compatible with PMAC 2.0 so you can continue to use it in all existing systems (but you can't use the Multi-Prop add-on in the same system). There is no need at all to replace an existing one unless you need to rez multiple props.
  • The new PAO-NC Multi-Props add-on will work in all existing systems that are set up to use the NC-Props 1.x add-on. You can remove the old NC Props script and replace it with this new one; but you need to enable a setting in the new add-on's script to allow it to correctly position things due to a difference in the way this is handled. This is a little less efficient than the new method but the difference will probably be almost indistinguishable for most systems.
  • The new add-on has an easy-to-use ability to convert those NC Props positions to the new PAO-NC Multi-Props ones, at which point you can disable the legacy support setting and get the new version's fully efficiency.
  • The new version is (fractionally) faster and more efficient than its predecessor.
  • Like the original version, editing and storing new props positions is child's play!
Specific details on how to use it are included in the product's documentation. This is the version of the script that is included in the PMAC 2.0 Builder's Kit.

PAO Msg Object Add-On v1.1

This is a revised version that extends the functionality of my existing PAO Msg Object add-on. The old version is fully compatible with PMAC 2.0 and you can replace it with the new version with no other changes required (it's fully compatible with existing set-ups). This is the version included in the new PMAC 2.0 builder's kit.

The new version does the same thing as the old except it now allows you to specify the name of an object to send messages to instead of having to supply a UUID. When you do so, the add-on looks for any object within the script's set range (32.0m but you can increase this if needed) and will send it the message. If more than one object is found with that name, it sends it to each of them, so you can use a single command to message multiple objects on a per-animation basis.

When specifying target by UUID the range is unlimited (other than it has to be in the same region, even if it's hundreds of meters away in a large var). When specifying by name there are some limits that Opensim imposes on the range and number of objects it can detect. Those can be overridden in your Opensim.ini file but you should do so with caution.

Details are in the product's documentation.

PAO Simple Messenger Add-On v1.0

This something I developed recently as part of a much larger project I'm working on for +Nara Malone and has much the same general functionality of the PAO Msg Object add-on except it doesn't handle things at a per-animation level.

Instead, you specify a list of one or more targets and, for each, a message you'd like sent to to the target when someone first sits down on a PMAC system, and another message you'd like sent to the target when the last person stands up again and PMAC returns to being dormant. This saves you from having to do per-animation set-ups for systems where you just want a simple on/off type of notification. If you want per-animation messaging, use my other add-on instead.

As with the new version of the PAO Msg Object add-on, you can specify targets either by UUID or name. Doing so by UUID allows it to send the message to an object anywhere within the region -- even a very large var -- whereas specifying a name will limit the range but can send it to multiple objects at the same time (if they all have the same name).

Both methods use osMessageObject() to send the message which raises a dataserver event in whatever script you place in your intended targets. This saves you from having to eat up valuable sim resources by leaving a bunch of listeners open all the time.

Like the PAO Msg Object add-on, this is simply a convenient pre-made extension but will still require you to script the target object(s) to do whatever it is you want it to do when it receives the message. Very basic instructions for the receiver script are included in the documentation but it's assumed you know what you're doing in that regard.

This item is included in the new PMAC 2.0 Builder's Kit and details on how to use it are in its accompanying documentation.

Paramour Chair Dancer 2.0

This replaces the old version of my chair dancer product and I have already posted in somewhat more depth about the new version's differences. The major difference is it now uses the PMAC 2.0 system's auto-sequence capability to make it an extremely efficient item to put in a club setting, makes it a lot more flexible, and also makes it a lot easier to modify or adjust. You can even use an add-on to extend its functionality (for instance, to trigger remote lighting or hand a special prop or outfit to the dancer...the sky's the limit).

 Here's a quick list its key features:
  • simple yet elegant 1-prim mesh chair (full perm so you can texture it any way you want...seat can be textured separately from the legs/back)
  • 4 sequenced sets of chair-dance animations, each with 10-12 animations lasting 5 minutes or more -- more than 20 minutes combined total
  • each animation is also self-looping -- more than 40 animations in all
  • an additional "play all" sequence that combines all 4 sets into a single loop
  • play through a sequence in full automatic or stop at any time to keep playing the current one, then resume...or just pick any one of the 40+ dances to play
  • easy ability to move the entire set-up into a different chair of your preference
  • full NPC-compatibility

Pricing and Availability

All of the above are released under Creative Commons Attribution-Non-Commercial-ShareAlike 4.0 International license and are completely free.

All are available directly from my shopping region (you'll find them in the middle of the 3 pyramid-shaped structures):
HGTP to RefugeGrid.com:8002:Paramour Shopping
You may also redistribute them (in their original boxes, and free) so you'll soon be able to find copies available at Nara's Nook, Metropolis, LFG, OSGrid, GCG, Kitely, and many other places throughout the metaverse.

Several commercial vendors have approached me and been granted license to sell products powered by the PMAC system. If you'd like to do the same, please contact me to discuss the details.

Tuesday, 9 February 2016

Coming soon...Paramour Chair Dancer 2.0

As part of my testing for the upcoming release of the PMAC 2.0 system I need to confirm that all of the newly added features are working as intended. I'm also in the process of trying to update as many of my existing products to be compatible with both Opensim 0.8.x and Opensim 0.9 so I thought I'd kill two birds with one stone and use PMAC's new auto-sequencing capabilities to power the new version of my "Paramour Chair Dancer" product.

Blender Cycles Render

What's Different?


  • Version 1.0 had its own custom script and fixed settings that you couldn't easily change. Version 2.0 will be powered entirely by the new PMAC 2.0 system, giving you the ability to completely control and adjust any positions, rotations, sequence timing, or any other aspect of its operation -- and do almost all of that on the fly with no notecard or script editing required.
  • Version 1.0 had only a single set of 12 animations lasting about 6 minutes. Version 2.0 has 4 different sets, each with between 10 and 12 animations, and each lasting 5-6 minutes. I also did an option to lump them all into a single looping set where it takes just over 20 minutes before it returns to the beginning. There's a slight "bump" in positions as it switches between sets but otherwise looks nice and smooth (and if you don't like the bump you can just play one set at a time). That's more than 40 animations in total!
  • Even though the animations in Version 1.0 were self-looping, you had no ability to stop the sequence. By powering the entire thing with PMAC 2.0 instead, you can now let it run in auto mode; or you can stop it any time to keep looping through the current animation, then re-engage the auto mode to resume the sequence; or you can simply pick any one of the 40+ animations at any time you like.
  • Version 1 used a simple 14-prim chair that I made several years ago and, frankly, doesn't look very good. The new version is a single mesh (1-prim LI) chair that is (IMO) simple and yet much more stylish and elegant. It was created with 2 material zones so you can easily change the texture of the seat or of the legs/back to anything else you like. You can easily scale it any way you want, too, in case it's too small or too large for you (something that's less easy to do with prims).
  • With version 2.0, if you don't like the supplied chair, you can easily just pull out the "guts" and put them into a different chair, then use PMAC's live editing ability to adjust and store new positions that fit the new object. Version 1.0 had just a single "position" and that had to work for all animations (which is why it only ever contained 1 matched set).
  • With version 1 it was possible to wear it as an attachment and use it somewhere else; but of course it was rather difficult to set up, didn't work in any region where scripts weren't enabled, and the unpredictable nature of the script engine meant that sometimes it would fail to release animation control when you detached it. All in all, not a successful idea so that capability was scrapped in version 2.0.
  • Because the new version is powered by PMAC 2.0 it requires a region where the chair owner has sufficient permissions to use the necessary OSSL functions. Version 1.0 used only LSL functions and didn't have this requirement. The new version is more efficient and uses fewer resources, too, so it's better suited to a club environment.

Where Can I Get It?

Right now, nowhere. I will release it at the same time as I finish testing and release the new PMAC 2.0 system so I can ensure that the system inside the chair is identical to the official release version. My testing is going far better than I'd expected so there's a reasonable chance you'll see it on or about Valentine's Day (Feb. 14, 2016). I'll make an official announcement when I do so.

Once released, you'll be able to pick up a copy from my shopping region (HGTP: RefugeGrid.com:8002:Paramour Shopping). As with all of my products, it will be free.

Wednesday, 3 February 2016

SNEAK PEEK: PMAC 2.0

In the last month or so in addition to finishing off the changes to my danceball and testing it, I've also been working on updating PMAC to be compatible with the changes in Opensim 0.9.

While I was at it, I've also added some features that I've either already placed in my own custom systems or are preparatory for some other products I have planned for the coming months.

With the number and scope of these changes it seemed significant enough to warrant a full version number increase rather than a subversion one, so when I finish testing (and documenting) it all, the new version will be released as PMAC 2.0. I don't want to give a firm ETA yet but it will very likely be before the end of February or, failing that, in early March.

In the meantime, I thought I'd give you a sneak peek at what's planned (which might also explain why I'm not releasing other stuff at the moment) and also give a "last call" for any other changes/additions/requests that users might have. If they seem useful and feasible (meet the overall design goals of the system and are something I can do and test within the planned-for release period) I'll try to add them.

CHANGES AT A GLANCE

Here are the quick teasers:
  • wrote a new integrated add-on to (optionally) allow variable auto-timed sequences
  • wrote a new integrated set of quite powerful remote control commands that can be called from another script in the PMAC object or even from a script in a remote prim or HUD
  • PMAC2.0 now has support for more than 9 concurrent users/positions with a couple of minor limitations on functionality
  • added a compatibility update for NPCs to allow them to work correctly in Opensim 0.9 parcels with access restrictions while also continuing to fully support them on 0.8.x regions
  • added a new configuration option to have PMAC be "silent"...effectively shutting it up unless it encounters an error (not that it was chatty before, but now it can be made even less so)
  • added a new configuration option to indicate whether it's only the owner who can access the new remote control commands
  • made a few minor tweaks to improve performance or handle corner cases that could produce unexpected results
  • the configuration notecard data is now string-trimmed when read so it won't generate errors if you accidentally include leading/trailing spaces in your notecard
  • all PMAC 1.x add-ons that I know of (including Seth's, Neo's and Aaack's) are now included inside the builder's kit rather than as separate packs

COMPATIBILITY

All existing PMAC 1.x systems are fully compatible with the new PMAC 2.0 core script with absolutely no changes required. You can simply replace the old core script with the new one and you'll be up and running. All changes are transparent and only represent extra options and controls. The system remains fully compatible with Opensim 0.8.x as well as being fully compatible with the changes to Opensim 0.9 (although you will need to manually adjust/edit positions to move a product back and forth between the two).

I have not and will not build in a global z-axis offset modifier to accommodate the sit target differences between Opensim 0.8.x and Opensim 0.9 due to the detrimental impact it would have on both the PMAC system and simulator performance. A system set up under one would need re-positioning of all animations to work properly on the other but is otherwise fully functional. Please don't complain to me about having to adjust positions...I didn't change the code.

Existing Add-On Compatibility:
  • The four public PMAC 1.x add-ons that I have written are 100% compatible with PMAC 2.0.
  • The MLP-to-PMAC converter script by Seth Nygard is 100% compatible with PMAC 2.0.
  • The NC Props add-on by Neo Cortex is 100% compatible with PMAC 2.0
  • The Content Giver add-on by Aaack Aardvark is 100% compatible with PMAC 2.0
If you use any other add-ons that I'm unaware of, or have made custom modifications to your system, you'll need to consult with their scripters to determine compatibility, but most likely there will be no issues. I took considerable care not to break anything in existing systems.

THE CHANGES IN DETAIL...

NEW: Added a new configuration option "silent" which, if set to TRUE, will only say error messages to chat and all other messages (including quit and user control changes) are silent.

The only things beyond this that it will say are "core" ones such as explaining why a user can't sit, can't activate the controls,  important warnings that are only rarely encountered, etc. or to confirm to the owner on lock/unlock menus.

By default this is set to FALSE. Note that when in use and the system is set to owner-only menus, an attempt by another user to activate the menu will be ignored, silently, without explaination if this option is set.

**********

NEW: Added a new integrated "Auto Set Add-on" directly inside PMAC's Core script that is intended primarily for automated systems where PMAC is configured to be in auto mode and users simply sit while PMAC automates a sequence.

This allows you to have the timer used for advancing animations to be variable and defined at a per-animation level in the group's set-up notecard. Typical applications would be:
  • for certain sequenced club items (the new versions of my Dance Table, Dance Chair, and Dance Stage will all use it; as will a special edition of my Dance Pole)
  • for special sets of animations that are created in sequences (there are several dance and sex ones I've seen that are in a multi-aniamtion extended sequence so this would be ideal for them)
  • for automated, sequenced dance-troop performances or stage shows

This new feature was originally design primarily for use with the other major new feature (remote commands) rather than in general purpose items but was useful enough to make it an internally handled feature.

How it works:

When PMAC is in auto mode, it will check the command block of each animation it plays for the command PMAC_SET_AUTO{f} where "f" is any non-zero positive float value. If found, it will set the autotimer to use this value. NOTE: If a subsequent animation doesn't have a value supplied, it will use whatever the previous animation's timer was, not the system's default (since that value was overridden) so if you plan to use this you'll llikely want to set a time value for each animation in the group.

Example: here's a line from a single-user group of dance animations and will set the autotimer for this animation to 57.5 seconds.

    Dance1|PMAC_SET_AUTO{57.5}|sensual_01|<0.0,0.0,0.4521>,<0,0,0,-1>

If PMAC is not in automode the command is ignored.
Using "SYNCH" does NOT reset the timer.

When auto mode is off and you enable it with "Options > Auto > Auto On" PMAC will check to see if the currently playing animation has a PMAC_SET_AUTO value. If it does, this will be used. If not, it will use whatever the current value of autoTimer is. If you use "Options > Auto > and a value" it will begin by setting the timer to the value you selected, ignoring any value defined for it; however any subsequent animation that has a set timer value will then OVERRIDE the value you set manually.

For example, consider a case where the current animation has PMAC_SET_AUTO{10.0} and the next animation in the notecard has PMAC_SET_AUTO{30.0}

If you start with the autotimer currently off....
    - If you use the dialog menu > Options > Auto > Auto On it will engage auto mode and use the current animation's defined 10 second value for the timer. When it adances to the next animation, the timer will update to the 30 second defined value.

    - If you use the dialog menu > Options > Auto > 120 it will engage auto mode with an intiial value of 120 seconds, so the current animation's value of 10 seconds is ignored and 2 minutes later it will advance to the next animation. When it does so, that animation's preset 30-second value will be used and become the new autotimer value until a different time value is encountered.
   
If you start with the autotimer is currently on....
    - If you select the dialog menu > Options > Auto > 120 it will restart the timer with the 120 second value, and then be updated to 30 seconds by the subsequent animation

The general rule of thumb if you're planning to use this in a PMAC system would be to define auto values for all animations in all groups, or at very least all animations in a single group, and keep in mind that auto value is always maintained at "whatever the last one called was" so it can result in unintended behaviour if your user switches to a different group that doesn't have set values. You might even want to simply restrict menu access to the owner and provide instructions. It all depends on your intended application.

For a general system I wouldn't use this. It's really for automated or remote controlled systems.

***********

NEW: Added a new set of remote commands that PMAC will pay attention to if received via llMessageLinked() or by a dataserver event  from osMessageObject().

These functions are intended primarily for scripting of advanced automated systems where the people seated are passive (usually NPCs, or else avatars who haven't accessed the dialog menu control system) and because of the way the system is designed can ONLY WORK when the current value of PMAC's "user" variable is NULL_KEY or it can lead to errors in subsequent use.

To ensure this doesn't happen, the use of any of these functions except for the synch one will force-set user to NULL_KEY so PMAC will ignore any response they give to an open dialog and that person will need to touch the PMAC object again to become the user once more. While this is slightly inconvenient to a user, it's the only way to make these functions work without breaking the system and, as I say, their intended use is for systems with passive occupants.

Another possible application is custom or stripped-down user menu to replace PMAC's normal one -- one where perhaps you give the owner the full menu and then have PMAC ignore anyone else and present them with a separate menu/dialog for far more limited interaction with the system, using these "hooks" as the method for communicating between your menu handling script and PMAC's main script.

Undoubtledly there are countless other possible applications that I haven't thought of yet. This new command set simply further expands the scope of the powerful integrated core tools available to scripters working with the system.

There are two methods for using the new remote commands feature and you can use either or both. There's no preferred method...both are equally fine and don't conflict with one another:
  • From a script in the same object, using:

    llMessageLinked(LINK_ROOT,-1,command,NULL_KEY);

    ...where command is one of the valid commands below (PMAC ignores any link message where the 2nd field isn't -1)
     
  • Or to use a remote controller (a different prim/linkset/HUD/whatever) you can use osMessageObject() to raise a dataserver event which will react to it:

    osMessageObject(target,command);

    ...where target is the UUId of the root prim of the PMAC object and command is one of the valid commands below

PMAC only expects one command per message so if you need to send several you'll have to do them in a sequence, and if the order they're executed is important you'll need to add some sort of delay between them to allow for potential asynchronous message handling in a busy simulator.

The implementation of this also requires a new PMAC configuration setting "ownerOnlyRemote" which allows you to decide whether to only pay attention to a remote, scripted object with the same owner as the PMAC system.

If the PMAC settings option is ownerOnlyRemote=TRUE, on receiving the osMessageObject() call the system will check the owner of the item sending the message and ignore anything that doesn't come from the same owner as the owner of PMAC system. This protects these commands from potential griefers (although you can achieve the same net effect by disallowing others to use that OSSL function or disallow scripts completely).

This check is NOT PERFORMED if ownerOnlyRemote=FALSE so someone could, potentially, intentionally grief a PMAC system but it would also allow you to distribute a HUD or some other device as part of a more elaborate automated PMAC system...you'll have to evaluate the risks and decide for yourself.

Commands and syntax:

PMAC_REMOTE_QUIT
  • This comand is identical to clicking "QUIT" on PMAC's dialog menu which kills any seated NPCs (even ones that PMAC didn't rez) and unsits any avatars. If the unit is set with the option to reset the script on quit, that will occur as well.
  • This command is silently ignored if PMAC is not in "RUNNING" state (in use and not in edit mode)
    PMAC_REMOTE_SYNCH
  • This command is identical to clicking the "SYNCH" button on PMAC's dialog menu
  • This command is the only one that does not set user to NULL_KEY
  • This command is silently ignored if PMAC is not in "RUNNING" state

PMAC_REMOTE_SWAP|p1|p2
  • This command swaps the two specified positions p1 and p2 more or less the way menu-driven swap works
  • The positions are supplied as 2 integers reflecting the animation positions you want to swap, where position 0 is the first one, 1 is the 2nd, etc... (ie like list indices) so, for example, in a 2-person group you would be using the command PMAC_REMOTE_SWAP|0|1
  • The order you supply them in doesn't matter as long as both are valid
  • Just like the menu-based version, a position doesn't need to be occupied in order to be swapped, and a synch is triggered when it happens (even if both are vacant)
  • If either position isn't valid, the swap will be refused with a warning
  • This command is silently ignored if PMAC is not in "RUNNING" state
PMAC_REMOTE_UNSIT|p
  • This command causes PMAC to unsit the occupant of position "p" if it is occupied or fails silently if it is empty or invalid, much like the menu-driven unsit works
  • The position value is supplied as an integer reflecting the position index you want to unsit, where position 0 is the first one, 1 is the 2nd one, etc...(like list indices) so, for example, to have the occupant of the 1st position stand you would use PMAC_REMOTE_UNSIT|0
  • Unlike the menu-based unsit, if the occupant is a NPC it is NOT REMOVED (killed) so you will need to handle its subsequent removal via an external script
  • This command is silently ignored if PMAC is not in "RUNNING" state
PMAC_REMOTE_AUTO_OFF
  • This command is the same as clicking AUTO-OFF on PMAC's dialog menu and disables auto mode if it was active.
  • This command will work when PMAC is in any state.
PMAC_REMOTE_AUTO_ON or PMAC_REMOTE_AUTO_ON|f
  • Turns on auto-play more or less exactly like using the dialog menu to do it
  • If you include a pipe symbol followed by a float >0.0 the supplied value will be used for the timer (example to turn it on and set the timer to 30 seconds, you would send the command "PMAC_AUTO_ON|30.0").
  •  If use just send the command "PMAC_AUTO_ON" with no timing value, or if the value you've supplied is invalid, PMAC will check to see if there is a custom timer value for the current animation and use that if it finds one
  • Otherwise it will use whatever the current value of the autoTimer variable is (which is whatever value is most recently had, or its default value if it hasn't been used yet since the last script reset)
  • NOTE: just like doing this from the menu, this simply starts the timer and doesn't restart or synch the current animation. The next animation will begin playing afer the timer elapses and if it has a PMAC_SET_AUTO command it will override any timer value you've set.
  • If PMAC is not in "RUNNING" state this function sets (and remembers) the new auto timer value but doesn't activate it. When someone sits to begin using the system, the timer will begin.
    PMAC_REMOTE_SET_GROUP|groupName
  • This command is the same as selecting a group from dialog menu
  • The "groupName" supplied after the pipe symbol must be valid "trimmed" group name or the command is ignored (with error message to owner)
  • A"trimmed" group name is the name without the prefix...example: you would use "dances" as the groupname for the group notecard ".menu012A dances")
  • NO PERMISSION CHECK is performed against the menu's permission settings to see whether the users are allowed to play that group or not; but if someone touches the unit to assume control of it again (to become "user") it will do so and not show a prohibited group.
  • NO USER COUNT CHECK IS PERFORMED prior to attempting to load the group, so if you currently have more users than the new group allows, it will fail on the loadGroup call and potentially generate a script error warning and/or chat warnings...
  • The intended purpose for this is to allow you to change the group remotely either prior to use or when the system is already in use in auto mode.If the item is in use but in manual mode and you change group and then subsequently enable auto mode, it will begin cycling through animations from the newly loaded group, not the old one (which may be what you want it to do anyway).
  • This command works in all PMAC states so if the unit is not currently in use it will set the new group which will be ready and loaded for the next person who uses it.
   
PMAC_REMOTE_SET_ANIMATION|groupName|animationName
  • This is the same effect as manually selecting a specific animation from the dialog except you need to supply both the "trimmed" group name and the animation name within that group that you want to play. If auto mode is enabled when this message is received, it is disabled and NOT subsequently re-enabled so you may need to follow it with a command to turn auto back on that's what you want.
  • The "groupName" portion of this is exactly as per above and there is no permission check done...the group is loaded (if found) and then the animation check is made
  • The animation name is the one used as the first field in the notecard's line
  • If no animation can be found by that name the command is ignored but PMAC's current group will have changed to the one specified during the call so this could potentially cause serious problems for subsequent operation so the system is placed into error state until it is reset. For this reason the error is said to local chat and quit is triggered as well.
  • If you're using this function, TEST YOUR SET-UP CAREFULLY AND THOROUGHLY to make sure it works before you distribute it. Note that this is only a potentially severe issue if the group exists but the animation name doesn't...if the group is invalid or missing it will simply ignore the command with a minor error warning to the owner but continue to work properly in all other respects.
  • This command works in all states so you can remotely pre-select the first animation that will play when someone first sits down and activates the system

None of the above give any sort of confirmation notices or feedback to the script that calls them but many (all?) will trigger a standard PMAC global link message of one type or another if successful. You can then use that passed data to detect and confirm the intended effect.
   
REMEMBER: using one of these commands sets the current user (if any) to NULL_KEY so if you've made any customizations to PMAC where the "user" variable is important you'll need to adapt it to test for non-null user.

***********

NEW: PMAC 2.0 now PARTIALLY supports as many concurrent users as you want via a small change in way it pulls the number of positions from the menu notecards. Now the format is:

    .menu[ss][n...][p] Groupname

Where:
    - as before, the group notecard name must begin with the string ".menu"
    - this must be followed by exactly 2 characters that are only used for to help you sort the group order
    - NEW!!!! this can now be followed by either a single-digit or 2-digit (or even 3-digit or more!) integer to indicate the number of positions
    - the final character must be either "A" or "G" or "O" to indicate whether the group permission is all, group or owner
    - followed by a space
    - followed by the name of the group (which must be a unique name)

During initialization, PMAC now checks the length of this intial string when building its internal lists so all of the following names would all be valid
    .menu031A Just Me            PMAC reads the number of positions as "1" = 1
    .menu0301A Just Me            PMAC reads the number of positions as "01" = 1
    .menu03001A Just Me            PMAC reads the number of posistions as "001" = 1
    .menu0118A Pile ONLY        PMAC reads the number of positions as "18" = 18 positions!

All of your existing group notecard names are still fully valid and require no changes at all to remain compatible with PMAC 2.0. This simply now permits a system to be configured to handle as many avatars/NPCs as your region can manage.

LIMITATIONS:
The only MAJOR limitation is that if you have more than 11 positions you will not be able to fully use PMAC's native swap or unsit features because their menus are limited to a single page. This means you'd never be able to swap or unsit someone for some of the higher positions. You *CAN* still do this using the external remote commands and an external controller script, but because this is really such a special case it isn't (and won't be) directly from within PMAC's native dialogs. For that many users you will probably need to be using an external controller for that sort of thing anyway.

There are a few additional practicalities of Opensim that still limit the number of positions:
  • The maximum contents of a notecard is 64k so if you had 100 positions per animation you'd be severely limited in the number of different ones you can have in the group
  • The maximum number of agents that a viewer will display before "impostering" is currently 65 and most people have this value set far lower; so it's somewhat impractical to have a huge number of positions
  • The time required to update positions and change animations increases as the number of avatars increases. I have tested it successfully with 20 concurrent avatars/NPCs and they remain in synch in my test region, but this is likely to be less accurate as the numbers increase or if there are a large number of avatars in the region already placing it under stress
  • The memory available to scripts is also limited...the more positions and users that have to be tracked, the closer PMAC will get to this limit (although it's unlikely to actually surpass it until you have far more agents than the region can handle)
  • Editing positions for a huge number of avatars would be something of a nightmare. Handles will be rezzed alternating through the colours you supply for them but, even so, that's a lot of bodies to move around...have fun if you try it!

***********

TWEAK: reformatted large portions of the core script to reduce total character usage since the newly added portions were pushing it very close to the max script character limit. I tried to do it in such a way as to keep it fairly easy for other scripters to read and follow (making it easier to script your own custom mods) so it isn't pruned as much as it could be.***********

***********

TWEAK: When reading the configuration notecard (if any) the variable names and supplied values are string-trimmed to remove leading and trailing spaces so it won't generate errors if you accidentally include one.

***********

TWEAK: Changed handling of the corner case where you are in manual mode, select a different group, then enable auto mode without selecting an animation from the new group. Previously, when the timer triggers it would say a warning to chat and disable auto mode. Now it will play the 1st animation of the newly selected group instead without warnings.

***********

TWEAK: Made a slight modification to the nc_props script by Neo Cortex that goes inside objects that are to be rezzed by his props add-on. The script is disabled if the item is worn (so it won't generate an error message when you wear the builder's kit giver object) and now if an item is rezzed manually to the ground instead of by PMAC it will say a warning to chat instead of generating a script error message due to attempting to send a message to a NULL_KEY object.

The new version of this script is now called "nc_props 1.1.1". You can safely leave the old version of the script in any existing objects and it will work fine...this is just a "tidying up" bit of housekeeping.

***********

TWEAK/COMPATIBILITY FIX: To make PMAC compatible with the changes to Opensim 0.9, NPCs are now rezzed with the creation flag value 8 to allow them to enter parcels where access permissions are restricted. You will still need to ensure that the PMAC object is set to the same group as the allowed group so the NPC is rezzed with the correct group assignment. The actual integer value 8 is used instead of the named constant in order to allow PMAC to remain compatible with Opensim 0.8.x and earlier.

***********

WILL NOT FIX: I will not add any sort of global z-axis offset modifier to accommodate the changes in sit target handling in Opensim 0.9 because it adds a significant number of additional calculation steps per animation call that will impair the performance of the PMAC system and increase its load on the region. Further, in position edit mode the tracking/following system for the handles will behave very slightly differently (there will be an odd offset between handle position and avatar position and rotations might appear to occur on a slightly offset axis) but will still work correctly in terms of storing and later playing back the new positions and rotations. Changing the editing system to correct for this would also involve too many additional calculation steps to be viable without it feeling unresponsive or laggy while you're trying to work with it.

Any system created and configured for Opensim 0.8.x or earlier will continue to work perfectly but will need to have all animation positions redone to alter them for correct positioning under Opensim 0.9.

Similarly, new systems created under Opensim 0.9 will work perfectly there, but will need to have the positions for all animations redone for correct positioning to be used in a region running Opensim 0.8.x.

You could write a custom script to do the position changes automatically for your notecards; or make separate versions of your systems for users of each; or you could appeal to the Opensim developers to revisit the decision to break all existing sit targets. I simply can't justify reducing PMAC's performance or increasing its load on a region to accommodate changes made to core.

PLANNED PRODUCTS

These advances in the PMAC 2.0 system will allow it to work as the core controller for a variety of new products beyond the ones that you'd typically think of, and do so extremely efficiently. Products that I plan to release in the coming months for which PMAC 2.0 will be the core hanlder:
  • A special storytelling/presentation system being developed in conjunction with Nara Malone as a tool for the next Hypergrid Story project. This will leverage all of the new and existing "power tools" in the PMAC core product and several of the add-ons; but be almost invisible to the user. ETA on this is late spring or more likey sometime in the summer of 2016.
  • An updated version of my "Paramour Table Dancer" product with a single automated dance sequence that lasts more than 30 minutes before it loops back to the beginning. ETA April 2016.
  • An updated and greatly expanded version of my "Paramour Chair Dancer" product with several different animations sequences lasting between 5 and 10 minutes each before looping. ETA May 2016.
  • Several other longer term projects that aren't yet sufficiently developed to announce.