Join us in Outworldz at www.outworldz.com:9000 or follow us:

Search dozens of selected web sites for OpenSim and LSL script

New! Script Meta-Search will search thousands of scripts here and at other sites for LSL or Opensim scripts.
Loading

Want to add a script or a project? Upload it and a half million people will see it and your name here this year.

Home   Show All
Category: Contributor: Creator
Prim Animator Archipelis scripts for prim animator  

Archipelis scripts for prim animator

An almost unlimited space prim animator. It uses multiple Store Scripts, that can hold thousands of prim animations
This is the latest version of the script. Must be used with Multiple copies of Store 0..1,2, to animate prims

Category: Prim Animator
By : Ferd Frederix
Created: 2013-09-06 Edited: 2013-09-04
Worlds: Second Life

the Zip file

Download all files for Archipelis scripts for prim animator
Contents are in zip format, with .LSL (text) source code and LSLEdit (text + Solution) formats.
Get file # 1. Animator.zip
Get file # 2. [93784 bytes] menu graphic.png
Get file # 3. Animator- stor.lsl
Get file # 4. Latest.zip
Get file # 5. Store 0.lsl
Get file # 6. Test on touchScript.lsl
Get file # 7. vtp.lsl
Get file # 8. ArchipelisBase.lsl

This script by Ferd Frederix may be used in any manner, modified, and republished.  Unless specified otherwise, my scripts are always free and open source.  Objects made with these scripts may be sold with no restrictions.  All I ask is that you point others to this location should they ask you about it and to not sell this script, unless it is for $0 L. Please help improve my work by reporting bugs and improvements.

1
2 // 06/20/2011
3 // Author Ferd Frederix
4 // Use with one or more copies of the script 'Store 0..Store 1.. Store N'
5 // Copyright 2011 Fred Beckhusen aka Ferd Frederix
6 //
7 // Licensed under the GNU Version3 license at http://www.gnu.org/copyleft/gpl.html
8 // This program and the STORE scipts it uses must be left Copy/Transfer/MOD
9 // Any items that use these scripts may have more restrictive permissions.
10
11 // for help and how to use, see "http://meteverse.mitsi.com/secondlife/Posts/Prim-Animator-DB
12
13 // Prim position root script
14 // Put this script in the root prim.
15 // touch the prim to start recording
16
17 // Record - store a new set of child prim positions
18 // Clear RAM - wipe out all recording in the prim. Leaves the database intact
19 // Pause - insert a 0.1 second pause
20 // Erase - Erases the Server data
21 // Load - Loads the data from the Server
22 // Publisgh - Saves the data to the database
23 // Recordings - Lists all recordings ( up to 16)
24 // Name - name a new recording
25 // Play All Plays back all recordings with a 1 second Pause.
26
27 // Publish - Saves to database
28 // Help - Get Web Help
29 // More - TBD
30
31 // configurable things
32
33
34
35
36 string MyName ; // The creator of the animation
37 string MyItemName; // a Name just for this unique item and any copies
38
39 integer debug = FALSE; // if set to TRUE, debug info appears
40
41 // Code follows - no need to edit below this line.
42 // remote db reading
43 key kHttpRequestID;
44
45
46 integer countLoaded = 0; // how many nanims have been loaded via HTTP
47
48 integer iPlayChannel = 1; // the playback channel, this is the channel you use in LinkMessages
49 integer countchannel= 2001; // how many have been saved
50 integer iDialogChannel ; // dialog boxes
51 integer iPrimCount ; // total number of prims
52 integer iWantNameFlag; // flag indicating we are waiting for a name to be chatted
53 integer imax; // total records in store
54 integer runtime = 0; // set to 1 after Recording and publishing.
55 // animation store
56 string sCurrentAnimationName; // The name of the animation we are playing
57 string sPriorAniName; // the prior animation name so we can spot differences as we read them in
58 list lLastPrimList; // storage of the last prim position we learned
59 integer iLastSTRIDE = 4; // size of the last prim list
60 integer iListenerHandle; // temp iListenerHandle when we are waiting for them to give us a name
61 list lUserAnimNames; // animations read from the notecard added to the Menu display
62
63
64 // Commands
65 integer Clear = 99; // erase local db
66 integer Erase = 100; // erase Server DB command
67 integer Add = 101; // add a coordinate
68 integer Publish = 102; // save to db
69 integer Name = 103; // send Name to db
70 integer thisName = 104; // send thisName to db
71 integer Play = 105; // play channel to make an animation run
72
73 Debug( string msg)
74 {
75 if(debug) llOwnerSay(msg);
76 }
77
78 // clear any old listeners and make a new on to control lag
79 NewListen()
80 {
81 iDialogChannel = (integer) (llFrand(400) + 300);
82 llListenRemove(iListenerHandle);
83 iListenerHandle = llListen(iDialogChannel,"","","");
84 }
85
86 // prompt the user for an animation name. Uses text box or chat
87 AskForName()
88 {
89 iWantNameFlag = TRUE;
91 NewListen();
92 llOwnerSay("Enter the name in the text box or type the new animation name on channel /" + (string) iDialogChannel );
93 llTextBox(llGetOwner(),"Type the new animation name",iDialogChannel);
94 }
95
96
97 Get(string data)
98 {
99 Debug("Data was " + data);
100
101 list lLine = (llParseString2List(data, ["|"], []));
102 string sAniName = llList2String(lLine,0);
103 string sNum = (string) Getline(lLine,1);
104 float fNum = (float) sNum;
105 vector vPos = (vector) Getline(lLine,2); // global for calcChild()
106 rotation rRot = (rotation) Getline(lLine,3); // global for calcChild()
107 vector vprimSize = (vector) Getline(lLine,4);
108 countLoaded++;
109 // the first record is always the root prim size
110 if(fNum == 0)
111 {
112 FetchNext();
113 return;
114 }
115
116 if(sAniName != sPriorAniName)
117 {
118 sPriorAniName = sAniName;
119 sCurrentAnimationName = sAniName;
120 if(llListFindList(lUserAnimNames,[sAniName]) == -1)
121 {
122 Debug("Loading animation " + sAniName);
123 lUserAnimNames += sAniName;
124 }
125
126 }
127 // Debug("Loading Prim #" + (string) fNum);
128 if(fNum != 1) // skip root prim
129 {
130 sCurrentAnimationName = sAniName;
131 llMessageLinked(LINK_THIS,Add,sAniName
132 +"|"
133 + (string) fNum
134 +"|"
135 + (string) vPos
136 + "|"
137 + (string) rRot
138 + "|"
139 + (string) vprimSize,"");
140
141
142
143 llSetText("Initialising... \n" + (string) (countLoaded) , <1,1,1>, 1.0);
144 }
145 llSleep(1); // http throttle avoidance
146
147 FetchNext();
148
149 }
150 // in case of hand editing, we wupe out extra stuff at end
151 string Getline(list Input, integer line)
152 {
153 return llStringTrim(llList2String(Input, line),STRING_TRIM);
154 }
155
156 Record()
157 {
158 if(llStringLength(sCurrentAnimationName) > 0)
159 {
160 integer ifoundmovement = 0; // will be set if any child moved
161 integer iPrimCounter ; // skip past the root prim
162 for (iPrimCounter =2; iPrimCounter <= iPrimCount ; iPrimCounter++ )
163 {
164 list my_list = llGetLinkPrimitiveParams(iPrimCounter,[PRIM_POSITION,PRIM_ROTATION, PRIM_SIZE ]);
165
166 // position is always in region coordinates, even if the prim is a child or the root prim of an attachment.
167 // rot is always the global rotation, even if the prim is a child or the root prim of an attachment.
168 // get current prim pos, rot and size
169
170 vector vrealPrimPos = llList2Vector(my_list,0) - llGetPos(); // position subtract Global Pos
171 vrealPrimPos /= llGetRot();
172 rotation rrealPrimRot = llList2Rot(my_list,1) / llGetRot(); // rotation subtract Global Rot
173 vector vrealPrimSize = llList2Vector(my_list,2); // size
174
175 // compare it to the last one we had, stride of list is a 4, and it is already sorted
176 integer iindex = (iPrimCounter - 2) * iLastSTRIDE; // zeroth position is fPrimCounter - start, or 2
177
178 // get the last thing we remembered about this prim
179 integer iprimNum = llList2Integer(lLastPrimList, iindex); // must be 0,1,2, in order
180 vector vlastPrimPos = llList2Vector(lLastPrimList, iindex+1);
181 rotation rlastPrimRot = llList2Rot(lLastPrimList, iindex+2);
182 vector vlastPrimSize = llList2Vector(lLastPrimList, iindex+3);
183
184 // if anything changed on this prim, we must record it.
185 if(vlastPrimPos != vrealPrimPos ||
186 rlastPrimRot != rrealPrimRot ||
187 vlastPrimSize!= vrealPrimSize
188 )
189 {
190 ifoundmovement++;
191
192 //Save them in the master list of all animations
193 llMessageLinked(LINK_THIS,Add,sCurrentAnimationName+ "|"
194 + (string) iPrimCounter
195 + "|"
196 + (string) vrealPrimPos
197 + "|"
198 + (string) rrealPrimRot
199 + "|"
200 + (string) vrealPrimSize,"");
201
202
203 imax = llGetListLength(lLastPrimList);
204 // save the changes in the last prim list so we can keep our lists smaller
205
206 lLastPrimList = llListReplaceList(lLastPrimList,[vrealPrimPos],iPrimCounter+1,iPrimCounter+1);
207 lLastPrimList = llListReplaceList(lLastPrimList,[rrealPrimRot],iPrimCounter+2,iPrimCounter+2);
208 lLastPrimList = llListReplaceList(lLastPrimList,[vrealPrimSize],iPrimCounter+3,iPrimCounter+3);
209 //Debug("Saved in history at prim # " + (string) (iPrimCounter));
210 llSleep(0.1);
211 } // if
212 else
213 {
214 Debug("Same @" + (string) iPrimCounter);
215 }
216
217 } // for
218
219 if(!ifoundmovement)
220 {
221 llOwnerSay("You must move at least one child prim.");
222 }
223
224 }
225 else
226 {
227 AskForName();
228 }
229
230 }
231
232 // on reset, record the base position in history so we can see changes
233
234 ClearRAM()
235 {
236
237 iPrimCount = llGetNumberOfPrims(); // how many we are recording
238 Debug("Prim Count = " + (string) iPrimCount);
239
240 sCurrentAnimationName = ""; // no name in use
241
242 lLastPrimList = []; // wipe last animations list
243 integer iPrimCounter ;
244 integer primCounter = 0;
245 for (iPrimCounter=2; iPrimCounter <= iPrimCount ; iPrimCounter++ ) // skip 1, which is the root prim
246 {
247 list my_list = llGetLinkPrimitiveParams(iPrimCounter,[PRIM_POSITION, PRIM_ROTATION, PRIM_SIZE ]);
248
249 // save the local pos and rot, since llGetLinkPrimitiveParams returns global pos and rot
250 vector primpos = llList2Vector(my_list,0) - llGetPos();
251 primpos /= llGetRot();
252 rotation primrot = llList2Rot(my_list,1) / llGetRot();
253
254 vector primsize = llList2Vector(my_list,2) ;
255 lLastPrimList += iPrimCounter;
256 lLastPrimList += primpos;
257 lLastPrimList += primrot;
258 lLastPrimList += primsize;
259 primCounter++;
260 }
261 llOwnerSay("RAM is cleared - Initial Settings saved for " + (string) primCounter + " child prims");
262 }
263
264
265 rotation calcChildRot(rotation rdeltaRot)
266 {
268 return rdeltaRot/llGetLocalRot();
269 else
270 return rdeltaRot/llGetRootRotation();
271 }
272
273
274 MakeMenu()
275 {
276 if(runtime)
277 {
278 MakeMenu2();
279 return;
280 }
281
282 list amenu = ["Name", "Record","Pause"] +
283 ["Erase","Load","Publish"] +
284 ["Recordings","-","Play All"] +
285 ["Help","-", "Finish"];
286
287 string menuText = "Available Memory: " + (string) llGetFreeMemory() +
288 "\n\n" +
289 "Recordings: Select a named animation\n" +
290 "Name: Set the animation name\n" +
291 "Play All: Play all animations\n" +
292 "Erase: Delete Recorded Data\n" +
293 "Load: Get from Server\n" +
294 "Publish: Save to Server\n" +
295 "Record: Record a snapshot of prim positions\n" +
296 "Pause: Insert 0.1 second pause\n" +
297 "Finish: End all programming\n" +
298 "Help: Help";
299
300 NewListen();
301 llDialog(llGetOwner(), menuText,amenu,iDialogChannel);
302
303 }
304
305 MakeMenu2()
306 {
307 string menuText ;
308 list menu2 = lUserAnimNames;
309 menu2 = llDeleteSubList(menu2,11,999); // 12 max
310
311 if(runtime)
312 menu2 += "Unlock";
313 if(llGetListLength(lUserAnimNames) == 0)
314 {
315 menu2 += ["Back"] ;
316 menuText = " There are no animation names to display\n\n" +
317 "Back:- Go back to programming menu";
318 }
319 else
320 menuText = "Pick an animation to play.";
321
322 NewListen();
323 llDialog(llGetOwner(), menuText,menu2,iDialogChannel);
324 }
325
326
327 FetchNext()
328 {
329 string url = "http://metaverse.mitsi.com/cgi/animate.plx?Type=Load&Count=" + (string) countLoaded + "&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyItemName);
330 Debug(url);
331
332 kHttpRequestID = llHTTPRequest(url, [], "");
333 }
334
335
336 default
337 {
339 {
340 MyName = llGetCreator(); // assign the creator if we get reset
341 MyItemName = llGetObjectDesc(); // and get the name of the Object
342 llOwnerSay("Animation name from the description is " + MyItemName);
343
344 if(MyItemName == "(No Description)" || llStringLength(MyItemName) == 0)
345 {
346 MyItemName = "Archipelis_" + (string) (llCeil(llFrand(200000) + 5000000)); // pick a large random number for a name
347 llOwnerSay("Animations will be saved as '" + MyItemName + "'");
348 llSetObjectDesc(MyItemName);
349 }
350
351
352 llMessageLinked(LINK_THIS,Name,MyName,"");
353 llMessageLinked(LINK_THIS,thisName,MyItemName,"");
354
355 if(runtime)
356 {
357 ClearRAM();
358 FetchNext(); // start with first line in DB
359 }
360 else
361 {
362 ClearRAM();
363 }
364 }
365
366 http_response(key queryid, integer status, list metadata, string data)
367 {
368 if(queryid == kHttpRequestID )
369 {
370 if(status == 200) // HTTP success status
371 {
372 if(data == "nothing to do")
373 {
374 llOwnerSay("Initialized with " + (string) countLoaded + " settings");
375 llSetText("" , <1,1,1>, 1.0);
376 return;
377 }
378 Get(data);
379 }
380 else
381 {
382 llOwnerSay("Server Error loading animations");
383 }
384 }
385 }
386
387 touch_start(integer total_number)
388 {
390 {
391 MakeMenu();
392 }
393 }
394
395 // timed out waitig for a name of an animation
396 timer()
397 {
398 iWantNameFlag = FALSE;
400 llOwnerSay(" Timeout waiting for animation name");
401 llListenRemove(iListenerHandle);
402 }
403
404 listen( integer channel, string name, key id, string message )
405 {
406 llListenRemove(iListenerHandle);
407 // Debug(message);
408
409 if(message == "Finish")
410 {
411 runtime++;
412 llOwnerSay("The animator is now locked. Further touches will bring up a list of animations. You must unlock the menu to add more animations");
413 }
414 else if(message == "Unlock")
415 {
416 runtime = 0;
417 llOwnerSay("The animator is now unlocked for programming.");
418 }
419
420 else if(message == "Erase")
421 {
422 ClearRAM();
423 llMessageLinked(LINK_THIS,Erase,"",""); // erase the db
424 MakeMenu();
425 }
426 else if(message =="Pause")
427 {
428 llMessageLinked(LINK_THIS,Add,"sCurrentAnimationName|"
429 + "-0.1" // sleep 1 tenth a second
430 + "|"
431 + "<0,0,0>" // null pos
432 + "<0,0,0,1>" // null rot
433 + "|"
434 + "<0,0,0>",""); // null size
435 MakeMenu();
436 }
437 else if(message == "Recordings")
438 {
439 MakeMenu2();
440 }
441 else if(message == "Load")
442 {
443 countLoaded = 0;
444 FetchNext(); // start with first line in DB
445 }
446 else if(message == "Record")
447 {
448 Record();
449 MakeMenu();
450 }
451 else if(message == "Publish")
452 {
453 llMessageLinked(LINK_THIS,Name,MyName,""); // in case we reset just the stores
454 llMessageLinked(LINK_THIS,thisName,MyItemName,"");
455 llMessageLinked(LINK_THIS,Publish,"","");
456 MakeMenu();
457 }
458 else if(message == "Name")
459 {
460 AskForName();
461 }
462 else if(message == "Back")
463 {
464 MakeMenu();
465 }
466 else if(message == "More")
467 {
468 MakeMenu();
469 }
470 else if(message == "Play All")
471 {
472 integer l = llGetListLength(lUserAnimNames);
473 if(l == 0)
474 llOwnerSay("Nothing to do");
475 else
476 {
477 integer i = 0;
478 for ( i = 0; i < l; i++)
479 {
480 string ani = llList2String(lUserAnimNames,i);
481 llMessageLinked(LINK_THIS,Play,ani,"");
482 llSleep(1);
483 }
484 }
485 MakeMenu();
486
487 }
488 else if(message == "Help")
489 {
490 llLoadURL(llGetOwner(),"View online help", "http://metaverse.mitsi.com/secondlife/Posts/Prim-Animator-DB");
491 }
492 else if(iWantNameFlag)
493 {
494 sCurrentAnimationName = message;
495 if(llGetListLength(lUserAnimNames) < 11)
496 {
497 if(llListFindList(lUserAnimNames,[sCurrentAnimationName]) == -1)
498 lUserAnimNames += message;
499 }
500 else
501 {
502 lUserAnimNames = llDeleteSubList(lUserAnimNames,11,99);
503 }
504
505 MakeMenu();
506
507 llOwnerSay("Ready to record animation '" + sCurrentAnimationName + "'");
508 llOwnerSay("Position all child prims, then select the Menu item 'Record', and repeat as necessary. When finished, click 'Recordings' to play back the animation. Click 'Name' again to start a new animation sequence.");
509
510 iWantNameFlag = 0;
512 }
513 else
514 {
515 if(llListFindList(lUserAnimNames,[message]) != -1)
516 {
517 Debug("playback animation " + message);
518 llMessageLinked(LINK_THIS,Play,message,"");
519 MakeMenu();
520 }
521 }
522 }
523
524 link_message(integer sender_num, integer num, string message, key id)
525 {
526 if(num == countchannel)
527 {
528 llSetText("Loaded " + message,<1,1,1>,1.0);
529 }
530 else if(num == iPlayChannel) // external messages come in channel 1 - change them to channel Play
531 {
532 Debug("playback animation " + message);
533 llMessageLinked(LINK_THIS,Play,message,"");
534 }
535 }
536
537
538 }
539
540
541 ਊ

