This commit is contained in:
Fred Beckhusen
2015-08-07 15:34:30 -05:00
parent ce47ec2f3e
commit fde850293c
8080 changed files with 0 additions and 2443112 deletions

View File

@@ -1,516 +0,0 @@
// :CATEGORY:Prim Animator
// :NAME:Archipelis scripts for prim animator
// :AUTHOR:Ferd Frederix
// :CREATED:2013-09-06
// :EDITED:2013-09-18 15:38:48
// :ID:52
// :NUM:77
// :REV:1
// :WORLD:Second Life
// :DESCRIPTION:
// An almost unlimited space prim animator. It uses multiple Store Scripts, that can hold thousands of prim animations
// The original version of the script. Must be used with Multiple copies of Store 0..1,2, to animate prims
// :CODE:
// author Ferd Frederix
// Prim position root script
// Put this script in the root prim.
// touch the prim to start recording
// Clear - wipe out all recording.
// Name - name a new recording
// Pause - insert a 1 second pause
// Record - store a new set of child prim positions
// Publish - Saves to database
// Help
// >> and << to cycle each animation
// configurable things
string MyName ="horse 5"; // the name of the Entire set of animations, must be unique
string MyPassword = "ferdzee"; // a password just for you and your stuff
integer debug = 0; // if set to TRUE, debug info appears
// remote db reading
key kHttpRequestID;
integer countLoaded = 0; // how many nanims have been loaded via HTTP
integer iPlayChannel = 1; // the playback channel, this is the channel you use in LinkMessages
integer countchannel= 2001; // how many have been saved
integer iDialogChannel ; // dialog boxes
integer iPrimCount ; // total number of prims
integer iWantNameFlag; // flag indicating we are waiting for a name to be chatted
integer imax; // total records in store
integer runtime = 0; // set to 1 after Recording and publishing.
// animation store
string sCurrentAnimationName; // The name of the animation we are playing
string sPriorAniName; // the prior animation name so we can spot differences as we read them in
list lLastPrimList; // storage of the last prim position we learned
integer iLastSTRIDE = 4; // size of the last prim list
integer iListenerHandle; // temp iListenerHandle when we are waiting for them to give us a name
list lUserAnimNames; // animations read from the notecard added to the Menu display
// Commands
integer Clear = 99; // erase local db
integer Erase = 100; // erase Server DB command
integer Add = 101; // add a coordinate
integer Publish = 102; // save to db
integer Name = 103; // send Name to db
integer Password = 104; // send Password to db
integer Play = 1; // play channel to make an animation run
Debug( string msg)
{
if (debug) llOwnerSay(msg);
}
// clear any old listeners and make a new on to control lag
NewListen()
{
iDialogChannel = (integer) (llFrand(400) + 300);
llListenRemove(iListenerHandle);
iListenerHandle = llListen(iDialogChannel,"","","");
}
// prompt the user for an animation name. Uses text box or chat
AskForName()
{
iWantNameFlag = TRUE;
llSetTimerEvent(60);
NewListen();
llOwnerSay("Enter the name in the text box or type the new animation name on channel /" + (string) iDialogChannel );
llTextBox(llGetOwner(),"Type the new animation name",iDialogChannel);
}
Get(string data)
{
Debug("Data was " + data);
list lLine = (llParseString2List(data, ["|"], []));
string sAniName = llList2String(lLine,0);
string sNum = (string) Getline(lLine,1);
float fNum = (float) sNum;
vector vPos = (vector) Getline(lLine,2); // global for calcChild()
rotation rRot = (rotation) Getline(lLine,3); // global for calcChild()
vector vprimSize = (vector) Getline(lLine,4);
countLoaded++;
// the first record is always the root prim size
if (fNum == 0)
{
FetchNext();
return;
}
if (sAniName != sPriorAniName)
{
sPriorAniName = sAniName;
sCurrentAnimationName = sAniName;
if (llListFindList(lUserAnimNames,[sAniName]) == -1)
{
Debug("Loading animation " + sAniName);
lUserAnimNames += sAniName;
}
}
// Debug("Loading Prim #" + (string) fNum);
if(fNum != 1) // skip root prim
{
sCurrentAnimationName = sAniName;
llMessageLinked(LINK_THIS,Add,sAniName
+"|"
+ (string) fNum
+"|"
+ (string) vPos
+ "|"
+ (string) rRot
+ "|"
+ (string) vprimSize,"");
llSetText("Initialising... \n" + (string) (countLoaded) , <1,1,1>, 1.0);
}
llSleep(1); // http throttle avoidance
FetchNext();
}
// in case of hand editing, we wupe out extra stuff at end
string Getline(list Input, integer line)
{
return llStringTrim(llList2String(Input, line),STRING_TRIM);
}
Record()
{
if (llStringLength(sCurrentAnimationName) > 0)
{
integer ifoundmovement = 0; // will be set if any child moved
integer iPrimCounter ; // skip past the root prim
for (iPrimCounter =2; iPrimCounter <= iPrimCount ; iPrimCounter++ )
{
list my_list = llGetLinkPrimitiveParams(iPrimCounter,[PRIM_POSITION,PRIM_ROTATION, PRIM_SIZE ]);
// position is always in region coordinates, even if the prim is a child or the root prim of an attachment.
// rot is always the global rotation, even if the prim is a child or the root prim of an attachment.
// get current prim pos, rot and size
vector vrealPrimPos = llList2Vector (my_list,0) - llGetPos(); // position subtract Global Pos
vrealPrimPos /= llGetRot();
rotation rrealPrimRot = llList2Rot (my_list,1) / llGetRot(); // rotation subtract Global Rot
vector vrealPrimSize = llList2Vector (my_list,2); // size
// compare it to the last one we had, stride of list is a 4, and it is already sorted
integer iindex = (iPrimCounter - 2) * iLastSTRIDE; // zeroth position is fPrimCounter - start, or 2
// get the last thing we remembered about this prim
integer iprimNum = llList2Integer (lLastPrimList, iindex); // must be 0,1,2, in order
vector vlastPrimPos = llList2Vector (lLastPrimList, iindex+1);
rotation rlastPrimRot = llList2Rot (lLastPrimList, iindex+2);
vector vlastPrimSize = llList2Vector (lLastPrimList, iindex+3);
// if anything changed on this prim, we must record it.
if (vlastPrimPos != vrealPrimPos ||
rlastPrimRot != rrealPrimRot ||
vlastPrimSize!= vrealPrimSize
)
{
ifoundmovement++;
//Save them in the master list of all animations
llMessageLinked(LINK_THIS,Add,sCurrentAnimationName+ "|"
+ (string) iPrimCounter
+ "|"
+ (string) vrealPrimPos
+ "|"
+ (string) rrealPrimRot
+ "|"
+ (string) vrealPrimSize,"");
imax = llGetListLength(lLastPrimList);
// save the changes in the last prim list so we can keep our lists smaller
lLastPrimList = llListReplaceList(lLastPrimList,[vrealPrimPos],iPrimCounter+1,iPrimCounter+1);
lLastPrimList = llListReplaceList(lLastPrimList,[rrealPrimRot],iPrimCounter+2,iPrimCounter+2);
lLastPrimList = llListReplaceList(lLastPrimList,[vrealPrimSize],iPrimCounter+3,iPrimCounter+3);
//Debug("Saved in history at prim # " + (string) (iPrimCounter));
} // if
} // for
//Debug("history:" + llDumpList2String(lLastPrimList,":"));
//Debug("master:" + llDumpList2String(lAniStore," "));
if (!ifoundmovement)
{
llOwnerSay("You must move at least one child prim.");
}
}
else
{
AskForName();
}
}
// on reset, record the base position in history so we can see changes
ClearRAM()
{
iPrimCount = llGetNumberOfPrims(); // how many we are recording
sCurrentAnimationName = ""; // no name in use
lLastPrimList = []; // wipe last animations list
integer iPrimCounter ;
for (iPrimCounter=2; iPrimCounter <= iPrimCount ; iPrimCounter++ ) // skip 1, which is the root prim
{
list my_list = llGetLinkPrimitiveParams(iPrimCounter,[PRIM_POSITION, PRIM_ROTATION, PRIM_SIZE ]);
// save the local pos and rot, since llGetLinkPrimitiveParams returns global pos and rot
vector primpos = llList2Vector (my_list,0) - llGetPos();
primpos /= llGetRot();
rotation primrot = llList2Rot (my_list,1) / llGetRot();
vector primsize = llList2Vector (my_list,2) ;
lLastPrimList += iPrimCounter;
lLastPrimList += primpos;
lLastPrimList += primrot;
lLastPrimList += primsize;
}
llOwnerSay("RAM is cleared");
}
rotation calcChildRot(rotation rdeltaRot)
{
if (llGetAttached())
return rdeltaRot/llGetLocalRot();
else
return rdeltaRot/llGetRootRotation();
}
MakeMenu()
{
if (runtime)
{
MakeMenu2();
return;
}
list amenu = ["Record","Clear RAM","Pause"] +
["Erase","Load","Publish"] +
["Recordings","Name","Play All"] +
["Help","More", "Finish"];
string menuText = "Available Memory: " + (string) llGetFreeMemory() +
"\n\n" +
"Recordings: Select a named animation\n" +
"Name: Set the animation name\n" +
"Play All: Play all animations\n" +
"Clear RAM: Erase SL memory\n"+
"Erase: Delete Server Data\n" +
"Load: Get from Server\n" +
"Publish: Save to Server\n" +
"Record: Record a snapshot of prim positions\n" +
"Pause: Insert 0.1 second pause\n" +
"Finish: End all programming\n" +
"Help: Help";
NewListen();
llDialog(llGetOwner(), menuText,amenu,iDialogChannel);
}
MakeMenu2()
{
string menuText ;
list menu2 = lUserAnimNames;
menu2 = llDeleteSubList(menu2,11,999); // 11 max
if (runtime)
menu2 += "Unlock";
if (llGetListLength(lUserAnimNames) == 0)
{
menu2 += ["Back"] ;
menuText = " There are no animation names to display\n\n" +
"Back:- Go back to programming menu";
}
else
menuText = "Pick an animation to play.";
NewListen();
llDialog(llGetOwner(), menuText,menu2,iDialogChannel);
}
FetchNext()
{
string url = "http://secondlife.mitsi.com/cgi/animate.plx?Type=Load&Count=" + (string) countLoaded + "&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyPassword);
Debug(url);
kHttpRequestID = llHTTPRequest(url, [], "");
}
default
{
state_entry()
{
llMessageLinked(LINK_THIS,Name,MyName,"");
llMessageLinked(LINK_THIS,Password,MyPassword,"");
if (runtime)
{
ClearRAM();
FetchNext(); // start with first line in DB
}
}
http_response(key queryid, integer status, list metadata, string data)
{
if (queryid == kHttpRequestID )
{
if (status == 200) // HTTP success status
{
if (data == "nothing to do")
{
llOwnerSay("Initialized with " + (string) countLoaded + " settings");
llSetText("" , <1,1,1>, 1.0);
return;
}
Get(data);
}
else
{
llOwnerSay("Server Error loading animations");
}
}
}
touch_start(integer total_number)
{
if (llDetectedKey(0) == llGetOwner() )
{
MakeMenu();
}
}
// timed out waitig for a name of an animation
timer()
{
iWantNameFlag = FALSE;
llSetTimerEvent(0);
llOwnerSay(" Timeout waiting for animation name");
llListenRemove(iListenerHandle);
}
listen( integer channel, string name, key id, string message )
{
llListenRemove(iListenerHandle);
// Debug(message);
if (message == "Finish")
{
runtime++;
llOwnerSay("The animator is now locked. Further touches will bring up a list of animations. You must unlock the menu to add more animations");
}
else if (message == "Unlock")
{
runtime = 0;
llOwnerSay("The animator is now unlocked for programming.");
}
else if (message == "Erase")
{
llMessageLinked(LINK_THIS,Erase,"",""); // erase the db
MakeMenu();
}
else if (message == "Clear RAM")
{
ClearRAM();
MakeMenu();
}
else if (message =="Pause")
{
llMessageLinked(LINK_THIS,Add,"sCurrentAnimationName|"
+ "-0.1" // sleep 1 tenth a second
+ "|"
+ "<0,0,0>" // null pos
+ "<0,0,0,1>" // null rot
+ "|"
+ "<0,0,0>",""); // null size
MakeMenu();
}
else if (message == "Recordings")
{
MakeMenu2();
}
else if (message == "Load")
{
countLoaded = 0;
FetchNext(); // start with first line in DB
}
else if (message == "Record")
{
Record();
MakeMenu();
}
else if (message == "Publish")
{
llMessageLinked(LINK_THIS,Name,MyName,""); // in case we reset just the stores
llMessageLinked(LINK_THIS,Password,MyPassword,"");
llMessageLinked(LINK_THIS,Publish,"","");
MakeMenu();
}
else if (message == "Name")
{
AskForName();
}
else if (message == "Back")
{
MakeMenu();
}
else if (message == "More")
{
MakeMenu();
}
else if (message == "Play All")
{
integer l = llGetListLength(lUserAnimNames);
if (l == 0)
llOwnerSay("Nothing to do");
else
{
integer i = 0;
for ( i = 0; i < l; i++)
{
string ani = llList2String(lUserAnimNames,i);
llMessageLinked(LINK_THIS,iPlayChannel,ani,"");
llSleep(1);
}
}
MakeMenu();
}
else if (message == "Help")
{
llLoadURL(llGetOwner(),"View online help", "http://secondlife.mitsi.com/secondlife/Posts/Prim-Animator-DB");
}
else if (iWantNameFlag)
{
sCurrentAnimationName = message;
if (llGetListLength(lUserAnimNames) < 11)
{
if (llListFindList(lUserAnimNames,[sCurrentAnimationName]) == -1)
lUserAnimNames += message;
}
else
{
lUserAnimNames = llDeleteSubList(lUserAnimNames,11,99);
}
MakeMenu();
llOwnerSay("Ready to record animation '" + sCurrentAnimationName + "'");
llOwnerSay("Position all child prims, then select the Menu item 'Record', and repeat as necessary. When finished, click the name to play back the animation. Click 'Name' again to start a new animation sequence.");
iWantNameFlag = 0;
llSetTimerEvent(1.0);
}
else
{
if (llListFindList(lUserAnimNames,[message]) != -1)
{
Debug("playback animation " + message);
llMessageLinked(LINK_THIS,iPlayChannel,message,"");
MakeMenu();
}
}
}
link_message(integer sender_num, integer num, string message, key id)
{
if (num == countchannel)
{
llSetText("Loaded " + message,<1,1,1>,1.0);
}
}
}

