Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Library: Simple Avie Positioner

Katherine Taney
KC Owner
Join date: 11 Jul 2006
Posts: 14
01-20-2008 01:47
Hey all, I thought I'd release this bit of coding since I've found so much help on these forums.

Basically, this simplifies avie placement when using PrimParams without a poseball. Sometimes it's a headache figuring out the rotation and position when the prim is rotated oddly, so this script let's you move and rotate the avie in real time, then hard-code the final vectors into the sitscript.

Basic instuctions: place the generic sitscript and the positioner script into the object. Sit on the object and use the movement keys to position the avie. Use the touch menu to report the new offsets, then paste these vectors into the sit script. Then delete the positioner script. The touch menu also changes the movement coordinates, and movement rate.

Generic SitScript:
CODE

//This script was written by Katherine Taney, it is free to use, modify, give away, etc....
//Please give credit and stuffs, stealing is wrong and bad and stuffs....

InitUserVariables() {
//---START USER VARIABLES---\\

//Enter values from pistioner script here -->
SIT_POSITION = (vector) <0,0,0>;//position relative to the poseball
SIT_ROTATION = (vector) <0,0,0>; //Edit this, rotation in degree
//<---
SIT_CAMERA_POSITION = (vector) <0, 0, 0>;//where the camera is at, in local coords
SIT_CAMERA_FOCUS = (vector) <0, 0, 0>;//where the camera is looking at, in local coords

SIT_TEXT = (string) "";//text to hover above poseball--Set to "*" for debug text--Set to "" for blank
SIT_TEXT_COLOR = (vector) <1.0, 0.0, 1.0>; //Color R,G,B
SIT_TEXT_ALPHA = (float) 0.0;//alpha of sit text
SIT_TEXT_HIDEONSIT = (integer) TRUE;//Hide sit text when avie sits TRUE or FALSE
HIDE_POSEBALL_ON_SIT = (integer) FALSE;//Hide the poseball when avie sits on it, TRUE or FALSE
VERBOSE = (integer) FALSE; //Says a bunch of stuff about animation found and stuffs

//---END USER VARIABLES---\\

}

string ANIMATION = "sit_ground";
vector SIT_POSITION;
vector SIT_ROTATION;
string SIT_TEXT;
vector SIT_TEXT_COLOR;
float SIT_TEXT_ALPHA;
vector SIT_CAMERA_POSITION;
vector SIT_CAMERA_FOCUS;
integer SIT_TEXT_HIDEONSIT;
integer HIDE_POSEBALL_ON_SIT;
integer VERBOSE;
integer gAvieNum = -1;
key gAvieKey;

SetAnim()
{
integer cnt = llGetInventoryNumber(INVENTORY_ANIMATION);
if (cnt == 0) ANIMATION = "sit_ground";
else {
ANIMATION = llGetInventoryName(INVENTORY_ANIMATION, 0);
if (VERBOSE) llOwnerSay("Animation set to: " + ANIMATION);
}
if (gAvieNum > -1) {
if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) {
StopAllAnims();
llStartAnimation(ANIMATION);
}
}
}

StopAllAnims() {
list anims = llGetAnimationList(gAvieKey);
integer n;
integer cnt = llGetListLength(anims);
for (n=0; n < cnt; n++)
llStopAnimation(llList2String(anims,n));
}

InitAvie()
{
SetAnim();
gAvieNum = -1;
key id = llAvatarOnSitTarget();
if (id != NULL_KEY) {
gAvieKey = id;
integer i;
integer cnt = llGetNumberOfPrims();
for (i=1; i<=cnt; i++) {
if (llGetLinkKey(i) == id) gAvieNum = i;
}
if (gAvieNum > -1)
if (SIT_TEXT_HIDEONSIT) llSetText("", SIT_TEXT_COLOR, SIT_TEXT_ALPHA);
if (HIDE_POSEBALL_ON_SIT) llSetAlpha(0.0,ALL_SIDES);
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION);
} else {
if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) {
StopAllAnims();
if (SIT_TEXT == "*") llSetText(llGetObjectName() + "\n" + llGetObjectDesc() + "\n" + ANIMATION, <0,0,1>, 0.5);
else llSetText(SIT_TEXT, SIT_TEXT_COLOR, SIT_TEXT_ALPHA);
if (HIDE_POSEBALL_ON_SIT) llSetAlpha(1.0,ALL_SIDES);
}
}
}