Archipelis scripts for prim animator

Prim storage Script
Should be named Store 0, Store 1 Stor32 etc.
As you need more storage, just copy it and increment the number

Category: Prim Animator
By : Ferd Frederix
Created: 2013-09-06 Edited: 2013-09-04
Worlds: Second Life


This script by Ferd Frederix may be used in any manner, modified, and republished.  Unless specified otherwise, my scripts are always free and open source.  Objects made with these scripts may be sold with no restrictions.  All I ask is that you point others to this location should they ask you about it and to not sell this script, unless it is for $0 L. Please help improve my work by reporting bugs and improvements.

1
2 // Prim Animator DB
3 // 06/20/2011
4 // Author Ferd Frederix
5
6 // Prim Storage script.
7 // Copyright 2011 Fred Beckhusen - all rights reserved
8
9
10 integer debug =FALSE;
11 // return codes
12 integer playchannel = 2000; // the script to do the actual playback
13 integer countchannel= 2001; // the script to do the actual playback
14
15 // constants
16 integer MAX = 999; // Maximum number of anims per script, if set to very high, oit clamps with free memory < 1000
17 integer full = FALSE; // this script RAM is full
18
19
20 // Commands
21 integer Erase = 100; // erase command
22 integer Add = 101; // add a coordinate
23 integer Publish = 102; // save to db
24 integer Name = 103; // send Name to db
25 integer Password = 104; // send Password to db
26 integer Play = 105; //
27
28 // vars
29 integer myNum = 0; // the number at the end of this script name 0, 1, 2....
30 integer imax; // total records in store
31 integer datum; // the load counter increments as we load anims from db
32 string MyName;
33 string MyPassword;
34
35
36 // remote db reading
37 key kHttpRequestID;
38
39 // lists
40 list names; // a list of distnct animation names stored here
41 list db; // name, prin num, pos, rot, size
42 integer STRIDE = 5; // 4 items in the above list
43 integer recordcount = 0; // how many anims are stored
44
45
46 vector vRootScale ; // the initial size when the prims were recorded
47 vector vScaleChange = <1,1,1>; // The change percent if resized
48
49 GetScale(vector orig_size)
50 {
51 //Debug ("Size:" + (string) orig_size);
52 vRootScale = orig_size; // save the size when we recorded the prims
53 vector newScale = llGetScale();
54 vScaleChange.x = newScale.x / vRootScale.x;
55 vScaleChange.y = newScale.y / vRootScale.y;
56 vScaleChange.z = newScale.z / vRootScale.z;
57
58 }
59
60
61 rotation calcChildRot(rotation rdeltaRot)
62 {
64 return rdeltaRot/llGetLocalRot();
65 else
66 return rdeltaRot/llGetRootRotation();
67 }
68 // Start saving records. The first record is the prim size.
69
70 StartPublishing ()
71 {
72 imax = llGetListLength(db);
73 datum = 0; // point to the first record, counts as we load records
74 integer howmany = imax / STRIDE ;
75 llOwnerSay((string) howmany + " movements recorded - now saving to server.");
76 string url;
77
78 // cannot save or delete unless we are the first prim to Publish
79 string save;
80 string erase = "0";
81 if(myNum == 0) {
82 erase = "1";
83 save = "Save";
84 }
85
86 //Debug( "Saving Size:" + (string) llGetScale());
87 url = "http://secondlife.mitsi.com/cgi/animate.plx?Type=";
88 url += save;
89 url += "&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyPassword);
90 url += "&Delete=";
91 url += erase;
92 url += "&aniName=RootPosition" ;
93 url += "&PrimNum=" + (string) 0;
94 url += "&Size=" + (string) llGetScale(); // save the scale as the first record
95 url += "&Pos=<1,1,1>" ;
96 url += "&Rot=<0,0,0,1>" ;
97
98 Debug(url);
99 kHttpRequestID = llHTTPRequest(url, [], "");
100 }
101
102
103
104 Put()
105 {
106 if(datum < imax)
107 {
108 string sAniName = llList2String(db, datum);
109 float fprimNum = llList2Float(db, datum+1);
110 vector vprimPos = llList2Vector(db, datum+2);
111 rotation rprimRot = llList2Rot(db, datum+3) ;
112 vector vprimSize = llList2Vector(db, datum+4);
113
114 string url = "http://secondlife.mitsi.com/cgi/animate.plx?Type=Save&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyPassword);
115 url += "&aniName=" + llEscapeURL(sAniName);
116 url += "&PrimNum=" + (string) fprimNum;
117 url += "&Pos=" + (string) vprimPos;
118 url += "&Rot=" + (string) rprimRot;
119 url += "&Size=" + (string) vprimSize;
120
121 Debug(url);
122 if((datum/STRIDE) % 10 == 0 && datum)
123 llMessageLinked(LINK_THIS,countchannel,"Saved " + (string) (datum/STRIDE) + " records","");
124
125
126 kHttpRequestID = llHTTPRequest(url, [], "");
127 llSleep(1);
128 datum += STRIDE;
129 }
130 else
131 {
132 llMessageLinked(LINK_THIS,countchannel,(string) (datum/STRIDE) + " movements saved.","");
133 llSleep(2.0);
134 llMessageLinked(LINK_THIS,countchannel,"","");
135 }
136
137 }
138
139
140 Debug(string msg)
141 {
142 if(debug)
143 llOwnerSay(llGetScriptName() + ":" + msg);
144 }
145
146
147 default
148 {
150 {
151 string name = llGetScriptName();
152 list parts = llParseString2List(name,[" "],[""]);
153 myNum = llList2Integer(parts,1);
154
155 vRootScale = llGetScale();
156 Add += 10 * myNum;
157 }
158
159 link_message(integer sender_num, integer num, string msg, key id)
160 {
161
162 Debug("cmd:" + (string) num + ":" + msg);
163
164 // valid commands only.
165 if(num != Erase && num != Play && num != Add && num != Publish && num != Name && num!= Password)
166 return;
167
168 Debug("cmd:" + (string) num + ":" + msg);
169
170
171 if(num == Erase)
172 {
173 db = [];
174 Debug((string) myNum + " erased " );
175 full = FALSE;
176 recordcount = 0;
177 return;
178 }
179 else if(num == Add)
180 {
181 if(full)
182 {
183 Debug((string) myNum + " pass Add on to " + (string) (num +10));
184 llMessageLinked(LINK_THIS,num +10,msg,id);
185 return;
186 }
187
188 //Debug("Add");
189 list vecs = llParseString2List(msg,["|"],[""]);
190
191 // Debug(llDumpList2String(vecs,"---"));
192 string name= llList2String(vecs,0);
193 if(llListFindList(names,[name]) == -1)
194 names += name;
195
196 float fNum = (float) (llList2String(vecs,1));
197 vector vPos = (vector) (llList2String(vecs,2));
198 rotation rRot = (rotation) (llList2String(vecs,3));
199 vector vprimSize = (vector) (llList2String(vecs,4));
200
201 db += name;
202 db += fNum;
203 db += vPos;
204 db += rRot;
205 db += vprimSize;
206
207 recordcount ++;
208 Debug("Store contains " + (string) recordcount + "Records");
209 //if(recordcount> MAX)
210 //{
211 // Debug("Full, record count = " + (string) recordcount);
212 // full++;
213 //}
214 if(llGetFreeMemory() < 1000)
215 {
216 Debug("Full");
217 full++;
218 }
219
220 Debug("Free:" + (string) llGetFreeMemory());
221 }
222 else if(num == Name)
223 {
224 MyName = msg;
225 }
226 else if(num == Password)
227 {
228 MyPassword = msg;
229 }
230 else if(num == Play)
231 {
232 if(llListFindList(names,[msg]) == -1)
233 {
234 Debug("Animation " + msg + " not found");
235 return;
236 }
237 integer currpos;
238 integer end = recordcount * STRIDE;
239 // play back all we find
240 for (currpos = 0; currpos < end; currpos+= STRIDE)
241 {
242 if( msg == llList2String(db,currpos) )
243 {
244 float fPrim = (float) llList2String(db,currpos+1);
245 vector vPos = (vector) llList2String(db,currpos+2);
246 rotation rRot = (rotation) llList2String(db,currpos+3);
247 vector vprimSize = (vector) llList2String(db,currpos+4);
248
249 //Debug(msg + "|" + spos + "|" + srot + "|" + sthesize);
250 GetScale(vRootScale); // original prim size
251
252 // set the local pos and locat rot to the prims orientation and position
253 rRot = calcChildRot(rRot);
254
255 if(fPrim < 0)
256 {
257 //DebugllOwnerSay("Sleeping " + (string) (fprimNum * -1));
258 llSleep( fPrim * -1);
259 }
260 else if(fPrim > 1 ) // skip root prim
261 {
262 vPos.x *= vScaleChange.x;
263 vprimSize.x *= vScaleChange.x;
264
265 vPos.y *= vScaleChange.y;
266 vprimSize.y *= vScaleChange.y;
267
268 vPos.z *= vScaleChange.z;
269 vprimSize.z *= vScaleChange.z;
270
271 Debug("p=" + (string) fPrim
272 + " l=" + (string) vPos
273 + " r=" + (string) rRot
274 + " s=" + (string) vprimSize);
275
276 llSetLinkPrimitiveParamsFast((integer) fPrim,[PRIM_POSITION,vPos,PRIM_ROTATION,rRot,PRIM_SIZE,vprimSize]);
277 }
278 }
279 }
280 }
281 else if(num == Publish)
282 {
283 if(myNum)
284 llSleep(5); // time to delete the database and save the root prim
285 StartPublishing();
286 }
287 else
288 {
289 Debug("Bad command");
290 }
291 }
292
293
294 // use for publishing in parallel
295 http_response(key queryid, integer status, list metadata, string data)
296 {
297 if(queryid == kHttpRequestID )
298 {
299 if(status == 200) // HTTP success status
300 {
301 Debug(data);
302 if(data == "ok")
303 {
304 Put();
305 return;
306 }
307 }
308 else
309 {
310 llOwnerSay("Server Error loading animations");
311 }
312 }
313 }
314
315
316 }