View File

@@ -1,314 +0,0 @@
// :CATEGORY:Prim Animator
// :NAME:Archipelis scripts for prim animator
// :AUTHOR:Ferd Frederix
// :CREATED:2013-09-06
// :EDITED:2013-09-18 15:38:48
// :ID:52
// :NUM:78
// :REV:1
// :WORLD:Second Life
// :DESCRIPTION:
// Prim storage Script Should be named Store 0
// :CODE:
// prim store
// constants
integer debug =0 ;
// return codes
integer countchannel= 2001; // echo the number iof prims loaded to the animator
// Commands
integer Clear = 99; // erase local db
integer Erase = 100; // erase Server DB command
integer Add = 101; // add a coordinate
integer Publish = 102; // save to db
integer Name = 103; // send Name to db
integer Password = 104; // send Password to db
integer Play = 1; // backwards compat
// vars
integer full = FALSE; // this script RAM is full
integer myNum = 0; // the number at the end of this script name 0, 1, 2....
integer imax; // total records in store
integer datum; // the load counter increments as we load anims from db
string MyName;
string MyPassword;
// remote db reading
key kHttpRequestID;
// lists
list names; // a list of distnct animation names stored here
list db; // name, prin num, pos, rot, size
integer STRIDE = 5; // 4 items in the above list
integer recordcount = 0; // how many anims are stored
vector vRootScale ; // the initial size when the prims were recorded
vector vScaleChange = <1,1,1>; // The change percent if resized
integer GetScale()
{
//Debug ("Size:" + (string) orig_size);
vector newScale = llGetScale();
vScaleChange.x = newScale.x / vRootScale.x;
vScaleChange.y = newScale.y / vRootScale.y;
vScaleChange.z = newScale.z / vRootScale.z;
return (vScaleChange != <1,1,1>);
}
// Start saving records. The first record is the prim size.
StartPublishing ()
{
imax = llGetListLength(db);
datum = 0; // point to the first record, counts as we load records
integer howmany = imax / STRIDE ;
llOwnerSay((string) howmany + " movements recorded - now saving to server.");
}
EraseDB()
{
string url;
//Debug( "Saving Size:" + (string) llGetScale());
url = "http://secondlife.mitsi.com/cgi/animate.plx?Type=Erase";
url += "&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyPassword);
Debug(url);
kHttpRequestID = llHTTPRequest(url, [], "");
}
Put()
{
if (datum < imax)
{
string sAniName = llList2String (db, datum);
float fprimNum = llList2Float (db, datum+1);
vector vprimPos = llList2Vector (db, datum+2);
rotation rprimRot = llList2Rot (db, datum+3) ;
vector vprimSize = llList2Vector (db, datum+4);
string url = "http://secondlife.mitsi.com/cgi/animate.plx?Type=Save&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyPassword);
url += "&aniName=" + (string) sAniName;
url += "&PrimNum=" + (string) fprimNum;
url += "&Pos=" + (string) vprimPos;
url += "&Rot=" + (string) rprimRot;
url += "&Size=" + (string) vprimSize;
Debug(url);
if ((datum/STRIDE) % 10 == 0 && datum)
llMessageLinked(LINK_THIS,countchannel,(string) (datum/STRIDE) ,"");
kHttpRequestID = llHTTPRequest(url, [], "");
llSleep(1);
datum += STRIDE;
}
else
{
llMessageLinked(LINK_THIS,countchannel,(string) (datum/STRIDE),"");
llSleep(2.0);
llMessageLinked(LINK_THIS,countchannel,"","");
}
}
Debug(string msg)
{
if (debug)
llOwnerSay(llGetScriptName() + ":" + msg);
}
default
{
state_entry()
{
list parts = llParseString2List( llGetScriptName(),[" "],[""]);
myNum = llList2Integer(parts,1);
vRootScale = llGetScale(); // set a default of this size, the real size when recorded comes from the server
Add = Add + (10 * myNum);
Debug("DB " + (string) myNum + " is empty");
}
link_message(integer sender_num, integer num, string msg, key id)
{
//Debug("cmd:" + (string) num + ":" + msg);
// valid commands only.
if (num != Clear && num != Erase && num != Play && num != Add && num != Publish && num != Name && num!= Password)
return;
Debug("cmd rcv :" + (string) num + ":" + msg);
if (num == Clear)
{
db = []; // zero the animations
names = []; // zero names db
//Debug((string) myNum + " erased " );
full = FALSE;
recordcount = 0;
return;
}
else if (num == Add)
{
if (full)
{
Debug((string) myNum + " pass Add on to " + (string) (num +10));
llMessageLinked(LINK_THIS,num +10,msg,id);
return;
}
//Debug("Add");
list vecs = llParseString2List(msg,["|"],[""]);
// Debug(llDumpList2String(vecs,"---"));
string name= llList2String(vecs,0);
if (llListFindList(names,[name]) == -1)
names += name;
float fNum = (float) (llList2String(vecs,1));
vector vPos = (vector) (llList2String(vecs,2));
rotation rRot = (rotation) (llList2String(vecs,3));
vector vprimSize = (vector) (llList2String(vecs,4));
db += name;
db += fNum;
db += vPos;
db += rRot;
db += vprimSize;
recordcount ++;
Debug("Mem:" + (string) llGetFreeMemory() );
if (llGetFreeMemory() < 2000)
full++;
}
else if (num == Name)
{
MyName = msg;
}
else if (num == Password)
{
MyPassword = msg;
}
else if (num == Play)
{
if (llListFindList(names,[msg]) == -1)
return;
integer currpos;
integer end = recordcount * STRIDE;
// play back all we find
for (currpos = 0; currpos < end; currpos+= STRIDE)
{
if ( msg == llList2String(db,currpos) )
{
float fPrim = (float) llList2String(db,currpos+1);
vector vPos = (vector) llList2String(db,currpos+2);
rotation rRot = (rotation) llList2String (db,currpos+3);
vector vprimSize = (vector) llList2String(db,currpos+4);
if (fPrim > 1 ) // skip root prim
{
// set the local pos and locat rot to the prims orientation and position
if (llGetAttached())
rRot = rRot/llGetLocalRot();
else
rRot = rRot/llGetRootRotation();
if (GetScale())
{
vPos.x *= vScaleChange.x;
vprimSize.x *= vScaleChange.x;
vPos.y *= vScaleChange.y;
vprimSize.y *= vScaleChange.y;
vPos.z *= vScaleChange.z;
vprimSize.z *= vScaleChange.z;
}
// Debug("p=" + (string) fPrim
// + " l=" + (string) vPos
// + " r=" + (string) rRot
// + " s=" + (string) vprimSize);
llSetLinkPrimitiveParamsFast((integer) fPrim,[PRIM_POSITION,vPos,PRIM_ROTATION,rRot,PRIM_SIZE,vprimSize]);
}
else if (fPrim == 0)
{
vRootScale = (vector) msg;
Debug("Set scale to " + (string) vRootScale);
}
else if (fPrim < 0)
{
Debug("Sleep");
llSleep( fPrim * -1);
}
}
}
}
else if (num == Publish)
{
if (myNum)
llSleep(5); // time to delete the database and save the root prim
StartPublishing();
}
else if (num == Erase)
{
EraseDB();
}
else
{
Debug("Bad command");
}
}
// use for publishing in parallel
http_response(key queryid, integer status, list metadata, string data)
{
if (queryid == kHttpRequestID )
{
if (status == 200) // HTTP success status
{
Debug(data);
if (data == "ok")
{
Put();
return;
}
else if (data == "deleted")
{
llOwnerSay("Remote database is empty");
return;
}
}
else
{
llOwnerSay("Server Error loading animations");
}
}
}
}