default
{
state_entry()
{
InitUserVariables();
SetAnim();
llSetText(SIT_TEXT, SIT_TEXT_COLOR, SIT_TEXT_ALPHA);
llSitTarget(SIT_POSITION-<0,0,0.35443>,llEuler2Rot(SIT_ROTATION * DEG_TO_RAD));
llSetCameraEyeOffset(SIT_CAMERA_POSITION); //Looking from
llSetCameraAtOffset(SIT_CAMERA_FOCUS); //Looking at
InitAvie();
}

on_rez(integer prm)
{
llResetScript();
}

changed(integer change)
{
if (change & CHANGED_LINK) {
InitAvie();
}
if (change & CHANGED_INVENTORY) {
SetAnim();
}
}

run_time_permissions(integer perm)
{
if (perm & PERMISSION_TRIGGER_ANIMATION) {
StopAllAnims();
llStartAnimation(ANIMATION);
llSetLinkPrimitiveParams(gAvieNum, [
PRIM_POSITION, SIT_POSITION,
PRIM_ROTATION, llEuler2Rot(SIT_ROTATION * DEG_TO_RAD)/llGetLocalRot()]);
}
}
}


Positioner Script:
CODE

//This script was written by Katherine Taney, it is free to use, modify, give away, etc....
//Please give credit and stuffs, stealing is wrong and bad and stuffs....

integer CONTROLS;
integer gAvieNum = -1;
key gAvieKey;
vector gAviePos = <0,0,0>;
vector gAvieRot = <0,0,0>;
float gMoveAmount = 0.1;
integer gRotAmountIndex = 5;
list ROTATIONAMOUNTS = [
1.0,5.0,10.0,15.0,30.0,45.0,90.0
];
vector SIT_TARGET_OFFSET = <0,0,0.35443>;

integer MODE = 0;
integer MODE_POSITION = 0;
integer MODE_ROTATION = 1;

integer MOVEMENT = 0;
integer MOVEMENT_LOCAL = 0;
integer MOVEMENT_WORLD = 1;
integer MOVEMENT_AVIE = 2;

integer gListenHandle;

integer INITIALIZING = FALSE;

integer gCurrentMenuOffest = 0;
integer gListenChannel = -194288;
integer gLnkMsgNumReturn = -455;
integer gLnkMsgNumCall = -456;
list gCurrentButtonList = [];
string gCurrentTitle = "";

InitControls()
{
INITIALIZING = TRUE;
llListenRemove(gListenHandle);
gListenChannel = (integer)(llFrand(-1000000000.0) - 1000000000.0);
gListenHandle = llListen(gListenChannel, "", NULL_KEY, "");
key id = llAvatarOnSitTarget();
gAvieNum = -1;
if (id != NULL_KEY) {
gAvieKey = id;
integer i;
integer cnt = llGetNumberOfPrims();
for (i=1; i<=cnt; i++) {
if (llGetLinkKey(i) == id) gAvieNum = i;
}
if (gAvieNum > -1)
llRequestPermissions(llGetLinkKey(gAvieNum), PERMISSION_TAKE_CONTROLS | PERMISSION_TRACK_CAMERA | PERMISSION_CONTROL_CAMERA);
} else {
if (llGetPermissions() & PERMISSION_CONTROL_CAMERA) {
llReleaseControls();
llClearCameraParams();
llReleaseCamera(gAvieKey);
}
}
}

SetCamera()
{
vector campos = llGetCameraPos();
rotation camrot = llGetCameraRot();
llSetCameraParams([
CAMERA_ACTIVE, 1, // 1 is active, 0 is inactive
CAMERA_FOCUS, campos + llRot2Fwd(camrot), // region-relative position
CAMERA_FOCUS_LAG, 0.0 , // (0 to 3) seconds
CAMERA_FOCUS_LOCKED, TRUE, // (TRUE or FALSE)
CAMERA_FOCUS_THRESHOLD, 0.0, // (0 to 4) meters
CAMERA_POSITION, campos, // region-relative position
CAMERA_POSITION_LAG, 0.0, // (0 to 3) seconds
CAMERA_POSITION_LOCKED, TRUE, // (TRUE or FALSE)
CAMERA_POSITION_THRESHOLD, 0.0 // (0 to 4) meters
]);
}