Archipelis scripts for prim animator

When touched will trigger an animation named "jump"

Category: Prim Animator
By : Ferd Frederix
Created: 2013-09-06 Edited: 2013-09-04
Worlds: Second Life


This script by Ferd Frederix may be used in any manner, modified, and republished.  Unless specified otherwise, my scripts are always free and open source.  Objects made with these scripts may be sold with no restrictions.  All I ask is that you point others to this location should they ask you about it and to not sell this script, unless it is for $0 L. Please help improve my work by reporting bugs and improvements.

1
2
3 default
4 {
6 {
7
8 }
9
10
11 touch_start(integer count)
12 {
13 llMessageLinked(LINK_SET, 1,"jump","");
14 }
15 }

Archipelis scripts for prim animator

Prim storage renumber animation recorder
- Not a fully debugged useful script.
It tries to make each prim have a number that matches the prim animator numbers so you can add more prims.

Category: Prim Animator
By : Ferd Frederix
Created: 2013-09-06 Edited: 2013-09-04
Worlds: Second Life


This script by Ferd Frederix may be used in any manner, modified, and republished.  Unless specified otherwise, my scripts are always free and open source.  Objects made with these scripts may be sold with no restrictions.  All I ask is that you point others to this location should they ask you about it and to not sell this script, unless it is for $0 L. Please help improve my work by reporting bugs and improvements.

