QUICKSTART WITH SF POSER
You can get the SFposer package from the opensimworld region: https://opensimworld.com/hop/74730
The package contains an empty SFposer Template.
- Rez the template and add your animations in its contents
- Click on it and select OPTIONS->New Menu to create a new poses menu. A new empty pose (Pose1) will automatically be added to the new menu
- Click OPTIONS -> EDIT POSE to adjust the pose. The positioning handles will appear.
- Touch each handle to select an animation from inventory
- Move the handles to position the avatars
- When done, click Save Pose, and then Save Menu
Congratulations, you just created your first menu card and pose!
- To add more poses, click Options -> Edit Pose -> New Pose and repeat
MENUS AND POSES
A POSE is a set of avatars playing animations in specific positions. SFposer organizes the poses in MENUS (groups of poses), and each of the menus is saved in a separate notecard inside the object. Each menu notecard line describes one POSE, and all the poses in the menu support the same maximum number of avatars. The notecards are automatically created and saved by SFposer, but you will need to edit the notecards to add Shortcodes, which provide additional functionality.
To add a shortcode to a pose, insert it in the specially reserved second column of the .menu notecards, right after the pose name. The column is usually occupied with "NO COM" or "NOCODE". Replace those with your shortcode(s):
Dance Together2|NO COM|danceLeft2|...
Dance Together|EXPR{smile;3;smile;4} SAY{Hello!} SAY{Hello again}|danceLeft|...
Dance Together3|SHORTCODE_GOES_HERE|danceLeft3|...
You can add multiple shortcodes{} simply separating them with spaces
There is additionally a configuration notecard for SFposer named '.SFconfig' where you can also add shortcodes, one per line (more on this later)
A shortcode{} can be executed via a button in the OPTIONS menu. To create a button, add a Button line in the .SFconfig notecard as follows:
Button=ButtonLabel=SHORTCODE{arg1;arg2;arg3}
After editing notecards, you need to stand up and sit again, to force the script to reset and reload them.
EXPR{expression1;repeatTime1;expression2;repeatTime2;expression3;repeatTime3 ... and so on for every avatar of the pose}
WatchMovie|EXPR{laugh_emote;4;open_mouth;3;frown;0}|chair_sit|<0.2112.... [the rest of the pose line]
If you wish to use a custom expression animation (e.g. a bento animation called bentoanim), you need to add the animation inside the SFposer object and rename it to "express_bentoanim". You can then use it as: EXPR{bento_anim;3}
Add the following Shortcode to a pose to rez the prop:
PROP{MyProp;<1,1,1>;<0,0,0,1>}
This will rez MyProp at position <1,1,1> and rotation <0,0,0,1> relative to the object. You do not need to edit the position and rotation manually instead you can position the props correctly by editing the pose (read below).
If you need to rez multiple props, add multiple PROP{} shortcodes, separating them by space: PROP{Prop1... } PROP{Prop2...} PROP{Prop3...} ....
Sit and re-sit on the SFposer to reload the notecards, and then select the pose again. The prop should rez in the position <1,1,1>, as instructed.
Now, edit the prop to position it to its final position, and then select Options -> Edit Pose -> Save Pose. The system will save the new PROP{} positions and also print them out in local chat.
Additional shortcodes for props are supported. You can use them to create Buttons that rez/derez props:
TOGGLEPROP{MyProp;<1,1,1>;<0,0,0,1>}
When the button is pressed, it rezzes the prop, when pressed again, it deletes it.
DELPROP{MyProp}
Deletes the prop
For example, you can define a rez/unrez button in the .SFconfig notecard as follows:
Button=Rez/Unrez=TOGGLEPROP{MyProp;<1,1,1>;<0,0,0,1>}
(remember to re-sit in order to reload the card)
Attachment Props: You can use the "SFposer attachment prop script" (get it here) to create props that auto-attach to a user (for example, a gym bench could use them to attach dumbbells to the sitter's hands). Use the following procedure to create attachment prop shortcodes:
- Wear the attachment, adjust it to its final position and add the "SFposer Attachment Prop script" inside it.
- RESET THE SCRIPTS in the attachment to record its position
- Detach the attachment, add it in the contents of the SFposer object, make it full permissions, and give it a name (e.g. MyProp)
Add the following shortcode to a pose to rez the prop and requests to attach to avatar sitting at position 0 (first avatar)
PROPATT{MyProp;0}
When you select that pose, the attachment prop will be rezzed and will request to attach to avatar at position 0 (the first avatar).
If instead you wish to attach the prop to the avatar that is currently using the menu, use the PROP{} shortcode:
PROP{MyProp;<0,0,0>;<0,0,0,1>}
Attachment props are not detached when switching positions, they will detach when you stand up.
Note that Attachment props are temporary and cannot be detached by right clicking, instead the user will have to click on them to detach.
RLV SUPPORT
SFPoser has built-in support for RLV and uses shortcodes to implement it.
Add the following lines to your .SFconfig notecard to create an "RLV Capture" and an "RLV Release" button:
Button=RLV Capture=RLVCAPTURE{20}
Button=RLV Release=RLVRELEASE{}
RLVCAPTURE{20} indicates that 20 is the maximum distance (in meters) within which to search for avatars to capture.
RLVRELEASE{} does not have any arguments
You can send RLV commands at specific poses with the RLV{} shortcode:
RLV{avatarNumber; @rlvCommand1 ; @rlvCommand2; @rlvCommand3 ... }
avatarNumber is the position of the avatar (0 is the first avatar). You can send multiple RLV commands with a single RLV{} shortcode, but remember to separate them with ';'
RLV support works with osCollar 7. You can read more about the RLV protocol here.
Button=Get Popcorn=GIVE{Popcorn}
You can use the shortcode ADDNPC{firstname lastname} in .SFconfig to rez NPCs during startup or after region restart.
You can also use the shortcodes ADDNPC{..} and DELNPC{..} in poses.
LG{0;rightwrist;rightHook}
UseCableMachine| LG{0;rightwrist life 1;righthook} LG{0;leftwrist life 1;lefthook} |cables|<1.3282,1.8789,0.8556>|<0.0001,-0.0002,0,1.>
Button=All Laugh=ANIM{express_laugh;express_laugh;express_laugh}
Button=Stop Laugh=STOPANIM{express_laugh;express_laugh;express_laugh}
autoTimer=60
You can change the auto-timer for individual poses with the shortcode TIMER{50}, which will set the animation timer every 50 seconds.Use TIMER{0} to stop the auto-timer.
PROP{MyProp;<1,0,0>;<0,0,0,1>} ANIM{clap;clap;clap;clap}
Button=MyButtonLabel=PROP{MyProp;<1,0,0>;<0,0,0,1>} ANIM{clap;clap;clap;clap}
ADDITIONAL SHORTCODES
MSGPROP{MyProp;Hello, prop}
Sends the dataserver message "Hello, prop" to the already-rezzed prop MyProp using osMessageObject()MSGATT{0;Hello, avatar1 attachment;19,4}
Sends the dataserver message "Hello, avatar1 attachment" to the attachments attached on attach points 19 or 4 of the avatar sitting on position 0 of the pose (first position) using osMessageAttachments(). You can read more on the documentation of osMessageAttachment online . You have to use the numeric codes for the attachment points. Click here to view the full list of attachment point numbers.MSGOBJ{<object-uuid>;Hello object}
Sends the dataserver message "Hello object" to the object with UUID <object-uuid> using osMessageObject(). This can be used to send shortcodes to another SFposer, however you will have to replace the '{' and '}' characters with '[' and ']' in the shortcodes for this to work. For example, to change the pose in another sfposer object:
MSGOBJ{<target-object-uuid>; SAY[Changing pose] SWITCHTOPOSE[MyPose]}
MSGLINK{4;Hello link number 4}
Uses osMessageObject to send the dataserver message "Hello link number 4" to the linked prim at link number 4SAYCH{21;Hello, channel 21}
Uses llSay() to say the string "Hello, channel 21" to the local chat channel 21. The string can contain the special codes %USER00, %USER01, %USER02 etc which are replaced witht the name of the avatar sitting at position 1, position 2 etc. An example: SAYCH{0; The user %USER00 is sitting with %USER01} SAY{Hello public channel}
Same as SAYCH, but for the local chat (channel 0)
REGIONSAY{21; Hello channel 21 in the whole region}
Like SAYCH, but region-wide
USAY{Hello dialog user}
Say something to the user currently using the dialog
LINKMSG{-1;99;Hello, all prims}
Invokes llMessageLinked(-1,99, "Hello, all prims" , <list-of-avatarIds> ) to send a link message. Note that LINK_SET = -1, LINK_THIS=-4TRIGGERSND{My sound}
Play the sound "My sound" using llTriggerSound
PLAYSND{My sound}
Play the sound "My sound" with llPlaySound
LOOPSND{My sound}
Start playing a sound loop with sound "my sound"
STOPSND{}
Stop playing sounds
SLEEP{0.5}
Add a delay (sleep) for 0.5 seconds
Changing linked prim properties on the fly
SHOW{MyChildPrim; <1 or 0>}
Show or hide the child prim named MyChildPrim (1 = show). This changes the child prim's opacity
SETPRIM{MyPrimName; <specially-encoded-list> }
This shortcode can be used to change the properties of the linked prim(s) named "MyPrimName" using the list of prim properties as in llSetPrimitiveParams(). It is essentially a way to call llSetLinkPrimitiveParams() without adding another script in the object. To use this shortcode, you must encode the list of parameters to llSetLinkPrimitiveParams() in a special format that can be pasted into the notecard. Use the script "SFposer encoder for SETPRIM" (link at the end of this page) to generate the shortcode.
Example: Changing the color of a child prim named MyPrim and making it transparent
The LSL list for llSetPrimitiveParams() would be [PRIM_COLOR, ALL_SIDES, <1,1,1>, 0.0]. Using the shortcode encoder script, it prints out in local chat the SETPRIM shortcode containing the encoded version of this list:
SETPRIM{MyPrim; I;18;I;-1;V;<1,1,1>;F;0.0}
Creating particle effects
Similar to SETPRIM, SETPARTICLES{} is used to set the particle system in any named prim in the link set.
SETPARTICLES{MyPrimName; <specially-encoded-list> }
The parameters list to be passed to llLinkParticleSystem() must be a specially-encoded encoded with the same script as above, but remember to replace SETPRIM with SETPARTICLES in the output of the script.
Presets of shortcodes
Presets are shortcodes that are shortcuts (macros) to execute multiple other shortcodes. Presets are defined in .SFconfig. The syntax for defining a Preset is:
Preset = MyPreset = SHOW{myPriml;1} TRIGGERSND{bang}
This defines the preset "MyCommand" as the series of shortcodes SHOW and TRIGGERSND
To use a Preset, invoke the PRESET{} shortcode in a pose line or a Button line:
PRESET{MyPreset}
Presets can be used to group together shortcodes that are shared by multiple poses. For example, a Shower object may contain poses that with water running and and others that don't. The two preset states (WaterOn and WaterOff) could be defined in .SFconfig as follows:
Preset = WaterOn = LOOPSND{watersound} SETPARTICLES{ShowerHead; <encoded list>}
Preset = WaterOff = STOPSND{} SETPARTICLES{ShowerHead;;}
Individual poses could be configured to use the presets as follows:
Pre Shower| PRESET{WaterOff} |<1,2,3>....
Shower| PRESET{WaterOn} |<1,2,3>....
AfterShower| PRESET{WaterOff} |<1,2,3>....
When switching between poses that use the same preset, the preset will not be restarted, instead it will continue running. If you explicitly want a preset to be restarted, add another, empty PRESET{} code before:
PRESET{} PRESET{WaterOn}
Creating Sequences
Using shortcodes and timers, it is possible to play animations in a menu as a sequence of poses. Use the TIMER{} code to set the duration of each pose, and use Shortcodes or Presets to add effects such as props, sounds etc. to each pose. To prevent looping the whole sequence, use TIMER{0} at the last pose.
This example menu notecard contains a sequence for a boxing match:
Warmup| TIMER{30} SAY{%USER00 is preparing to fight %USER01} | prepare1| <0.012....
Fight | TIMER{30} PRESET{Fighting} SAY{Fight!} | fight1 | <0.012....
Victory| TIMER{0} TRIGGERSND{victory} SAY{%USER00 won! } | victory1 | <0.012....
Any shortcode can be added to an add-on button in the OPTIONS menu with the Button option in .SFconfig:
Button=My Button=SAYCH{0; Hello,world}
Running shortcodes on every script reset in .SFconfig
You can execute shortcodes in .SFconfig which will be executed every time SFposer is reset (whenever everyone stands up). Add the shortcode on a single line by itself . This can be used for example to change the properties of prims when the system is reset using SETPRIM{}, to rez NPCs etc.
llMessageLinked(LINK_THIS, -1, "SHORTCODE{...}", NULL_KEY);
To send through dataserver messages, use:
osMessageObject("<SFposer object UUID>", "SHORTCODE{...}");
allowRemote=0 Only sitting avatars can use the menus, the object does not accept dataserver commands
allowRemote=1 All avatars, sitting or not, can touch the object to use the menus, the object does not accept dataserver commands
allowRemote=2 Only sitting avatars can use the menus, and the object accepts dataserver commands
allowRemote=3 All avatars, sitting or not, can use the menus, and the object accepts dataserver commands
allowRemote=4 Disable all menu dialogs, and the object accepts dataserver commands. Use this in case you want to control SFposer remotely-only, in which case SFposer will not generate any dialog when touched. This is useful if you want to host SFposer and another menu-driven script in the same root prim.
In order to allow changing poses and animation menus remotely, the following shortcodes are available for remote operation:
SWITCHTOMENU{My Menu} Switches to the animation menu "My Menu"
SWITCHTOPOSE{My Posename} Switches to the pose "My Posename" which must be in the currently selected animation menu.
UNSIT{<avatarNumber>} Unsits the avatar in position <avatarNumber> (first position is 0)
ADDNPC{firstname lastname} Adds an NPC from the inventory
DELNPC{firstname lastname} Deletes the NPC
SWAP{pos1; pos2} Swaps the users in pos1 and pos2 (first position is 0)
It is possible to use the API to add Buttons to the OPTIONS menu. In this case, instead of a shortcode, the message sent to SFposer has the same format as the .SFconfig configuration line for creating a button:
osMessageObject("<object-uuid>", "Button=Say Hi=SAY{Hello, world}" );
For deleting a button from the OPTIONS menu, there is the shortcode DELBUTTON{}:
DELBUTTON{Help me}
e.g. osMessageObject("<object-uuid>", "DELBUTTON{Say Hi}" );
Buttons with arbitrary-string codes can also be created. This is meant to be used for sending messages to other scripts. The syntax is:
Button = Send code = MyCodeIsHere
When pressed, the button will send a link_message as follows:
llMessageLinked(LINK_THIS, 0, "MyCodeIsHere|<current-user-uuid>", "<uuid1>|<uuid2>|...");
The API command GETSTATUS can be used to retrieve the current state of the SFposer object. Send the string GETSTATUS through dataserver or link_message to retrieve the status (Note this is not a shortcode so {} are not added):
llMessageLinked(LINK_ROOT, -1, "GETSTATUS", ""); or osMessageObject("<sfposer-uuid>" , "GETSTATUS");
SFposer will respond a link_message or dataserver message respectively, with a string containing the current state of sfposer:
osMessageObject("<sender-uuid>", "SFSTATUS|<current-menu-user-uuid>|<current-menu-name>|<current-pose-name>|<auto-timer>|<internal status>|<current-pose-shortcodes>|<user1-uuid>,<user2-uuid>,<user3-uuid>...");
EVENTS
SFposer sends link_message notifications to the root prim for any significant event. You can listen to those events by creating addon scripts. The names of the link_message events are the same as the ones used by PMAC.
This is the list of events that are sent:
GLOBAL_ANIMATION_SYNCH_CALLED
GLOBAL_NEXT_AN
GLOBAL_NEW_USER_ASSUMED_CONTROL
GLOBAL_SYSTEM_RESET
GLOBAL_START_USING
GLOBAL_USER_SAT
GLOBAL_USER_STOOD
GLOBAL_SYSTEM_GOING_DORMANT
GLOBAL_NOTICE_ENTERING_EDIT_MODE
GLOBAL_NOTICE_LEAVING_EDIT_MODE
GLOBAL_STORE_ADDON_NOTICE
GLOBAL_EDIT_STORE_TO_CARD
Look into the source code to see the arguments sent with each event. The events are sent via llMessageLinked() to LINK_THIS (the root object), with numeric Value=0. The 'key' argument is replaced with a concatenated list of the currently sitting avatar uuids (Just like PMAC). An example of the event messages sent out is:
llMessageLinked( LINK_THIS, 0, "GLOBAL_USER_SAT|0|1111-111-111", "111-111-111|000-000-000|000-000-000" );
Triggering Shortcodes with Event Filters
You can define Shortcodes that will be triggered automatically when an event matches a pattern using OnEvent configuration lines.
The Event filters are defined in the .SFconfig notecard as follows:
OnEvent = <Event filter> = SHORTCODE{} SHORTCODE2{} ...
<Event filter> is replaced with the part of the of the event string that is to be matched.
Example: When the first user sits on the object , SFposer emits the event "GLOBAL_USER_SAT|0|<user-uuid>"
The following OnEvent filter matches the substring "GLOBAL_USER_SAT|0", and triggers the shortcode SAYCH:
OnEvent = GLOBAL_USER_SAT|0 = SAYCH{0; Hello, first user}
The different events contain different kinds of information in their event strings. It is possible for example, to use the the event string to trigger a shortcode when a specific avatar position is being filled or emptied. It is also possible to trigger a shortcode when a specific user-id sits on the object. Examples:
OnEvent = GLOBAL_USER_STOOD|3 = SAYCH{0; Goodbye, user 3}
OnEvent = GLOBAL_USER_SAT|0|2ae39a9c-13 = SAY{Hello, %USER00, i recognized you sitting in first position}
OnEvent = GLOBAL_SYSTEM_GOING_DORMANT = SAY{Thanks for using me}
LIST OF .SFconfig NOTECARD OPTIONS
The following configuration options are supported in the .SFconfig notecard:
allowRemote= 0 or 1, 2,3,4 . Controls who can access the menus. See above for details
autoTimer=90 Set the auto-timer (seconds)
defaultGroup=Sit Name of the default menu when a user first sits in the object
adjusterStep=0.03 Set the adjustment step (in meters) for the ADJUST menu (X-, X+ etc)
mainMenuTitle=Hello users Set a custom message to show in the MENUS dialog instead of the default
autoSwitchGroup=1 Automagically switch to a bigger or smaller size animation menu when more people sit on the object or when they stand up. The system will switch to the first available animation menu that can accomodate the number of sitters
autoSwitchGroup=2 Same as above, except that when an avatar stands up, SFposer will NOT switch to a smaller menu.
showDialogOnSit=1 Automatically show the menu dialog as soon as the first user sits
showMenusOnStart=1 When first showing the dialog, show the list of Menus first, rather than the list of poses
showOptionsAgain=1 Show the Options dialog again after selecting an option from the Options menu instead of dismissing it. The user will have to click ignore to dismiss
allowSoloNpc=0 This forces the system to remove the rezzed NPCs when all humans have stood up (default is 1)
offsetPos = <x,y,z> Move all poses by the vector <x,y,z> , i.e. add a global position offset to all positions
offsetRot = <x,y,z> Rotate all the poses by the euler vector <x,y,z> (in *degrees*), i.e. add a global rotation to all positions
lockMenus=A Unlocked menus to all users (the default). Other options:
lockMenus=O Lock all menus to owner only
lockMenus=G Lock all menus to users who have activated the same group as the object
lockMenus=S Lock all menus until the owner has seated
lockSit=A Everyone can sit (the default). Other options:
lockSit=O Only the owner can sit
lockSit=G Only members of the same group can sit
lockSit=S The owner must sit first before other users can sit
Preset=Dumbbell=PROP{dumbbell;<0,0,0>;<0,0,0,1>} Creates a preset (shortcut to a series of shortcodes) that can be used in poses (See above)
Button=Hello=SAY{Hello} SAY{Hello again} Creates a button in the OPTIONS menu that executes shortcodes (See above)
OnEvent=GLOBAL_SYSTEM_GOING_DORMANT=SAY{Bye} Creates an event filter (See above)
In addition any number of shortcodes can be added to the .SFconfig notecard , one at a line. They will be executed every time the script is reset
Allow_osGetNotecard = true
Allow_osMessageObject = true
Allow_osMessageAttachments = ESTATE_OWNER,ESTATE_MANAGER,PARCEL_OWNER
Allow_osAvatarPlayAnimation = ESTATE_OWNER,ESTATE_MANAGER,PARCEL_OWNER
Allow_osAvatarStopAnimation = ESTATE_OWNER,ESTATE_MANAGER,PARCEL_OWNER
Allow_osMakeNotecard = ESTATE_OWNER,ESTATE_MANAGER,PARCEL_OWNER
Allow_osNpcCreate = ESTATE_OWNER,ESTATE_MANAGER,PARCEL_OWNER
Allow_osNpcRemove = ESTATE_OWNER,ESTATE_MANAGER,PARCEL_OWNER
Allow_osNpcSit = ESTATE_OWNER,ESTATE_MANAGER,PARCEL_OWNER
Allow_osSetPrimitiveParams = ESTATE_OWNER,ESTATE_MANAGER,PARCEL_OWNER
.menu0005A Dance Together
where
.menu : All pose notecards must begin with .menu
00: Used for ordering of menus. Can be between 00-99
05: Means this menu notecard contains poses for 5 avatars
A: Menu is for use by (A)ll. Can also be (G)roup or (O)owner, or (S) in which case the owner must sit first before the menu can be accessed by other users
Dance Together: The label shown in the button is "Dance Together"
- Thanks to Aaack Aardvark @ osgrid for beta testing
File name | Added By | Last Updated | Actions |
---|---|---|---|
1. SFposer MAIN SCRIPT v 0.91112 | OpenSimWorld✔ | 5 months ago | View |
2. SFposer Prop Script | OpenSimWorld✔ | 3 years ago | View |
3. SFposer Attachment Prop script | OpenSimWorld✔ | 4 years ago | View |
4. SFposer encoder for SETPRIM shortcodes | OpenSimWorld✔ | 3 years ago | View |
5.1 Copy Missing Animations - TARGET object | OpenSimWorld✔ | 5 months ago | View |
5.2 Copy Missing Animations - SOURCE object | OpenSimWorld✔ | 5 months ago | View |
6. Remove unused animations | OpenSimWorld✔ | 4 years ago | View |
7. Auto-Upgrader for SFposer | OpenSimWorld✔ | 4 years ago | View |
8. Example HUD script | OpenSimWorld✔ | 2 years ago | View |
9. Example Appearance Clone script | OpenSimWorld✔ | 5 months ago | View |