Mark()
{
llSay(-123456, "!MARK~" + (string)llGetRootPosition() + "~" + (string)llGetLocalPos() + "~" + (string)llGetRootRotation() + "~" + (string)llGetLocalRot() + "~" + (string)gAviePos + "~" + (string)gAvieRot);
}

list GetMenuList(list btnList)
{
//llOwnerSay(llList2CSV(btnList));
integer i;
list tmpMenuList = [];
integer listLen = llGetListLength(btnList);
integer buttoncount = 12;
if (gCurrentMenuOffest > 0) {
--buttoncount;
tmpMenuList = ["<-Back"];
}
if (listLen > buttoncount) --buttoncount;
integer stopPos = buttoncount;
if (listLen > buttoncount) {
stopPos = gCurrentMenuOffest + buttoncount;
}
if (stopPos > listLen) stopPos = listLen;
for (i=gCurrentMenuOffest;i<stopPos;i++) {
tmpMenuList += llList2String(btnList,i);
}
if (listLen > stopPos) tmpMenuList += ["Next->"];
return tmpMenuList;
}

HandleControl(integer held, integer change)
{
if (!INITIALIZING) {
//llOwnerSay((string)held + "~" + (string)change);
SetCamera();
vector mv;
float amt;
if (MODE == MODE_POSITION) amt = gMoveAmount;
else if (MODE == MODE_ROTATION) amt = llList2Float(ROTATIONAMOUNTS, gRotAmountIndex);

if (held & change & CONTROL_FWD) mv += <amt, 0.0, 0.0>;
if (held & change & CONTROL_BACK) mv += <-amt, 0.0, 0.0>;
if (held & change & CONTROL_UP) mv += <0.0, 0.0, amt>;
if (held & change & CONTROL_DOWN) mv += <0.0, 0.0, -amt>;
if (held & change & CONTROL_ROT_LEFT) mv += <0.0, -amt, 0.0>;
if (held & change & CONTROL_ROT_RIGHT) mv += <0.0, amt, 0.0>;
if (MOVEMENT == MOVEMENT_WORLD) mv = mv / llGetLocalRot();
else if (MOVEMENT == MOVEMENT_AVIE) mv = mv * llEuler2Rot(gAvieRot*DEG_TO_RAD);
if (mv != ZERO_VECTOR) {
if (MODE == MODE_POSITION) {
gAviePos += mv;
llSetLinkPrimitiveParams(gAvieNum, [PRIM_POSITION, gAviePos]);
}
else if (MODE == MODE_ROTATION) {
gAvieRot += mv;
llSetLinkPrimitiveParams(gAvieNum, [PRIM_ROTATION, llEuler2Rot(gAvieRot*DEG_TO_RAD)/llGetLocalRot()]);
}
Mark();
}

if (held & change & CONTROL_RIGHT) {
if (MODE == MODE_POSITION) {
gMoveAmount *= 10;
llOwnerSay("Move amount set to " + (string)gMoveAmount);
}
else if (MODE == MODE_ROTATION) {
gRotAmountIndex += 1;
if (gRotAmountIndex > llGetListLength(ROTATIONAMOUNTS)-1) gRotAmountIndex = 0;
llOwnerSay("Rotate amount set to " + llList2String(ROTATIONAMOUNTS, gRotAmountIndex));
}
}
if (held & change & CONTROL_LEFT) {
if (MODE == MODE_POSITION) {
gMoveAmount /= 10;
llOwnerSay("Move amount set to " + (string)gMoveAmount);
}
else if (MODE == MODE_ROTATION) {
gRotAmountIndex -= 1;
if (gRotAmountIndex < 0) gRotAmountIndex = llGetListLength(ROTATIONAMOUNTS)-1;
llOwnerSay("Rotate amount set to " + llList2String(ROTATIONAMOUNTS, gRotAmountIndex));
}
}

}
}