1
2
3 // Prim Animator DB
4 // 06/20/2011
5 // Author Ferd Frederix
6 // Use with one or more copies of the script 'Store 0..Store 1.. Store N'
7 // Copyright 2011 Fred Beckhusen aka Ferd Frederix
8 //
9 // Licensed under the GNU Version3 license at http://www.gnu.org/copyleft/gpl.html
10 // This program and the STORE scipts it uses must be left Copy/Transfer/MOD
11 // Any items that use these scripts may have more restrictive permissions.
12
13 // for help and how to use, see "http://meteverse.mitsi.com/secondlife/Posts/Prim-Animator-DB
14
15 // Prim position root script
16 // Put this script in the root prim.
17 // touch the prim to start recording
18
19 // Record - store a new set of child prim positions
20 // Clear RAM - wipe out all recording in the prim. Leaves the database intact
21 // Pause - insert a 0.1 second pause
22 // Erase - Erases the Server data
23 // Load - Loads the data from the Server
24 // Publisgh - Saves the data to the database
25 // Recordings - Lists all recordings ( up to 16)
26 // Name - name a new recording
27 // Play All Plays back all recordings with a 1 second Pause.
28
29 // Publish - Saves to database
30 // Help - Get Web Help
31 // More - TBD
32
33 // configurable things
34
35
36
37
38 string MyName ; // The creator of the animation
39 string MyItemName; // a Name just for this unique item and any copies
40
41 integer debug = TRUE; // if set to TRUE, debug info appears
42
43 // Code follows - no need to edit below this line.
44 // remote db reading
45 key kHttpRequestID;
46
47
48 integer countLoaded = 0; // how many nanims have been loaded via HTTP
49
50 integer iPlayChannel = 1; // the playback channel, this is the channel you use in LinkMessages
51 integer countchannel= 2001; // how many have been saved
52 integer iDialogChannel ; // dialog boxes
53 integer iPrimCount ; // total number of prims
54 integer iWantNameFlag; // flag indicating we are waiting for a name to be chatted
55 integer imax; // total records in store
56 integer runtime = 0; // set to 1 after Recording and publishing.
57 // animation store
58 string sCurrentAnimationName; // The name of the animation we are playing
59 string sPriorAniName; // the prior animation name so we can spot differences as we read them in
60 list lLastPrimList; // storage of the last prim position we learned
61 integer iLastSTRIDE = 4; // size of the last prim list
62 integer iListenerHandle; // temp iListenerHandle when we are waiting for them to give us a name
63 list lUserAnimNames; // animations read from the notecard added to the Menu display
64
65
66 // Commands
67 integer Clear = 99; // erase local db
68 integer Erase = 100; // erase Server DB command
69 integer Add = 101; // add a coordinate
70 integer Publish = 102; // save to db
71 integer Name = 103; // send Name to db
72 integer thisName = 104; // send thisName to db
73 integer Play = 105; // play channel to make an animation run
74
75 list NameNum; // 2 stride list of real vs virtual numbers of prims
76
77 Debug( string msg)
78 {
79 if(debug) llOwnerSay(msg);
80 }
81
82
83 integer getVirtual(integer real)
84 {
85 llOwnerSay("Seeking " + (string) real);
86 integer i;
87 integer num = llGetListLength(NameNum);
88 for (i = 0 ; i < num; i += 2)
89 {
90 llOwnerSay("Examine " + (string) i);
91 if(llList2Integer(NameNum,i) == real)
92 {
93 llOwnerSay("Located " + (string) real);
94 return (real);
95 }
96 }
97
98 integer new = i/2 +1;
99 llOwnerSay("Returning " + (string) new);
100 return new;
101 }
102
103 Renumber()
104 {
105 integer realPrimNum ;
106 for ( realPrimNum = 2; realPrimNum < iPrimCount; realPrimNum++)
107 {
108 list name = llGetLinkPrimitiveParams(realPrimNum,[PRIM_DESC] );
109
110 integer num = (integer) llList2String(name,0);
111 if(num == realPrimNum)
112 {
113 NameNum += num;
114 NameNum += num;
115 }
116 else
117 {
118 integer newNum = getVirtual(realPrimNum); // get the next unused prim Number
119 string newname = generate_index(newNum); // make 2 digits
120 llSetLinkPrimitiveParamsFast(realPrimNum,[ PRIM_DESC,newname ]); // save it
121 NameNum += (integer) newname; // save it in the Real to Virtual List
122 NameNum += num;
123 }
124 }
125
126 llOwnerSay(llDumpList2String(NameNum,","));
127
128 }
129
130 // get a 2-digit string fiven a number
131 string generate_index(integer i)
132 {
133 if(i < 10)
134 return "0" + (string)i;
135
136 return (string)i;
137 }
138
139
140 // clear any old listeners and make a new on to control lag
141 NewListen()
142 {
143 iDialogChannel = (integer) (llFrand(400) + 300);
144 llListenRemove(iListenerHandle);
145 iListenerHandle = llListen(iDialogChannel,"","","");
146 }
147
148 // prompt the user for an animation name. Uses text box or chat
149 AskForName()
150 {
151 iWantNameFlag = TRUE;
153 NewListen();
154 llOwnerSay("Enter the name in the text box or type the new animation name on channel /" + (string) iDialogChannel );
155 llTextBox(llGetOwner(),"Type the new animation name",iDialogChannel);
156 }
157
158
159 Get(string data)
160 {
161 Debug("Data was " + data);
162
163 list lLine = (llParseString2List(data, ["|"], []));
164 string sAniName = llList2String(lLine,0);
165 string sNum = (string) Getline(lLine,1);
166 float fNum = (float) sNum;
167 vector vPos = (vector) Getline(lLine,2); // global for calcChild()
168 rotation rRot = (rotation) Getline(lLine,3); // global for calcChild()
169 vector vprimSize = (vector) Getline(lLine,4);
170 countLoaded++;
171 // the first record is always the root prim size
172 if(fNum == 0)
173 {
174 FetchNext();
175 return;
176 }
177
178 if(sAniName != sPriorAniName)
179 {
180 sPriorAniName = sAniName;
181 sCurrentAnimationName = sAniName;
182 if(llListFindList(lUserAnimNames,[sAniName]) == -1)
183 {
184 Debug("Loading animation " + sAniName);
185 lUserAnimNames += sAniName;
186 }
187
188 }
189 // Debug("Loading Prim #" + (string) fNum);
190 if(fNum != 1) // skip root prim
191 {
192 sCurrentAnimationName = sAniName;
193 llMessageLinked(LINK_THIS,Add,sAniName
194 +"|"
195 + (string) fNum
196 +"|"
197 + (string) vPos
198 + "|"
199 + (string) rRot
200 + "|"
201 + (string) vprimSize,"");
202
203
204
205 llSetText("Initialising... \n" + (string) (countLoaded) , <1,1,1>, 1.0);
206 }
207 llSleep(1); // http throttle avoidance
208
209 FetchNext();
210
211 }
212 // in case of hand editing, we wupe out extra stuff at end
213 string Getline(list Input, integer line)
214 {
215 return llStringTrim(llList2String(Input, line),STRING_TRIM);
216 }
217
218 Record()
219 {
220 if(llStringLength(sCurrentAnimationName) > 0)
221 {
222 integer ifoundmovement = 0; // will be set if any child moved
223 integer iPrimCounter ; // skip past the root prim
224 for (iPrimCounter =2; iPrimCounter <= iPrimCount ; iPrimCounter++ )
225 {
226 list my_list = llGetLinkPrimitiveParams(iPrimCounter,[PRIM_POSITION,PRIM_ROTATION, PRIM_SIZE ]);
227
228 // position is always in region coordinates, even if the prim is a child or the root prim of an attachment.
229 // rot is always the global rotation, even if the prim is a child or the root prim of an attachment.
230 // get current prim pos, rot and size
231
232 vector vrealPrimPos = llList2Vector(my_list,0) - llGetPos(); // position subtract Global Pos
233 vrealPrimPos /= llGetRot();
234 rotation rrealPrimRot = llList2Rot(my_list,1) / llGetRot(); // rotation subtract Global Rot
235 vector vrealPrimSize = llList2Vector(my_list,2); // size
236
237 // compare it to the last one we had, stride of list is a 4, and it is already sorted
238 integer iindex = (iPrimCounter - 2) * iLastSTRIDE; // zeroth position is fPrimCounter - start, or 2
239
240 // get the last thing we remembered about this prim
241 integer iprimNum = llList2Integer(lLastPrimList, iindex); // must be 0,1,2, in order
242 vector vlastPrimPos = llList2Vector(lLastPrimList, iindex+1);
243 rotation rlastPrimRot = llList2Rot(lLastPrimList, iindex+2);
244 vector vlastPrimSize = llList2Vector(lLastPrimList, iindex+3);
245
246 // if anything changed on this prim, we must record it.
247 if(vlastPrimPos != vrealPrimPos ||
248 rlastPrimRot != rrealPrimRot ||
249 vlastPrimSize!= vrealPrimSize
250 )
251 {
252 ifoundmovement++;
253
254 //Save them in the master list of all animations
255 llMessageLinked(LINK_THIS,Add,sCurrentAnimationName+ "|"
256 + (string) iPrimCounter
257 + "|"
258 + (string) vrealPrimPos
259 + "|"
260 + (string) rrealPrimRot
261 + "|"
262 + (string) vrealPrimSize,"");
263
264
265 imax = llGetListLength(lLastPrimList);
266 // save the changes in the last prim list so we can keep our lists smaller
267
268 lLastPrimList = llListReplaceList(lLastPrimList,[vrealPrimPos],iPrimCounter+1,iPrimCounter+1);
269 lLastPrimList = llListReplaceList(lLastPrimList,[rrealPrimRot],iPrimCounter+2,iPrimCounter+2);
270 lLastPrimList = llListReplaceList(lLastPrimList,[vrealPrimSize],iPrimCounter+3,iPrimCounter+3);
271 //Debug("Saved in history at prim # " + (string) (iPrimCounter));
272 llSleep(0.1);
273 } // if
274 else
275 {
276 Debug("Same @" + (string) iPrimCounter);
277 }
278
279 } // for
280 //Debug("history:" + llDumpList2String(lLastPrimList,":"));
281 //Debug("master:" + llDumpList2String(lAniStore," "));
282
283 if(!ifoundmovement)
284 {
285 llOwnerSay("You must move at least one child prim.");
286 }
287
288 }
289 else
290 {
291 AskForName();
292 }
293
294 }
295
296 // on reset, record the base position in history so we can see changes
297
298 ClearRAM()
299 {
300
301 iPrimCount = llGetNumberOfPrims(); // how many we are recording
302 Debug("Prim Count = " + (string) iPrimCount);
303
304 sCurrentAnimationName = ""; // no name in use
305
306 lLastPrimList = []; // wipe last animations list
307 integer iPrimCounter ;
308 integer primCounter = 0;
309 for (iPrimCounter=2; iPrimCounter <= iPrimCount ; iPrimCounter++ ) // skip 1, which is the root prim
310 {
311 list my_list = llGetLinkPrimitiveParams(iPrimCounter,[PRIM_POSITION, PRIM_ROTATION, PRIM_SIZE ]);
312
313 // save the local pos and rot, since llGetLinkPrimitiveParams returns global pos and rot
314 vector primpos = llList2Vector(my_list,0) - llGetPos();
315 primpos /= llGetRot();
316 rotation primrot = llList2Rot(my_list,1) / llGetRot();
317
318 vector primsize = llList2Vector(my_list,2) ;
319 lLastPrimList += iPrimCounter;
320 lLastPrimList += primpos;
321 lLastPrimList += primrot;
322 lLastPrimList += primsize;
323 primCounter++;
324 }
325 llOwnerSay("RAM is cleared - Initial Settings saved for " + (string) primCounter + " child prims");
326 }
327
328
329 rotation calcChildRot(rotation rdeltaRot)
330 {
332 return rdeltaRot/llGetLocalRot();
333 else
334 return rdeltaRot/llGetRootRotation();
335 }
336
337
338 MakeMenu()
339 {
340 if(runtime)
341 {
342 MakeMenu2();
343 return;
344 }
345
346 list amenu = ["Record","Clear RAM","Pause"] +
347 ["Erase","Load","Publish"] +
348 ["Recordings","Name","Play All"] +
349 ["Help","More", "Finish"];
350
351 string menuText = "Available Memory: " + (string) llGetFreeMemory() +
352 "\n\n" +
353 "Recordings: Select a named animation\n" +
354 "Name: Set the animation name\n" +
355 "Play All: Play all animations\n" +
356 "Clear RAM: Erase SL memory\n"+
357 "Erase: Delete Server Data\n" +
358 "Load: Get from Server\n" +
359 "Publish: Save to Server\n" +
360 "Record: Record a snapshot of prim positions\n" +
361 "Pause: Insert 0.1 second pause\n" +
362 "Finish: End all programming\n" +
363 "Help: Help";
364
365 NewListen();
366 llDialog(llGetOwner(), menuText,amenu,iDialogChannel);
367
368 }
369
370 MakeMenu2()
371 {
372 string menuText ;
373 list menu2 = lUserAnimNames;
374 menu2 = llDeleteSubList(menu2,11,999); // 12 max
375
376 if(runtime)
377 menu2 += "Unlock";
378 if(llGetListLength(lUserAnimNames) == 0)
379 {
380 menu2 += ["Back"] ;
381 menuText = " There are no animation names to display\n\n" +
382 "Back:- Go back to programming menu";
383 }
384 else
385 menuText = "Pick an animation to play.";
386
387 NewListen();
388 llDialog(llGetOwner(), menuText,menu2,iDialogChannel);
389 }
390
391
392 FetchNext()
393 {
394 string url = "http://metaverse.mitsi.com/cgi/animate.plx?Type=Load&Count=" + (string) countLoaded + "&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyItemName);
395 Debug(url);
396
397 kHttpRequestID = llHTTPRequest(url, [], "");
398 }
399
400
401 default
402 {
404 {
405 MyName = llGetOwner(); // assign the owner if we get reset
406 MyItemName = llGetObjectDesc(); // and get the name of the Object
407 llOwnerSay("Animation name from the description is " + MyItemName);
408
409 if(MyItemName == "(No Description)" || llStringLength(MyItemName) == 0)
410 {
411 MyItemName = "Archipelis_" + (string) (llCeil(llFrand(200000) + 5000000)); // pick a large random number for a name
412 llOwnerSay("Animations will be saved as '" + MyItemName + "'");
413 llSetObjectDesc(MyItemName);
414 }
415
416 llMessageLinked(LINK_THIS,Name,MyName,"");
417 llMessageLinked(LINK_THIS,thisName,MyItemName,"");
418
419
420
421
422 if(runtime)
423 {
424 ClearRAM();
425 FetchNext(); // start with first line in DB
426 }
427 else
428 {
429 ClearRAM();
430 }
431
432 Renumber();
433
434 }
435
436 http_response(key queryid, integer status, list metadata, string data)
437 {
438 if(queryid == kHttpRequestID )
439 {
440 if(status == 200) // HTTP success status
441 {
442 if(data == "nothing to do")
443 {
444 llOwnerSay("Initialized with " + (string) countLoaded + " settings");
445 llSetText("" , <1,1,1>, 1.0);
446 return;
447 }
448 Get(data);
449 }
450 else
451 {
452 llOwnerSay("Server Error loading animations");
453 }
454 }
455 }
456
457 touch_start(integer total_number)
458 {
460 {
461 MakeMenu();
462 }
463 }
464
465 // timed out waitig for a name of an animation
466 timer()
467 {
468 iWantNameFlag = FALSE;
470 llOwnerSay(" Timeout waiting for animation name");
471 llListenRemove(iListenerHandle);
472 }
473
474 listen( integer channel, string name, key id, string message )
475 {
476 llListenRemove(iListenerHandle);
477 // Debug(message);
478
479 if(message == "Finish")
480 {
481 runtime++;
482 llOwnerSay("The animator is now locked. Further touches will bring up a list of animations. You must unlock the menu to add more animations");
483 }
484 else if(message == "Unlock")
485 {
486 runtime = 0;
487 llOwnerSay("The animator is now unlocked for programming.");
488 }
489
490 else if(message == "Erase")
491 {
492 llMessageLinked(LINK_THIS,Erase,"",""); // erase the db
493 MakeMenu();
494 }
495 else if(message == "Clear RAM")
496 {
497 ClearRAM();
498 MakeMenu();
499 }
500 else if(message =="Pause")
501 {
502 llMessageLinked(LINK_THIS,Add,"sCurrentAnimationName|"
503 + "-0.1" // sleep 1 tenth a second
504 + "|"
505 + "<0,0,0>" // null pos
506 + "<0,0,0,1>" // null rot
507 + "|"
508 + "<0,0,0>",""); // null size
509 MakeMenu();
510 }
511 else if(message == "Recordings")
512 {
513 MakeMenu2();
514 }
515 else if(message == "Load")
516 {
517 countLoaded = 0;
518 FetchNext(); // start with first line in DB
519 }
520 else if(message == "Record")
521 {
522 Record();
523 MakeMenu();
524 }
525 else if(message == "Publish")
526 {
527 llMessageLinked(LINK_THIS,Name,MyName,""); // in case we reset just the stores
528 llMessageLinked(LINK_THIS,thisName,MyItemName,"");
529 llMessageLinked(LINK_THIS,Publish,"","");
530 MakeMenu();
531 }
532 else if(message == "Name")
533 {
534 AskForName();
535 }
536 else if(message == "Back")
537 {
538 MakeMenu();
539 }
540 else if(message == "More")
541 {
542 MakeMenu();
543 }
544 else if(message == "Play All")
545 {
546 integer l = llGetListLength(lUserAnimNames);
547 if(l == 0)
548 llOwnerSay("Nothing to do");
549 else
550 {
551 integer i = 0;
552 for ( i = 0; i < l; i++)
553 {
554 string ani = llList2String(lUserAnimNames,i);
555 llMessageLinked(LINK_THIS,Play,ani,"");
556 llSleep(1);
557 }
558 }
559 MakeMenu();
560
561 }
562 else if(message == "Help")
563 {
564 llLoadURL(llGetOwner(),"View online help", "http://metaverse.mitsi.com/secondlife/Posts/Prim-Animator-DB");
565 }
566 else if(iWantNameFlag)
567 {
568 sCurrentAnimationName = message;
569 if(llGetListLength(lUserAnimNames) < 11)
570 {
571 if(llListFindList(lUserAnimNames,[sCurrentAnimationName]) == -1)
572 lUserAnimNames += message;
573 }
574 else
575 {
576 lUserAnimNames = llDeleteSubList(lUserAnimNames,11,99);
577 }
578
579 MakeMenu();
580
581 llOwnerSay("Ready to record animation '" + sCurrentAnimationName + "'");
582 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.");
583
584 iWantNameFlag = 0;
586 }
587 else
588 {
589 if(llListFindList(lUserAnimNames,[message]) != -1)
590 {
591 Debug("playback animation " + message);
592 llMessageLinked(LINK_THIS,Play,message,"");
593 MakeMenu();
594 }
595 }
596 }
597
598 link_message(integer sender_num, integer num, string message, key id)
599 {
600 if(num == countchannel)
601 {
602 llSetText("Loaded " + message,<1,1,1>,1.0);
603 }
604 else if(num == iPlayChannel) // external messages come in channel 1 - change them to channel Play
605 {
606 Debug("playback animation " + message);
607 llMessageLinked(LINK_THIS,Play,message,"");
608 }
609 }
610
611
612 }