View File

@@ -1,314 +0,0 @@
// :CATEGORY:Prim Animator
// :NAME:Archipelis scripts for prim animator
// :AUTHOR:Ferd Frederix
// :CREATED:2013-09-06
// :EDITED:2013-09-18 15:38:48
// :ID:52
// :NUM:79
// :REV:1
// :WORLD:Second Life
// :DESCRIPTION:
// Prim storage Script Should be names Store 1
// :CODE:
// prim store
// constants
integer debug =0 ;
// return codes
integer countchannel= 2001; // echo the number iof prims loaded to the animator
// Commands
integer Clear = 99; // erase local db
integer Erase = 100; // erase Server DB command
integer Add = 101; // add a coordinate
integer Publish = 102; // save to db
integer Name = 103; // send Name to db
integer Password = 104; // send Password to db
integer Play = 1; // backwards compat
// vars
integer full = FALSE; // this script RAM is full
integer myNum = 0; // the number at the end of this script name 0, 1, 2....
integer imax; // total records in store
integer datum; // the load counter increments as we load anims from db
string MyName;
string MyPassword;
// remote db reading
key kHttpRequestID;
// lists
list names; // a list of distnct animation names stored here
list db; // name, prin num, pos, rot, size
integer STRIDE = 5; // 4 items in the above list
integer recordcount = 0; // how many anims are stored
vector vRootScale ; // the initial size when the prims were recorded
vector vScaleChange = <1,1,1>; // The change percent if resized
integer GetScale()
{
//Debug ("Size:" + (string) orig_size);
vector newScale = llGetScale();
vScaleChange.x = newScale.x / vRootScale.x;
vScaleChange.y = newScale.y / vRootScale.y;
vScaleChange.z = newScale.z / vRootScale.z;
return (vScaleChange != <1,1,1>);
}
// Start saving records. The first record is the prim size.
StartPublishing ()
{
imax = llGetListLength(db);
datum = 0; // point to the first record, counts as we load records
integer howmany = imax / STRIDE ;
llOwnerSay((string) howmany + " movements recorded - now saving to server.");
}
EraseDB()
{
string url;
//Debug( "Saving Size:" + (string) llGetScale());
url = "http://secondlife.mitsi.com/cgi/animate.plx?Type=Erase";
url += "&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyPassword);
Debug(url);
kHttpRequestID = llHTTPRequest(url, [], "");
}
Put()
{
if (datum < imax)
{
string sAniName = llList2String (db, datum);
float fprimNum = llList2Float (db, datum+1);
vector vprimPos = llList2Vector (db, datum+2);
rotation rprimRot = llList2Rot (db, datum+3) ;
vector vprimSize = llList2Vector (db, datum+4);
string url = "http://secondlife.mitsi.com/cgi/animate.plx?Type=Save&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyPassword);
url += "&aniName=" + (string) sAniName;
url += "&PrimNum=" + (string) fprimNum;
url += "&Pos=" + (string) vprimPos;
url += "&Rot=" + (string) rprimRot;
url += "&Size=" + (string) vprimSize;
Debug(url);
if ((datum/STRIDE) % 10 == 0 && datum)
llMessageLinked(LINK_THIS,countchannel,(string) (datum/STRIDE) ,"");
kHttpRequestID = llHTTPRequest(url, [], "");
llSleep(1);
datum += STRIDE;
}
else
{
llMessageLinked(LINK_THIS,countchannel,(string) (datum/STRIDE),"");
llSleep(2.0);
llMessageLinked(LINK_THIS,countchannel,"","");
}
}
Debug(string msg)
{
if (debug)
llOwnerSay(llGetScriptName() + ":" + msg);
}
default
{
state_entry()
{
list parts = llParseString2List( llGetScriptName(),[" "],[""]);
myNum = llList2Integer(parts,1);
vRootScale = llGetScale(); // set a default of this size, the real size when recorded comes from the server
Add = Add + (10 * myNum);
Debug("DB " + (string) myNum + " is empty");
}
link_message(integer sender_num, integer num, string msg, key id)
{
//Debug("cmd:" + (string) num + ":" + msg);
// valid commands only.
if (num != Clear && num != Erase && num != Play && num != Add && num != Publish && num != Name && num!= Password)
return;
Debug("cmd rcv :" + (string) num + ":" + msg);
if (num == Clear)
{
db = []; // zero the animations
names = []; // zero names db
//Debug((string) myNum + " erased " );
full = FALSE;
recordcount = 0;
return;
}
else if (num == Add)
{
if (full)
{
Debug((string) myNum + " pass Add on to " + (string) (num +10));
llMessageLinked(LINK_THIS,num +10,msg,id);
return;
}
//Debug("Add");
list vecs = llParseString2List(msg,["|"],[""]);
// Debug(llDumpList2String(vecs,"---"));
string name= llList2String(vecs,0);
if (llListFindList(names,[name]) == -1)
names += name;
float fNum = (float) (llList2String(vecs,1));
vector vPos = (vector) (llList2String(vecs,2));
rotation rRot = (rotation) (llList2String(vecs,3));
vector vprimSize = (vector) (llList2String(vecs,4));
db += name;
db += fNum;
db += vPos;
db += rRot;
db += vprimSize;
recordcount ++;
Debug("Mem:" + (string) llGetFreeMemory() );
if (llGetFreeMemory() < 2000)
full++;
}
else if (num == Name)
{
MyName = msg;
}
else if (num == Password)
{
MyPassword = msg;
}
else if (num == Play)
{
if (llListFindList(names,[msg]) == -1)
return;
integer currpos;
integer end = recordcount * STRIDE;
// play back all we find
for (currpos = 0; currpos < end; currpos+= STRIDE)
{
if ( msg == llList2String(db,currpos) )
{
float fPrim = (float) llList2String(db,currpos+1);
vector vPos = (vector) llList2String(db,currpos+2);
rotation rRot = (rotation) llList2String (db,currpos+3);
vector vprimSize = (vector) llList2String(db,currpos+4);
if (fPrim > 1 ) // skip root prim
{
// set the local pos and locat rot to the prims orientation and position
if (llGetAttached())
rRot = rRot/llGetLocalRot();
else
rRot = rRot/llGetRootRotation();
if (GetScale())
{
vPos.x *= vScaleChange.x;
vprimSize.x *= vScaleChange.x;
vPos.y *= vScaleChange.y;
vprimSize.y *= vScaleChange.y;
vPos.z *= vScaleChange.z;
vprimSize.z *= vScaleChange.z;
}
// Debug("p=" + (string) fPrim
// + " l=" + (string) vPos
// + " r=" + (string) rRot
// + " s=" + (string) vprimSize);
llSetLinkPrimitiveParamsFast((integer) fPrim,[PRIM_POSITION,vPos,PRIM_ROTATION,rRot,PRIM_SIZE,vprimSize]);
}
else if (fPrim == 0)
{
vRootScale = (vector) msg;
Debug("Set scale to " + (string) vRootScale);
}
else if (fPrim < 0)
{
Debug("Sleep");
llSleep( fPrim * -1);
}
}
}
}
else if (num == Publish)
{
if (myNum)
llSleep(5); // time to delete the database and save the root prim
StartPublishing();
}
else if (num == Erase)
{
EraseDB();
}
else
{
Debug("Bad command");
}
}
// use for publishing in parallel
http_response(key queryid, integer status, list metadata, string data)
{
if (queryid == kHttpRequestID )
{
if (status == 200) // HTTP success status
{
Debug(data);
if (data == "ok")
{
Put();
return;
}
else if (data == "deleted")
{
llOwnerSay("Remote database is empty");
return;
}
}
else
{
llOwnerSay("Server Error loading animations");
}
}
}
}