default
{
state_entry()
{
CONTROLS = CONTROL_FWD | CONTROL_BACK | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_UP | CONTROL_DOWN | CONTROL_ROT_LEFT | CONTROL_ROT_RIGHT;
InitControls();
}

run_time_permissions(integer perm)
{
if (perm & PERMISSION_TAKE_CONTROLS) {
llTakeControls(CONTROLS, 1, 0);
llSetTimerEvent(1.2);
}
}

changed(integer change)
{
if (change & CHANGED_LINK) {
InitControls();
}
}

control(key id, integer held, integer change)
{
HandleControl(held, change);
}

timer()
{
llSetTimerEvent(0.0);
llSetLinkPrimitiveParams(gAvieNum, [PRIM_POSITION, gAviePos, PRIM_ROTATION, llEuler2Rot(gAvieRot*DEG_TO_RAD)/llGetLocalRot()]);
SetCamera();
llSay(-123456, "!CONTROL~" + (string)gAvieKey + "~" + (string)gListenChannel);
llSay(-123456, "!CONFIG~" + (string)MODE + "~" + (string)MOVEMENT + "~" + (string)gAvieKey);
Mark();
llOwnerSay("Avie positioner active");
INITIALIZING = FALSE;
}

touch_start(integer total_number)
{
list btnlist = ["ZERO"];
if (MODE == MODE_POSITION) btnlist += "Rotation";
else if (MODE == MODE_ROTATION) btnlist += "Position";
if (MOVEMENT == MOVEMENT_LOCAL) btnlist += "World";
else if (MOVEMENT == MOVEMENT_WORLD) btnlist += "Avatar";
else if (MOVEMENT == MOVEMENT_AVIE) btnlist += "Local";
btnlist += "Report";
string title =
"Avatar Postition: " + (string)gAviePos + "\n" +
"Avatar Rotation (DEG): " + (string)gAvieRot + "\n" +
"Pose Positioner Options:";
llMessageLinked(LINK_SET, -456, llDumpList2String([-455, title] + btnlist, "~"), llDetectedKey(0));
}

link_message(integer sender_num, integer num, string str, key id)
{
if (num == gLnkMsgNumCall) {
gCurrentMenuOffest = 0;
list tmp = llParseString2List(str, ["~"], []);
gLnkMsgNumReturn = (integer)llList2String(tmp, 0);
gCurrentTitle = llList2String(tmp, 1);
tmp = llListReplaceList(tmp, [], 0,1);
gCurrentButtonList = tmp;
llDialog(id, gCurrentTitle, GetMenuList(gCurrentButtonList), gListenChannel);
}
else if (num == -455) {
if (str == "Rotation") {
MODE = MODE_ROTATION;
llOwnerSay("Rotation mode selected");
}
else if (str == "Position") {
MODE = MODE_POSITION;
llOwnerSay("Position mode selected");
}
else if (str == "World") {
MOVEMENT = MOVEMENT_WORLD;
llOwnerSay("World movement selected");
}
else if (str == "Local") {
MOVEMENT = MOVEMENT_LOCAL;
llOwnerSay("Local movement selected");
}
else if (str == "Avatar") {
MOVEMENT = MOVEMENT_AVIE;
llOwnerSay("Avatar movement selected");
}
else if (str == "ZERO") {
gAviePos = ZERO_VECTOR;
gAvieRot = ZERO_VECTOR;
llSetLinkPrimitiveParams(gAvieNum, [PRIM_POSITION, gAviePos, PRIM_ROTATION, llEuler2Rot(gAvieRot*DEG_TO_RAD)/llGetLocalRot()]);
Mark();
llOwnerSay("Zeroed");
}
else if (str == "Increase") {
if (MODE == MODE_POSITION) {
gMoveAmount *= 10;
llOwnerSay("Move amount set to " + (string)gMoveAmount);
}
else if (MODE == MODE_ROTATION) {
gRotAmountIndex += 1;
if (gRotAmountIndex > llGetListLength(ROTATIONAMOUNTS)-1) gRotAmountIndex = 0;
llOwnerSay("Rotate amount set to " + llList2String(ROTATIONAMOUNTS, gRotAmountIndex));
}
}
else if (str == "Decrease") {
if (MODE == MODE_POSITION) {
gMoveAmount /= 10;
llOwnerSay("Move amount set to " + (string)gMoveAmount);
}
else if (MODE == MODE_ROTATION) {
gRotAmountIndex -= 1;
if (gRotAmountIndex < 0) gRotAmountIndex = llGetListLength(ROTATIONAMOUNTS)-1;
llOwnerSay("Rotate amount set to " + llList2String(ROTATIONAMOUNTS, gRotAmountIndex));
}
}
else if (llGetSubString(str, 0, 2) == "SET") {
if (llGetSubString(str, 3, 3) == "P") {
gMoveAmount = (float)llGetSubString(str, 4, -1);
llOwnerSay("Move amount set to " + (string)gMoveAmount);
}
else if (llGetSubString(str, 3, 3) == "R") {
gRotAmountIndex = llListFindList(ROTATIONAMOUNTS, [(float)llGetSubString(str, 4, -1)]);
if (gRotAmountIndex == -1) gRotAmountIndex = 5;
llOwnerSay("Rotate amount set to " + llList2String(ROTATIONAMOUNTS, gRotAmountIndex));
}
}
else if (str == "Report") {
llOwnerSay("\n" +
"SIT_POSITION = " + (string)gAviePos + ";\n" +
"SIT_ROTATION = " + (string)(llRot2Euler(llEuler2Rot(gAvieRot*DEG_TO_RAD))*RAD_TO_DEG) + ";"
);
}
else {
if (str == "X+") HandleControl(CONTROL_FWD, CONTROL_FWD);
else if (str == "X-") HandleControl(CONTROL_BACK, CONTROL_BACK);
else if (str == "Y+") HandleControl(CONTROL_ROT_RIGHT, CONTROL_ROT_RIGHT);
else if (str == "Y-") HandleControl(CONTROL_ROT_LEFT, CONTROL_ROT_LEFT);
else if (str == "Z+") HandleControl(CONTROL_UP, CONTROL_UP);
else if (str == "Z-") HandleControl(CONTROL_DOWN, CONTROL_DOWN);
else llOwnerSay("ERR: " + str);
}
llSay(-123456, "!CONFIG~" + (string)MODE + "~" + (string)MOVEMENT + "~" + (string)gAvieKey);
Mark();
}
}

listen(integer channel, string name, key id, string str)
{
if (str == "<-Back") {
gCurrentMenuOffest -= 11;
llDialog(id, gCurrentTitle, GetMenuList(gCurrentButtonList), gListenChannel);
} else if (str == "Next->") {
gCurrentMenuOffest += 11;
llDialog(id, gCurrentTitle, GetMenuList(gCurrentButtonList), gListenChannel);
} else {
llMessageLinked(LINK_SET, gLnkMsgNumReturn, llStringTrim(str, STRING_TRIM), id);
}
}
}