Archipelis scripts for prim animator

Archipelis script to replace the buggy one that comes with Archipelis 2.0.
It removes the extra images, leaving behind the one that is needed, and removes itself after making the Archipelis prims

Category: Prim Animator
By : Ferd Frederix
Created: 2013-09-06 Edited: 2013-09-04
Worlds: Second Life


This script by Ferd Frederix may be used in any manner, modified, and republished.  Unless specified otherwise, my scripts are always free and open source.  Objects made with these scripts may be sold with no restrictions.  All I ask is that you point others to this location should they ask you about it and to not sell this script, unless it is for $0 L. Please help improve my work by reporting bugs and improvements.

1
2 // With the courtesy of BestMomo Lagan.
3 // remove extra textures, script, and allow re-linked prim animation by Ferd Frederix
4
5 string generate_index(integer i)
6 {
7 if(i < 10)
8 return "0" + (string)i;
9
10 return (string)i;
11 }
12
13
14 // remove all textures except the one on this prim.
15 clean(string index)
16 {
17 string texture = "texture_" + index;
18 string geometry = "geometry_" + index;
19
21 integer i;
22 for (i=0; i<j; i++)
23 {
25 if( inventory != texture && inventory != geometry)
26 llRemoveInventory(inventory);
27 }
28 llSetObjectName(index); // rename to allow re-linkable prim animation
29 llRemoveInventory(llGetScriptName()); // delete this script, too
30 }
31
32
33
34 default
35 {
36 on_rez(integer start_param)
37 {
38 if(start_param == 0)
39 return;
40
41 string message = (string)start_param;
42 integer message_size = llStringLength(message);
43 string index;
44 string the_scale;
45
46 if(message_size == 9)
47 {
48 index = llGetSubString(message, 0, 1);
49 the_scale = "0." + llGetSubString(message, 2, 8);
50 }
51 else if(message_size == 8)
52 {
53 index = "0" + llGetSubString(message, 0, 0);
54 the_scale = "." + llGetSubString(message, 1, 7);
55 }
56 else
57 {
58 index = "00";
59 the_scale = "." + llGetSubString(message, 0, 6);
60 }
61
62 index = generate_index(((integer)index) - 1);
63
64 rotation the_rotation = llEuler2Rot(<90.0 * DEG_TO_RAD, .0, .0>);
65 llSetRot(the_rotation);
66
67 float the_scale_value = (float)the_scale * 2.0 * 10.0;
68 llSetScale(<the_scale_value, the_scale_value, the_scale_value>);
69
70 string geometry = "geometry_" + index;
72
73 string texture = "texture_" + index;
75 llSetTexture(texture, ALL_SIDES);
76
77 clean(index); // remove all but the necessary textures
78 }
79 }

Archipelis scripts for prim animator

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

Category: Prim Animator
By : Ferd Frederix
Created: 2013-09-06 Edited: 2013-09-04
Worlds: Second Life


This script by Ferd Frederix may be used in any manner, modified, and republished.  Unless specified otherwise, my scripts are always free and open source.  Objects made with these scripts may be sold with no restrictions.  All I ask is that you point others to this location should they ask you about it and to not sell this script, unless it is for $0 L. Please help improve my work by reporting bugs and improvements.

1
2 // author Ferd Frederix
3 // Prim position root script
4 // Put this script in the root prim.
5 // touch the prim to start recording
6
7 // Clear - wipe out all recording.
8 // Name - name a new recording
9 // Pause - insert a 1 second pause
10 // Record - store a new set of child prim positions
11 // Publish - Saves to database
12 // Help
13 // >> and << to cycle each animation
14
15 // configurable things
16
17
18
19
20 string MyName ="horse 5"; // the name of the Entire set of animations, must be unique
21 string MyPassword = "ferdzee"; // a password just for you and your stuff
22
23
24 integer debug = 0; // if set to TRUE, debug info appears
25 // remote db reading
26 key kHttpRequestID;
27
28
29 integer countLoaded = 0; // how many nanims have been loaded via HTTP
30
31 integer iPlayChannel = 1; // the playback channel, this is the channel you use in LinkMessages
32 integer countchannel= 2001; // how many have been saved
33 integer iDialogChannel ; // dialog boxes
34 integer iPrimCount ; // total number of prims
35 integer iWantNameFlag; // flag indicating we are waiting for a name to be chatted
36 integer imax; // total records in store
37 integer runtime = 0; // set to 1 after Recording and publishing.
38 // animation store
39 string sCurrentAnimationName; // The name of the animation we are playing
40 string sPriorAniName; // the prior animation name so we can spot differences as we read them in
41 list lLastPrimList; // storage of the last prim position we learned
42 integer iLastSTRIDE = 4; // size of the last prim list
43 integer iListenerHandle; // temp iListenerHandle when we are waiting for them to give us a name
44 list lUserAnimNames; // animations read from the notecard added to the Menu display
45
46
47 // Commands
48 integer Clear = 99; // erase local db
49 integer Erase = 100; // erase Server DB command
50 integer Add = 101; // add a coordinate
51 integer Publish = 102; // save to db
52 integer Name = 103; // send Name to db
53 integer Password = 104; // send Password to db
54 integer Play = 1; // play channel to make an animation run
55
56 Debug( string msg)
57 {
58 if(debug) llOwnerSay(msg);
59 }
60
61 // clear any old listeners and make a new on to control lag
62 NewListen()
63 {
64 iDialogChannel = (integer) (llFrand(400) + 300);
65 llListenRemove(iListenerHandle);
66 iListenerHandle = llListen(iDialogChannel,"","","");
67 }
68
69 // prompt the user for an animation name. Uses text box or chat
70 AskForName()
71 {
72 iWantNameFlag = TRUE;
74 NewListen();
75 llOwnerSay("Enter the name in the text box or type the new animation name on channel /" + (string) iDialogChannel );
76 llTextBox(llGetOwner(),"Type the new animation name",iDialogChannel);
77 }
78
79
80 Get(string data)
81 {
82 Debug("Data was " + data);
83
84 list lLine = (llParseString2List(data, ["|"], []));
85 string sAniName = llList2String(lLine,0);
86 string sNum = (string) Getline(lLine,1);
87 float fNum = (float) sNum;
88 vector vPos = (vector) Getline(lLine,2); // global for calcChild()
89 rotation rRot = (rotation) Getline(lLine,3); // global for calcChild()
90 vector vprimSize = (vector) Getline(lLine,4);
91 countLoaded++;
92 // the first record is always the root prim size
93 if(fNum == 0)
94 {
95 FetchNext();
96 return;
97 }
98
99 if(sAniName != sPriorAniName)
100 {
101 sPriorAniName = sAniName;
102 sCurrentAnimationName = sAniName;
103 if(llListFindList(lUserAnimNames,[sAniName]) == -1)
104 {
105 Debug("Loading animation " + sAniName);
106 lUserAnimNames += sAniName;
107 }
108
109 }
110 // Debug("Loading Prim #" + (string) fNum);
111 if(fNum != 1) // skip root prim
112 {
113 sCurrentAnimationName = sAniName;
114 llMessageLinked(LINK_THIS,Add,sAniName
115 +"|"
116 + (string) fNum
117 +"|"
118 + (string) vPos
119 + "|"
120 + (string) rRot
121 + "|"
122 + (string) vprimSize,"");
123
124
125
126 llSetText("Initialising... \n" + (string) (countLoaded) , <1,1,1>, 1.0);
127 }
128 llSleep(1); // http throttle avoidance
129
130 FetchNext();
131
132 }
133 // in case of hand editing, we wupe out extra stuff at end
134 string Getline(list Input, integer line)
135 {
136 return llStringTrim(llList2String(Input, line),STRING_TRIM);
137 }
138
139 Record()
140 {
141 if(llStringLength(sCurrentAnimationName) > 0)
142 {
143 integer ifoundmovement = 0; // will be set if any child moved
144 integer iPrimCounter ; // skip past the root prim
145 for (iPrimCounter =2; iPrimCounter <= iPrimCount ; iPrimCounter++ )
146 {
147 list my_list = llGetLinkPrimitiveParams(iPrimCounter,[PRIM_POSITION,PRIM_ROTATION, PRIM_SIZE ]);
148
149 // position is always in region coordinates, even if the prim is a child or the root prim of an attachment.
150 // rot is always the global rotation, even if the prim is a child or the root prim of an attachment.
151 // get current prim pos, rot and size
152
153 vector vrealPrimPos = llList2Vector(my_list,0) - llGetPos(); // position subtract Global Pos
154 vrealPrimPos /= llGetRot();
155 rotation rrealPrimRot = llList2Rot(my_list,1) / llGetRot(); // rotation subtract Global Rot
156 vector vrealPrimSize = llList2Vector(my_list,2); // size
157
158 // compare it to the last one we had, stride of list is a 4, and it is already sorted
159 integer iindex = (iPrimCounter - 2) * iLastSTRIDE; // zeroth position is fPrimCounter - start, or 2
160
161 // get the last thing we remembered about this prim
162 integer iprimNum = llList2Integer(lLastPrimList, iindex); // must be 0,1,2, in order
163 vector vlastPrimPos = llList2Vector(lLastPrimList, iindex+1);
164 rotation rlastPrimRot = llList2Rot(lLastPrimList, iindex+2);
165 vector vlastPrimSize = llList2Vector(lLastPrimList, iindex+3);
166
167 // if anything changed on this prim, we must record it.
168 if(vlastPrimPos != vrealPrimPos ||
169 rlastPrimRot != rrealPrimRot ||
170 vlastPrimSize!= vrealPrimSize
171 )
172 {
173 ifoundmovement++;
174
175 //Save them in the master list of all animations
176 llMessageLinked(LINK_THIS,Add,sCurrentAnimationName+ "|"
177 + (string) iPrimCounter
178 + "|"
179 + (string) vrealPrimPos
180 + "|"
181 + (string) rrealPrimRot
182 + "|"
183 + (string) vrealPrimSize,"");
184
185
186 imax = llGetListLength(lLastPrimList);
187 // save the changes in the last prim list so we can keep our lists smaller
188
189 lLastPrimList = llListReplaceList(lLastPrimList,[vrealPrimPos],iPrimCounter+1,iPrimCounter+1);
190 lLastPrimList = llListReplaceList(lLastPrimList,[rrealPrimRot],iPrimCounter+2,iPrimCounter+2);
191 lLastPrimList = llListReplaceList(lLastPrimList,[vrealPrimSize],iPrimCounter+3,iPrimCounter+3);
192 //Debug("Saved in history at prim # " + (string) (iPrimCounter));
193 } // if
194
195 } // for
196 //Debug("history:" + llDumpList2String(lLastPrimList,":"));
197 //Debug("master:" + llDumpList2String(lAniStore," "));
198
199 if(!ifoundmovement)
200 {
201 llOwnerSay("You must move at least one child prim.");
202 }
203
204 }
205 else
206 {
207 AskForName();
208 }
209
210 }
211
212 // on reset, record the base position in history so we can see changes
213
214 ClearRAM()
215 {
216
217 iPrimCount = llGetNumberOfPrims(); // how many we are recording
218 sCurrentAnimationName = ""; // no name in use
219
220 lLastPrimList = []; // wipe last animations list
221 integer iPrimCounter ;
222
223 for (iPrimCounter=2; iPrimCounter <= iPrimCount ; iPrimCounter++ ) // skip 1, which is the root prim
224 {
225 list my_list = llGetLinkPrimitiveParams(iPrimCounter,[PRIM_POSITION, PRIM_ROTATION, PRIM_SIZE ]);
226
227 // save the local pos and rot, since llGetLinkPrimitiveParams returns global pos and rot
228 vector primpos = llList2Vector(my_list,0) - llGetPos();
229 primpos /= llGetRot();
230 rotation primrot = llList2Rot(my_list,1) / llGetRot();
231
232 vector primsize = llList2Vector(my_list,2) ;
233 lLastPrimList += iPrimCounter;
234 lLastPrimList += primpos;
235 lLastPrimList += primrot;
236 lLastPrimList += primsize;
237
238 }
239 llOwnerSay("RAM is cleared");
240 }
241
242
243 rotation calcChildRot(rotation rdeltaRot)
244 {
246 return rdeltaRot/llGetLocalRot();
247 else
248 return rdeltaRot/llGetRootRotation();
249 }
250
251
252 MakeMenu()
253 {
254 if(runtime)
255 {
256 MakeMenu2();
257 return;
258 }
259
260 list amenu = ["Record","Clear RAM","Pause"] +
261 ["Erase","Load","Publish"] +
262 ["Recordings","Name","Play All"] +
263 ["Help","More", "Finish"];
264
265 string menuText = "Available Memory: " + (string) llGetFreeMemory() +
266 "\n\n" +
267 "Recordings: Select a named animation\n" +
268 "Name: Set the animation name\n" +
269 "Play All: Play all animations\n" +
270 "Clear RAM: Erase SL memory\n"+
271 "Erase: Delete Server Data\n" +
272 "Load: Get from Server\n" +
273 "Publish: Save to Server\n" +
274 "Record: Record a snapshot of prim positions\n" +
275 "Pause: Insert 0.1 second pause\n" +
276 "Finish: End all programming\n" +
277 "Help: Help";
278
279 NewListen();
280 llDialog(llGetOwner(), menuText,amenu,iDialogChannel);
281
282 }
283
284 MakeMenu2()
285 {
286 string menuText ;
287 list menu2 = lUserAnimNames;
288 menu2 = llDeleteSubList(menu2,11,999); // 11 max
289
290 if(runtime)
291 menu2 += "Unlock";
292 if(llGetListLength(lUserAnimNames) == 0)
293 {
294 menu2 += ["Back"] ;
295 menuText = " There are no animation names to display\n\n" +
296 "Back:- Go back to programming menu";
297 }
298 else
299 menuText = "Pick an animation to play.";
300
301 NewListen();
302 llDialog(llGetOwner(), menuText,menu2,iDialogChannel);
303 }
304
305
306 FetchNext()
307 {
308 string url = "http://secondlife.mitsi.com/cgi/animate.plx?Type=Load&Count=" + (string) countLoaded + "&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyPassword);
309 Debug(url);
310
311 kHttpRequestID = llHTTPRequest(url, [], "");
312 }
313
314
315 default
316 {
318 {
319 llMessageLinked(LINK_THIS,Name,MyName,"");
320 llMessageLinked(LINK_THIS,Password,MyPassword,"");
321
322 if(runtime)
323 {
324 ClearRAM();
325 FetchNext(); // start with first line in DB
326 }
327 }
328
329 http_response(key queryid, integer status, list metadata, string data)
330 {
331 if(queryid == kHttpRequestID )
332 {
333 if(status == 200) // HTTP success status
334 {
335 if(data == "nothing to do")
336 {
337 llOwnerSay("Initialized with " + (string) countLoaded + " settings");
338 llSetText("" , <1,1,1>, 1.0);
339 return;
340 }
341 Get(data);
342 }
343 else
344 {
345 llOwnerSay("Server Error loading animations");
346 }
347 }
348 }
349
350 touch_start(integer total_number)
351 {
353 {
354 MakeMenu();
355 }
356 }
357
358 // timed out waitig for a name of an animation
359 timer()
360 {
361 iWantNameFlag = FALSE;
363 llOwnerSay(" Timeout waiting for animation name");
364 llListenRemove(iListenerHandle);
365 }
366
367 listen( integer channel, string name, key id, string message )
368 {
369 llListenRemove(iListenerHandle);
370 // Debug(message);
371
372 if(message == "Finish")
373 {
374 runtime++;
375 llOwnerSay("The animator is now locked. Further touches will bring up a list of animations. You must unlock the menu to add more animations");
376 }
377 else if(message == "Unlock")
378 {
379 runtime = 0;
380 llOwnerSay("The animator is now unlocked for programming.");
381 }
382
383 else if(message == "Erase")
384 {
385 llMessageLinked(LINK_THIS,Erase,"",""); // erase the db
386 MakeMenu();
387 }
388 else if(message == "Clear RAM")
389 {
390 ClearRAM();
391 MakeMenu();
392 }
393 else if(message =="Pause")
394 {
395 llMessageLinked(LINK_THIS,Add,"sCurrentAnimationName|"
396 + "-0.1" // sleep 1 tenth a second
397 + "|"
398 + "<0,0,0>" // null pos
399 + "<0,0,0,1>" // null rot
400 + "|"
401 + "<0,0,0>",""); // null size
402 MakeMenu();
403 }
404 else if(message == "Recordings")
405 {
406 MakeMenu2();
407 }
408 else if(message == "Load")
409 {
410 countLoaded = 0;
411 FetchNext(); // start with first line in DB
412 }
413 else if(message == "Record")
414 {
415 Record();
416 MakeMenu();
417 }
418 else if(message == "Publish")
419 {
420 llMessageLinked(LINK_THIS,Name,MyName,""); // in case we reset just the stores
421 llMessageLinked(LINK_THIS,Password,MyPassword,"");
422 llMessageLinked(LINK_THIS,Publish,"","");
423 MakeMenu();
424 }
425 else if(message == "Name")
426 {
427 AskForName();
428 }
429 else if(message == "Back")
430 {
431 MakeMenu();
432 }
433 else if(message == "More")
434 {
435 MakeMenu();
436 }
437 else if(message == "Play All")
438 {
439 integer l = llGetListLength(lUserAnimNames);
440 if(l == 0)
441 llOwnerSay("Nothing to do");
442 else
443 {
444 integer i = 0;
445 for ( i = 0; i < l; i++)
446 {
447 string ani = llList2String(lUserAnimNames,i);
448 llMessageLinked(LINK_THIS,iPlayChannel,ani,"");
449 llSleep(1);
450 }
451 }
452 MakeMenu();
453
454 }
455 else if(message == "Help")
456 {
457 llLoadURL(llGetOwner(),"View online help", "http://secondlife.mitsi.com/secondlife/Posts/Prim-Animator-DB");
458 }
459 else if(iWantNameFlag)
460 {
461 sCurrentAnimationName = message;
462 if(llGetListLength(lUserAnimNames) < 11)
463 {
464 if(llListFindList(lUserAnimNames,[sCurrentAnimationName]) == -1)
465 lUserAnimNames += message;
466 }
467 else
468 {
469 lUserAnimNames = llDeleteSubList(lUserAnimNames,11,99);
470 }
471
472 MakeMenu();
473
474 llOwnerSay("Ready to record animation '" + sCurrentAnimationName + "'");
475 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.");
476
477 iWantNameFlag = 0;
478 llSetTimerEvent(1.0);
479 }
480 else
481 {
482 if(llListFindList(lUserAnimNames,[message]) != -1)
483 {
484 Debug("playback animation " + message);
485 llMessageLinked(LINK_THIS,iPlayChannel,message,"");
486 MakeMenu();
487 }
488 }
489 }
490
491 link_message(integer sender_num, integer num, string message, key id)
492 {
493 if(num == countchannel)
494 {
495 llSetText("Loaded " + message,<1,1,1>,1.0);
496 }
497 }
498
499
500 }
501
502
503 ਊ