I've placed a box in my shop that includes both of these scripts, plus a HUD to control positioning, a marker that follows the avie to show local coordinates, an example with everything assembled and ready to use, and a zero pose. The box is for sale for L$0.
Nada Epoch
The Librarian
Join date: 4 Nov 2002
Posts: 1,423
Library bump
01-21-2008 14:23
:)
_____________________
i've got nothing. ;)
Digital Kaos
Sexy Motions
Join date: 22 Aug 2005
Posts: 15
02-13-2008 11:03
Awesome that is very generous of you,thank you
Archaeva Maximus
Registered User
Join date: 11 Oct 2007
Posts: 5
03-02-2008 03:33
not to sure what this does but I position my av by clicking the poseball first then edit, then i sit on the poseball and then can rotate my av in realtime anyway so why the script, may have missed something here.
Max Pitre
Registered User
Join date: 19 Jul 2006
Posts: 370
03-02-2008 05:55
From: Archaeva Maximus
not to sure what this does but I position my av by clicking the poseball first then edit, then i sit on the poseball and then can rotate my av in realtime anyway so why the script, may have missed something here.


Because, thankfully, not everyone uses round poseballs. My couch cushions use different shapes or sculpty cushions and one clicks the cushions to sit on them.
electroRogue Sinister
Registered User
Join date: 23 May 2008
Posts: 1
luv it
05-31-2008 11:23
ty ever so much, I went to your shop and found it easy =).

Does anybody think they could make something similar for attached objects ?
xx
eR
Anastasia Serenity
Registered User
Join date: 2 Jan 2009
Posts: 53
09-25-2009 08:38
Katherine Taney profile cant be found anymore and the shop isn't there?


I am looking for this HUD and if someone can tell me where to get, or simply send it to me? Would be nice ! Thank you
Farrah Seetan
Registered User
Join date: 23 Jun 2008
Posts: 4
10-16-2009 05:59
you can still get it here...

https://uncensored.xstreetsl.com/modules.php?name=Marketplace&file=item&ItemID=1184465

and I've repackaged it so that it's not (no copy) (no modify) which was just a notecard giver script inside the box and placed it at my store ground level for sale for 0L so people can find it inworld by searching for her name, which is how I actually found it as someone had it out at their workshop and sent me a copy.

I've placed it inworld due to not knowing if Katherine is just hidden or gone and when her slex magic box will stop working.

You can find my store by searching for D&A Studios or Amara Twilight.