Archipelis scripts for prim animator

Prim storage Script Should be named Store 0

Category: Prim Animator
By : Ferd Frederix
Created: 2013-09-06 Edited: 2013-09-04
Worlds: Second Life


This script by Ferd Frederix may be used in any manner, modified, and republished.  Unless specified otherwise, my scripts are always free and open source.  Objects made with these scripts may be sold with no restrictions.  All I ask is that you point others to this location should they ask you about it and to not sell this script, unless it is for $0 L. Please help improve my work by reporting bugs and improvements.

1
2 // prim store
3 // constants
4 integer debug =0 ;
5 // return codes
6
7 integer countchannel= 2001; // echo the number iof prims loaded to the animator
8
9
10
11
12 // Commands
13 integer Clear = 99; // erase local db
14 integer Erase = 100; // erase Server DB command
15 integer Add = 101; // add a coordinate
16 integer Publish = 102; // save to db
17 integer Name = 103; // send Name to db
18 integer Password = 104; // send Password to db
19 integer Play = 1; // backwards compat
20
21 // vars
22 integer full = FALSE; // this script RAM is full
23 integer myNum = 0; // the number at the end of this script name 0, 1, 2....
24 integer imax; // total records in store
25 integer datum; // the load counter increments as we load anims from db
26 string MyName;
27 string MyPassword;
28
29
30 // remote db reading
31 key kHttpRequestID;
32
33 // lists
34 list names; // a list of distnct animation names stored here
35 list db; // name, prin num, pos, rot, size
36 integer STRIDE = 5; // 4 items in the above list
37 integer recordcount = 0; // how many anims are stored
38
39
40 vector vRootScale ; // the initial size when the prims were recorded
41 vector vScaleChange = <1,1,1>; // The change percent if resized
42
43 integer GetScale()
44 {
45 //Debug ("Size:" + (string) orig_size);
46 vector newScale = llGetScale();
47
48 vScaleChange.x = newScale.x / vRootScale.x;
49 vScaleChange.y = newScale.y / vRootScale.y;
50 vScaleChange.z = newScale.z / vRootScale.z;
51 return (vScaleChange != <1,1,1>);
52
53 }
54
55
56
57 // Start saving records. The first record is the prim size.
58
59 StartPublishing ()
60 {
61 imax = llGetListLength(db);
62 datum = 0; // point to the first record, counts as we load records
63 integer howmany = imax / STRIDE ;
64 llOwnerSay((string) howmany + " movements recorded - now saving to server.");
65 }
66
67 EraseDB()
68 {
69 string url;
70
71 //Debug( "Saving Size:" + (string) llGetScale());
72 url = "http://secondlife.mitsi.com/cgi/animate.plx?Type=Erase";
73 url += "&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyPassword);
74
75 Debug(url);
76 kHttpRequestID = llHTTPRequest(url, [], "");
77
78 }
79
80 Put()
81 {
82 if(datum < imax)
83 {
84 string sAniName = llList2String(db, datum);
85 float fprimNum = llList2Float(db, datum+1);
86 vector vprimPos = llList2Vector(db, datum+2);
87 rotation rprimRot = llList2Rot(db, datum+3) ;
88 vector vprimSize = llList2Vector(db, datum+4);
89
90 string url = "http://secondlife.mitsi.com/cgi/animate.plx?Type=Save&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyPassword);
91 url += "&aniName=" + (string) sAniName;
92 url += "&PrimNum=" + (string) fprimNum;
93 url += "&Pos=" + (string) vprimPos;
94 url += "&Rot=" + (string) rprimRot;
95 url += "&Size=" + (string) vprimSize;
96
97 Debug(url);
98 if((datum/STRIDE) % 10 == 0 && datum)
99 llMessageLinked(LINK_THIS,countchannel,(string) (datum/STRIDE) ,"");
100
101
102 kHttpRequestID = llHTTPRequest(url, [], "");
103 llSleep(1);
104 datum += STRIDE;
105 }
106 else
107 {
108 llMessageLinked(LINK_THIS,countchannel,(string) (datum/STRIDE),"");
109 llSleep(2.0);
110 llMessageLinked(LINK_THIS,countchannel,"","");
111 }
112
113 }
114
115
116 Debug(string msg)
117 {
118 if(debug)
119 llOwnerSay(llGetScriptName() + ":" + msg);
120 }
121
122
123 default
124 {
126 {
127 list parts = llParseString2List( llGetScriptName(),[" "],[""]);
128 myNum = llList2Integer(parts,1);
129
130 vRootScale = llGetScale(); // set a default of this size, the real size when recorded comes from the server
131
132 Add = Add + (10 * myNum);
133
134 Debug("DB " + (string) myNum + " is empty");
135 }
136
137 link_message(integer sender_num, integer num, string msg, key id)
138 {
139
140 //Debug("cmd:" + (string) num + ":" + msg);
141
142 // valid commands only.
143 if(num != Clear && num != Erase && num != Play && num != Add && num != Publish && num != Name && num!= Password)
144 return;
145
146 Debug("cmd rcv :" + (string) num + ":" + msg);
147
148 if(num == Clear)
149 {
150 db = []; // zero the animations
151 names = []; // zero names db
152 //Debug((string) myNum + " erased " );
153 full = FALSE;
154 recordcount = 0;
155 return;
156 }
157 else if(num == Add)
158 {
159 if(full)
160 {
161 Debug((string) myNum + " pass Add on to " + (string) (num +10));
162 llMessageLinked(LINK_THIS,num +10,msg,id);
163 return;
164 }
165
166 //Debug("Add");
167 list vecs = llParseString2List(msg,["|"],[""]);
168
169 // Debug(llDumpList2String(vecs,"---"));
170 string name= llList2String(vecs,0);
171 if(llListFindList(names,[name]) == -1)
172 names += name;
173
174 float fNum = (float) (llList2String(vecs,1));
175 vector vPos = (vector) (llList2String(vecs,2));
176 rotation rRot = (rotation) (llList2String(vecs,3));
177 vector vprimSize = (vector) (llList2String(vecs,4));
178
179 db += name;
180 db += fNum;
181 db += vPos;
182 db += rRot;
183 db += vprimSize;
184
185 recordcount ++;
186 Debug("Mem:" + (string) llGetFreeMemory() );
187 if(llGetFreeMemory() < 2000)
188 full++;
189 }
190 else if(num == Name)
191 {
192 MyName = msg;
193 }
194 else if(num == Password)
195 {
196 MyPassword = msg;
197 }
198 else if(num == Play)
199 {
200 if(llListFindList(names,[msg]) == -1)
201 return;
202
203 integer currpos;
204 integer end = recordcount * STRIDE;
205 // play back all we find
206 for (currpos = 0; currpos < end; currpos+= STRIDE)
207 {
208 if( msg == llList2String(db,currpos) )
209 {
210 float fPrim = (float) llList2String(db,currpos+1);
211 vector vPos = (vector) llList2String(db,currpos+2);
212 rotation rRot = (rotation) llList2String(db,currpos+3);
213 vector vprimSize = (vector) llList2String(db,currpos+4);
214
215 if(fPrim > 1 ) // skip root prim
216 {
217
218 // set the local pos and locat rot to the prims orientation and position
220 rRot = rRot/llGetLocalRot();
221 else
222 rRot = rRot/llGetRootRotation();
223
224 if(GetScale())
225 {
226 vPos.x *= vScaleChange.x;
227 vprimSize.x *= vScaleChange.x;
228
229 vPos.y *= vScaleChange.y;
230 vprimSize.y *= vScaleChange.y;
231
232 vPos.z *= vScaleChange.z;
233 vprimSize.z *= vScaleChange.z;
234 }
235 // Debug("p=" + (string) fPrim
236 // + " l=" + (string) vPos
237 // + " r=" + (string) rRot
238 // + " s=" + (string) vprimSize);
239
240 llSetLinkPrimitiveParamsFast((integer) fPrim,[PRIM_POSITION,vPos,PRIM_ROTATION,rRot,PRIM_SIZE,vprimSize]);
241 }
242 else if(fPrim == 0)
243 {
244 vRootScale = (vector) msg;
245 Debug("Set scale to " + (string) vRootScale);
246 }
247 else if(fPrim < 0)
248 {
249 Debug("Sleep");
250 llSleep( fPrim * -1);
251 }
252 }
253 }
254 }
255 else if(num == Publish)
256 {
257 if(myNum)
258 llSleep(5); // time to delete the database and save the root prim
259 StartPublishing();
260 }
261 else if(num == Erase)
262 {
263 EraseDB();
264 }
265
266 else
267 {
268 Debug("Bad command");
269 }
270 }
271
272
273 // use for publishing in parallel
274 http_response(key queryid, integer status, list metadata, string data)
275 {
276 if(queryid == kHttpRequestID )
277 {
278 if(status == 200) // HTTP success status
279 {
280 Debug(data);
281 if(data == "ok")
282 {
283 Put();
284 return;
285 }
286 else if(data == "deleted")
287 {
288 llOwnerSay("Remote database is empty");
289 return;
290 }
291
292 }
293 else
294 {
295 llOwnerSay("Server Error loading animations");
296 }
297 }
298 }
299
300
301 }
302 ਊ

Archipelis scripts for prim animator

Prim storage Script Should be names Store 1

Category: Prim Animator
By : Ferd Frederix
Created: 2013-09-06 Edited: 2013-09-04
Worlds: Second Life


This script by Ferd Frederix may be used in any manner, modified, and republished.  Unless specified otherwise, my scripts are always free and open source.  Objects made with these scripts may be sold with no restrictions.  All I ask is that you point others to this location should they ask you about it and to not sell this script, unless it is for $0 L. Please help improve my work by reporting bugs and improvements.

1
2 // prim store
3 // constants
4 integer debug =0 ;
5 // return codes
6
7 integer countchannel= 2001; // echo the number iof prims loaded to the animator
8
9
10
11
12 // Commands
13 integer Clear = 99; // erase local db
14 integer Erase = 100; // erase Server DB command
15 integer Add = 101; // add a coordinate
16 integer Publish = 102; // save to db
17 integer Name = 103; // send Name to db
18 integer Password = 104; // send Password to db
19 integer Play = 1; // backwards compat
20
21 // vars
22 integer full = FALSE; // this script RAM is full
23 integer myNum = 0; // the number at the end of this script name 0, 1, 2....
24 integer imax; // total records in store
25 integer datum; // the load counter increments as we load anims from db
26 string MyName;
27 string MyPassword;
28
29
30 // remote db reading
31 key kHttpRequestID;
32
33 // lists
34 list names; // a list of distnct animation names stored here
35 list db; // name, prin num, pos, rot, size
36 integer STRIDE = 5; // 4 items in the above list
37 integer recordcount = 0; // how many anims are stored
38
39
40 vector vRootScale ; // the initial size when the prims were recorded
41 vector vScaleChange = <1,1,1>; // The change percent if resized
42
43 integer GetScale()
44 {
45 //Debug ("Size:" + (string) orig_size);
46 vector newScale = llGetScale();
47
48 vScaleChange.x = newScale.x / vRootScale.x;
49 vScaleChange.y = newScale.y / vRootScale.y;
50 vScaleChange.z = newScale.z / vRootScale.z;
51 return (vScaleChange != <1,1,1>);
52
53 }
54
55
56
57 // Start saving records. The first record is the prim size.
58
59 StartPublishing ()
60 {
61 imax = llGetListLength(db);
62 datum = 0; // point to the first record, counts as we load records
63 integer howmany = imax / STRIDE ;
64 llOwnerSay((string) howmany + " movements recorded - now saving to server.");
65 }
66
67 EraseDB()
68 {
69 string url;
70
71 //Debug( "Saving Size:" + (string) llGetScale());
72 url = "http://secondlife.mitsi.com/cgi/animate.plx?Type=Erase";
73 url += "&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyPassword);
74
75 Debug(url);
76 kHttpRequestID = llHTTPRequest(url, [], "");
77
78 }
79
80 Put()
81 {
82 if(datum < imax)
83 {
84 string sAniName = llList2String(db, datum);
85 float fprimNum = llList2Float(db, datum+1);
86 vector vprimPos = llList2Vector(db, datum+2);
87 rotation rprimRot = llList2Rot(db, datum+3) ;
88 vector vprimSize = llList2Vector(db, datum+4);
89
90 string url = "http://secondlife.mitsi.com/cgi/animate.plx?Type=Save&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyPassword);
91 url += "&aniName=" + (string) sAniName;
92 url += "&PrimNum=" + (string) fprimNum;
93 url += "&Pos=" + (string) vprimPos;
94 url += "&Rot=" + (string) rprimRot;
95 url += "&Size=" + (string) vprimSize;
96
97 Debug(url);
98 if((datum/STRIDE) % 10 == 0 && datum)
99 llMessageLinked(LINK_THIS,countchannel,(string) (datum/STRIDE) ,"");
100
101
102 kHttpRequestID = llHTTPRequest(url, [], "");
103 llSleep(1);
104 datum += STRIDE;
105 }
106 else
107 {
108 llMessageLinked(LINK_THIS,countchannel,(string) (datum/STRIDE),"");
109 llSleep(2.0);
110 llMessageLinked(LINK_THIS,countchannel,"","");
111 }
112
113 }
114
115
116 Debug(string msg)
117 {
118 if(debug)
119 llOwnerSay(llGetScriptName() + ":" + msg);
120 }
121
122
123 default
124 {
126 {
127 list parts = llParseString2List( llGetScriptName(),[" "],[""]);
128 myNum = llList2Integer(parts,1);
129
130 vRootScale = llGetScale(); // set a default of this size, the real size when recorded comes from the server
131
132 Add = Add + (10 * myNum);
133
134 Debug("DB " + (string) myNum + " is empty");
135 }
136
137 link_message(integer sender_num, integer num, string msg, key id)
138 {
139
140 //Debug("cmd:" + (string) num + ":" + msg);
141
142 // valid commands only.
143 if(num != Clear && num != Erase && num != Play && num != Add && num != Publish && num != Name && num!= Password)
144 return;
145
146 Debug("cmd rcv :" + (string) num + ":" + msg);
147
148 if(num == Clear)
149 {
150 db = []; // zero the animations
151 names = []; // zero names db
152 //Debug((string) myNum + " erased " );
153 full = FALSE;
154 recordcount = 0;
155 return;
156 }
157 else if(num == Add)
158 {
159 if(full)
160 {
161 Debug((string) myNum + " pass Add on to " + (string) (num +10));
162 llMessageLinked(LINK_THIS,num +10,msg,id);
163 return;
164 }
165
166 //Debug("Add");
167 list vecs = llParseString2List(msg,["|"],[""]);
168
169 // Debug(llDumpList2String(vecs,"---"));
170 string name= llList2String(vecs,0);
171 if(llListFindList(names,[name]) == -1)
172 names += name;
173
174 float fNum = (float) (llList2String(vecs,1));
175 vector vPos = (vector) (llList2String(vecs,2));
176 rotation rRot = (rotation) (llList2String(vecs,3));
177 vector vprimSize = (vector) (llList2String(vecs,4));
178
179 db += name;
180 db += fNum;
181 db += vPos;
182 db += rRot;
183 db += vprimSize;
184
185 recordcount ++;
186 Debug("Mem:" + (string) llGetFreeMemory() );
187 if(llGetFreeMemory() < 2000)
188 full++;
189 }
190 else if(num == Name)
191 {
192 MyName = msg;
193 }
194 else if(num == Password)
195 {
196 MyPassword = msg;
197 }
198 else if(num == Play)
199 {
200 if(llListFindList(names,[msg]) == -1)
201 return;
202
203 integer currpos;
204 integer end = recordcount * STRIDE;
205 // play back all we find
206 for (currpos = 0; currpos < end; currpos+= STRIDE)
207 {
208 if( msg == llList2String(db,currpos) )
209 {
210 float fPrim = (float) llList2String(db,currpos+1);
211 vector vPos = (vector) llList2String(db,currpos+2);
212 rotation rRot = (rotation) llList2String(db,currpos+3);
213 vector vprimSize = (vector) llList2String(db,currpos+4);
214
215 if(fPrim > 1 ) // skip root prim
216 {
217
218 // set the local pos and locat rot to the prims orientation and position
220 rRot = rRot/llGetLocalRot();
221 else
222 rRot = rRot/llGetRootRotation();
223
224 if(GetScale())
225 {
226 vPos.x *= vScaleChange.x;
227 vprimSize.x *= vScaleChange.x;
228
229 vPos.y *= vScaleChange.y;
230 vprimSize.y *= vScaleChange.y;
231
232 vPos.z *= vScaleChange.z;
233 vprimSize.z *= vScaleChange.z;
234 }
235 // Debug("p=" + (string) fPrim
236 // + " l=" + (string) vPos
237 // + " r=" + (string) rRot
238 // + " s=" + (string) vprimSize);
239
240 llSetLinkPrimitiveParamsFast((integer) fPrim,[PRIM_POSITION,vPos,PRIM_ROTATION,rRot,PRIM_SIZE,vprimSize]);
241 }
242 else if(fPrim == 0)
243 {
244 vRootScale = (vector) msg;
245 Debug("Set scale to " + (string) vRootScale);
246 }
247 else if(fPrim < 0)
248 {
249 Debug("Sleep");
250 llSleep( fPrim * -1);
251 }
252 }
253 }
254 }
255 else if(num == Publish)
256 {
257 if(myNum)
258 llSleep(5); // time to delete the database and save the root prim
259 StartPublishing();
260 }
261 else if(num == Erase)
262 {
263 EraseDB();
264 }
265
266 else
267 {
268 Debug("Bad command");
269 }
270 }
271
272
273 // use for publishing in parallel
274 http_response(key queryid, integer status, list metadata, string data)
275 {
276 if(queryid == kHttpRequestID )
277 {
278 if(status == 200) // HTTP success status
279 {
280 Debug(data);
281 if(data == "ok")
282 {
283 Put();
284 return;
285 }
286 else if(data == "deleted")
287 {
288 llOwnerSay("Remote database is empty");
289 return;
290 }
291
292 }
293 else
294 {
295 llOwnerSay("Server Error loading animations");
296 }
297 }
298 }
299
300
301 }
302 ਊ

Back to the Best Free Tools in Second Life and OpenSim.