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 Prim_Animator_using_one_script  

Prim_Animator_using_one_script

The Single prim animator script Instructions are at http://secondlife.mitsi.com/secondlife/Posts/Prim-Animator
A newer script is at http://metaverse.mitsi.com/secondlife/posts/prim-compiler/

Category: Prim
By : Ferd Frederix
Created: 2010-10-23 Edited: 2010-10-23
Worlds: Second Life

the Zip file

Download all files for Prim_Animator_using_one_script
Contents are in zip format, with .LSL (text) source code and LSLEdit (text + Solution) formats.
Get file # 1. Prim_Animator_using_one_script_1.lsl
Get file # 2. Prim_Animator_using_one_script_2.lsl
Get file # 3. Prim_Animator_using_one_script_3.lsl
Get file # 4. Prim_Animator_using_one_script_4.lsl
Get file # 5. Prim_Animator_using_one_script_5.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 // One Script Prim Animation
2 // ( rev1.1) add llTextBox
3 // Free and Open Source - not for sale but for free use in any build.
4
5 // Original Script by: Ferd Frederix
6
7 integer runtime = FALSE; // set to TRUE after making the notecard
8
9 string NOTECARD = "Movement"; // the notecard for this script, you can add more than 1 script and notecard, just change this line to match
10 integer playchannel = 1; // the playback channel, this is the channel you use in LinkMessages
11
12
13 integer debug = FALSE; // if set to TRUE, debug info appears
14
15
16 // notecard reading
17 string priorname; // the prior animation name so we can spot differences as we read them in
18 integer iIndexLines; // lines in a card
19 integer inotecardIndex = 0; // notecard counter;
20 integer move = 0; // N movements rea from the notecard
21
22 key kNoteCardLines; // the key of the notecard
23 key kGetIndexLines; // the key of the current line
24
25 //communications
26 integer dialogchannel ; // dialog boxes
27
28 integer nPrims; // total number of prims
29 integer PrimsCounter = 0; // how many have checked in
30 integer timercounter = 0; // how many seconds have gone by
31 integer wantname; // flag indicating we are waiting for a name to be chatted
32
33
34 // the list of coords
35 list masterlist; // master list of all positions
36 list llastPrimList; // storage of the last prim position we learned
37 string curranimation; // what we are playing
38
39 integer STRIDE = 5; // size of the master list
40 integer lastSTRIDE = 4; // size of the last prim list
41
42 integer listener; // temp listener when we are waiting for them to give us a name
43
44 vector InitSize; // the initial size when the prims were recorded
45 list LoadedAnims; // animations read from the notecard added to the Menu display
46
47 // in case of hand editing, we wupe out extra stuff at end
48 string Getline(list Input, integer line)
49 {
50 return llStringTrim(llList2String(Input, line),STRING_TRIM);
51 }
52
53 Record()
54 {
55 if(llStringLength(curranimation) > 0)
56 {
57 integer foundmovement = 0; // will be set if any child moved
58 integer PrimCounter ; // skip past the root prim
59 for (PrimCounter =2; PrimCounter <= nPrims; PrimCounter++ )
60 {
61 list my_list = llGetLinkPrimitiveParams(PrimCounter,[PRIM_POSITION,PRIM_ROTATION, PRIM_SIZE ]);
62 // position is always in region coordinates, even if the prim is a child or the root prim of an attachment.
63 // rot is always the global rotation, even if the prim is a child or the root prim of an attachment.
64
65 // get current prim pos, rot and size
66 vector vrealPrimPos = llList2Vector(my_list,0) - llGetPos(); // position subtract Global Pos
67 vrealPrimPos /= llGetRot();
68 rotation rrealPrimRot = llList2Rot(my_list,1) / llGetRot(); // rotation subtract Global Rot
69 vector vrealPrimSize = llList2Vector(my_list,2); // size
70
71 // compare it to the last one we had, stride of list is a 4, and it is already sorted
72 integer iindex = (PrimCounter - 2) * lastSTRIDE; // zeroth position is PrimCounter - start, or 2
73
74 // get the last thing we remembered about this prim
75 float fprimNum = llList2Integer(llastPrimList, iindex); // must be 0,1,2, in order
76 vector vlastPrimPos = llList2Vector(llastPrimList, iindex+1);
77 rotation rlastPrimRot = llList2Rot(llastPrimList, iindex+2);
78 vector vlastPrimSize = llList2Vector(llastPrimList, iindex+3);
79
80 // if anything changed on this prim, we must record it.
81 if(vlastPrimPos != vrealPrimPos ||
82 rlastPrimRot != rrealPrimRot ||
83 vlastPrimSize!= vrealPrimSize
84 )
85 {
86 foundmovement++;
87
88 // show owner any changes they mnade
89 if(debug)
90 {
91 llOwnerSay("prim:" + (string) PrimCounter);
92
93 if(vlastPrimPos != vrealPrimPos)
94 llOwnerSay("pos delta :" + (string) (vrealPrimPos - vlastPrimPos));
95
96 if(rlastPrimRot != rrealPrimRot)
97 llOwnerSay("rot delta:" + (string) (llRot2Euler(rrealPrimRot - rlastPrimRot) * RAD_TO_DEG));
98
99 if(vlastPrimSize != vrealPrimSize)
100 llOwnerSay("size delta:" + (string) (vrealPrimSize - vlastPrimSize));
101 }
102
103 //Save them in the master list of all animations
104 masterlist += curranimation;
105 masterlist += PrimCounter;
106 masterlist += vrealPrimPos;
107 masterlist += rrealPrimRot;
108 masterlist += vrealPrimSize;
109
110 // save them in the last movement list
111 integer saved = FALSE;
112 integer i;
113 integer imax = llGetListLength(llastPrimList);
114 // save the changes in the last prim list so we can keep our lists smaller
115 for ( i=0; i < imax; i += lastSTRIDE )
116 {
117 if(llList2Float(llastPrimList,i) == PrimCounter)
118 {
119 llastPrimList = llListReplaceList(llastPrimList,[vrealPrimPos],i+1,i+1);
120 llastPrimList = llListReplaceList(llastPrimList,[rrealPrimRot],i+2,i+2);
121 llastPrimList = llListReplaceList(llastPrimList,[vrealPrimSize],i+3,i+3);
122 if(debug) llOwnerSay("In history at position " + (string) (i/lastSTRIDE));
123 saved++;
124 }
125 }
126
127 // never moved before? add it then
128 if(! saved)
129 {
130 if(debug) llOwnerSay("Someone added a new prim and then clicked Record");
131 llastPrimList += PrimCounter;
132 llastPrimList += vrealPrimPos;
133 llastPrimList += rrealPrimRot;
134 llastPrimList += vrealPrimSize;
135 }
136 } // if
137 } // for
138 if(debug) llOwnerSay("history:" + llDumpList2String(llastPrimList,":"));
139
140 if(!foundmovement)
141 llOwnerSay("You must move at least one child prim.");
142 }
143 else
144 {
145 llOwnerSay("You must name your animation.");
146 llOwnerSay("Type the new animation name on channel /" + (string) dialogchannel);
147 wantname++;
148 }
149 }
150
151 // on reset, record the base position in history so we can see changes
152 Clear()
153 {
154 LoadedAnims = []; // wipe out Menu
155 masterlist = []; // wipe all recordings
156 llastPrimList = []; // wipe last animations
157 integer PrimCounter ; // skip 1, which is the root prim
158 integer counter = 0;
159 // save all the current settings in memory
160 for (PrimCounter=2; PrimCounter <= nPrims; PrimCounter++ )
161 {
162 list my_list = llGetLinkPrimitiveParams(PrimCounter,[PRIM_POSITION,PRIM_ROTATION, PRIM_SIZE ]);
163
164 // save the local pos and rot, since llGetLinkPrimitiveParams returns global pos and rot
165 vector primpos = llList2Vector(my_list,0) - llGetPos();
166 rotation primrot = llList2Rot(my_list,1) / llGetRot();
167 vector primsize = llList2Vector(my_list,2) ;
168
169 llastPrimList += PrimCounter;
170 llastPrimList += primpos;
171 llastPrimList += primrot;
172 llastPrimList += primsize;
173 counter++;
174 }
175 if(debug) llOwnerSay("Saved " + (string) counter + " prims initial position in history");
176 }
177
178 DumpBack ()
179 {
180 integer i;
181 integer imax = llGetListLength(masterlist);
182 integer howmany = imax / STRIDE ;
183 llOwnerSay((string) howmany + " movements recorded - copy these and paste them into the notecard");
184
185 integer flag = 0;
186 for (i = 0; i < imax; i+= STRIDE)
187 {
188 if( i == 0 )
189 llOwnerSay( "|start|" + (string) llGetScale());
190
191 string saniName = llList2String(masterlist,i);
192 curranimation = saniName;
193
194 float fprimNum = llList2Integer(masterlist, i+1);
195 integer iprimNum = (integer) fprimNum;
196 vector vprimPos = llList2Vector(masterlist, i+2);
197 rotation rprimRot = llList2Rot(masterlist, i+3) ;
198 vector vprimSize = llList2Vector(masterlist, i+4);
199
200 llOwnerSay("|"+ saniName + "|" + (string) iprimNum + "|" + (string) vprimPos + "|" + (string) rprimRot + "|" + (string) vprimSize );
201 flag++;
202 }
203 if(! flag)
204 llOwnerSay("No recording was made, nothing to play back." );
205 }
206
207
208 rotation calcChildRot(rotation rdeltaRot)
209 {
210
212 return rdeltaRot/llGetLocalRot();
213 else
214 return rdeltaRot/llGetRootRotation();
215
216 }
217
218
219 PlayBack (string name)
220 {
221 integer i;
222 integer imax = llGetListLength(masterlist);
223
224 integer linknum = 0;
225
226 for (i = 0; i < imax; i+= STRIDE)
227 {
228 string saniName = llList2String(masterlist,i);
229 if(saniName == name)
230 {
231 float fprimNum = llList2Float(masterlist,i+1);
232 vector vPos = llList2Vector(masterlist,i+2);
233 rotation rRot = llList2Rot(masterlist,i+3) ;
234 vector vprimSize = llList2Vector(masterlist,i+4) ;
235
236 vector scale = llGetScale();
237 float delta = scale.x / InitSize.x ; // see if the root prim has grown or shrunk as a percentage
238
239 vPos *= delta; // add any difference in size to it positions there
240 vprimSize *= delta; // grow the child prim, too
241
242
243 // support negative prim numbers as a delay
244 if(fprimNum < 0)
245 {
246 if(debug) llOwnerSay("Sleeping " + (string) (fprimNum * -1));
247 llSleep((float) fprimNum * -1);
248 }
249 else
250 {
251 if(fprimNum > 1 )
252 {
253 // set the local pos and locat rot to the prims orientation and position
254 rRot = calcChildRot(rRot);
255
256 list actions = [PRIM_POSITION,vPos,PRIM_ROTATION,rRot,PRIM_SIZE,vprimSize];
257 if(debug) llOwnerSay("Moving prim :" + (string) fprimNum + ":" + llDumpList2String(actions,":"));
258
259 llSetLinkPrimitiveParamsFast((integer) fprimNum,actions);
260 }
261 }
262 }
263 }
264 }
265
266 MakeMenu()
267 {
268 list amenu = ["Reset","Record","Help","Name","Notecard","Pause"] + LoadedAnims;
269
270 llListenRemove(listener);
271 listener = llListen(dialogchannel,"","","");
272
273 amenu = llDeleteSubList(amenu,12,99);
274
275 llDialog(llGetOwner(), "Pick a command",amenu,dialogchannel);
276 }
277
278
279
280 default
281 {
283 {
284 InitSize = llGetScale(); // save the size when we recorded the prims
285 nPrims = llGetNumberOfPrims(); // how many we are recording
286 if(debug) llOwnerSay(" Total Prims = " + (string) nPrims);
287 Clear();
288
290
291 if(llStringLength(notecardname) > 0)
292 {
293 kNoteCardLines = llGetNumberOfNotecardLines(NOTECARD);
294 kGetIndexLines = llGetNotecardLine(NOTECARD,0);
295 }
296 else
297 {
298 llOwnerSay("If you add a notecard, you can save your animations permanently in a notecard named " + NOTECARD);
299 }
300 dialogchannel = (integer) (llFrand(100) +600);
301
302 }
303
304 // read notecard on bootup
305 dataserver(key queryid, string data)
306 {
307 if(queryid == kNoteCardLines)
308 {
309 iIndexLines = (integer) data;
310 }
311
312 if(queryid == kGetIndexLines)
313 {
314 if(data != EOF)
315 {
316 queryid = llGetNotecardLine(NOTECARD, inotecardIndex);
317 list lLine = (llParseString2List(data, ["|"], []));
318
319 string junk = llList2String(lLine,0);
320 string aniname = llList2String(lLine,1);
321 string aNum = (string) Getline(lLine,2);
322
323 // check for the prim size,and save it, the fiorst line will look like this:
324 // [18:06] prim position 1.2: |start|<1.02306, 1.02306, 1.02306>
325
326 if(inotecardIndex == 0 && aniname == "start")
327 {
328 InitSize = (vector) aNum;
329 }
330 else if(inotecardIndex == 0 && aniname != "start")
331 {
332 llOwnerSay("The notecard " + NOTECARD + " is incorrect, it must begin with 'start|<x,y,z>' with the size of the original prim");
333 }
334 else
335 {
336
337 float Num = (float) aNum;
338
339 vector vPos = (vector) Getline(lLine,3); // global for calcChild()
340 rotation rRot = (rotation) Getline(lLine,4); // global for calcChild()
341 vector Size = (vector) Getline(lLine,5);
342
343 vector scale = llGetScale();
344 float delta = scale.x / InitSize.x ; // see if the root prim has grown or shrunk as a percentage
345
346
347 if(aniname != priorname)
348 {
349 llOwnerSay("Loading animation " + aniname);
350 priorname = aniname;
351 LoadedAnims += aniname;
352 }
353
354 if(Num != 1) // skip root prim
355 {
356 masterlist += [aniname];
357 masterlist += [Num];
358 masterlist += [vPos];
359 masterlist += [rRot];
360 masterlist += [Size];
361
362 if(Num > 1) // not the pauses
363 {
364 rRot = calcChildRot(rRot);
365 vPos *= delta; // add any difference in size to it positions there
366 Size *= delta; // grow the child prim, too
367
368 llSetLinkPrimitiveParamsFast((integer) Num,[PRIM_POSITION,vPos,PRIM_ROTATION,rRot,PRIM_SIZE,Size]);
369 move++;
370 }
371
372 }
373 }
374 inotecardIndex++;
375 integer InitPerCent = (integer) llRound(( (inotecardIndex+1) / (float) iIndexLines) * 100);
376 llSetText("Initialising... \n" + (string) InitPerCent + "%" , <1,1,1>, 1.0);
377 if(InitPerCent >= 100)
378 llSetText("" , <1,1,1>, 1.0);
379 kGetIndexLines = llGetNotecardLine(NOTECARD,inotecardIndex);
380
381 }
382 else
383 {
384 llOwnerSay("initialized with " + (string) move + " movements");
385 llSetText("" , <1,1,1>, 1.0);
386 }
387 }
388 }
389
390
391 touch_start(integer total_number)
392 {
393 if(llDetectedKey(0) == llGetOwner() && ! runtime)
394 {
395 MakeMenu();
396 }
397
398 // add any control code here
399 // example:
400 // llMessageLinked(LINK_SET,playchannel,"All",""); // will play Animation named "All"
401
402 }
403
404 listen( integer channel, string name, key id, string message )
405 {
406
407 if(channel == dialogchannel)
408 {
409 if(message == "Reset")
410 {
411 Clear();
412 if(debug) llOwnerSay("Reset = " + llDumpList2String(llastPrimList,":"));
413 MakeMenu();
414 }
415 else if(message =="Pause")
416 {
417 masterlist += curranimation;
418 masterlist += -1;
419 masterlist += <0,0,0>; // pos
420 masterlist += <0,0,0,1>;// rot
421 masterlist += <0,0,0>; // size
422 MakeMenu();
423 }
424 else if(message == "Record")
425 {
426 Record();
427
428 MakeMenu();
429 }
430 else if(message == "Name")
431 {
432 llOwnerSay("Type the current animation name on channel /" + (string) dialogchannel);
433
434 wantname++;
435 MakeMenu();
436 llTextBox(llGetOwner(),"Enter an Animation Name",dialogchannel);
437 }
438 else if(message =="Menu")
439 {
440 MakeMenu();
441 }
442 else if(message == "Notecard")
443 {
444 DumpBack();
445 MakeMenu();
446 }
447 else if(message == "Help")
448 {
449 llLoadURL(llGetOwner(),"View online help", "http://secondlife.mitsi.com/secondlife/Posts/Prim-Animator");
450 }
451 else if(wantname)
452 {
453 curranimation = message;
454
455 LoadedAnims += message;
456
457 MakeMenu();
458 llOwnerSay("Recording is ready for animation '" + curranimation + "'");
459 llOwnerSay("Position all child prims, then select the Menu item 'Record', and repeat as necessary. When finished, click 'PlayBack' to play back the animation, or click the animation name. Click 'Name' to start a new animation sequence");
460 wantname = 0;
461 PrimsCounter = 0;
462 timercounter = 0;
463 llSetTimerEvent(1.0);
464 }
465 else
466 {
467 if(llListFindList(LoadedAnims,[message]) != -1)
468 {
469 PlayBack(message);
470 MakeMenu();
471 }
472 }
473
474
475 }
476 }
477
478
479
480 link_message(integer sender_num, integer num, string message, key id)
481 {
482 if(num == playchannel)
483 {
484 if(debug) llOwnerSay("playback animation " + message);
485 PlayBack(message);
486 }
487 }
488
489
490
491
492 }

Prim_Animator_using_one_script

A simple sensor to trigger your animated prims.
If an avatar gets within a settable distance, it plays back animation 'sit'. When all avatars have left, it plays a 'stand' animation.

Category: Prim
By : Ferd Frederix
Created: 2010-10-23 Edited: 2010-10-23
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 // Sensor
3 integer sitting = FALSE;
4
5 default
6 {
8 {
9 llMessageLinked(LINK_SET,1,"stand",""); // stand on all 4's
10 llSensorRepeat("","",AGENT,5,PI,5.0); // look for people
11 }
12
13 // found an avatar
14 sensor(integer num_detected)
15 {
16 if(sitting)
17 {
18 llMessageLinked(LINK_SET,1,"sit",""); // sit on rear
19 sitting = FALSE;
20 }
21 }
22
23 // no one detected?
24 no_sensor()
25 {
26 if(! sitting)
27 {
28 llMessageLinked(LINK_SET,1,"stand",""); // stand on all 4's
29 sitting = TRUE;
30 }
31 }
32 }

Prim_Animator_using_one_script

A simple touch and playback script. When touched, it plays back animations named 'stand' and 'sit' in order, then the next time it is clicked, it plays 'sit'.

Category: Prim
By : Ferd Frederix
Created: 2010-10-23 Edited: 2010-10-23
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 integer flag;
2
3 default
4 {
5 touch_start(integer total_number)
6 {
7 if(flag++ %2 == 0)
8 {
9 llMessageLinked(LINK_SET,1,"stand",""); // stand on all 4's
10 llMessageLinked(LINK_SET,1,"wag",""); // stand on all 4's
11 }
12 else
13 llMessageLinked(LINK_SET,1,"sit",""); // sit on rear
14 }
15 }

Prim_Animator_using_one_script

Animated pet script requires recorded animatrions for left, stand , right, sit, wag

You need to pre-record 5 animations to use this script:

'right' should put the right legs forward, as when walking, and 'left' should do the opposite.
'sit should be the animal sitting down, or begging.
'stand' should be the position the animal is in when walking, with legs in a standing position.
'wag' is the tail wagging back and forth.

Category: Prim
By : Ferd Frederix
Created: 2010-10-23 Edited: 2010-10-23
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 ////////////////////////////////////////// CUT HERE ////////////////////////////////////////////
2 // pet that wanders
3
4
5 vector start_pos;
6 integer what;
7 vector Destination;
8 float roam_range = 10;
9 float STRENGTH = 4.0; // how hard to turn, bigger = ?
10 float DAMPING = 0.2; // and how soon
11 vector direction = <3,0,0>; // push 3
12 vector last_pos = <0,0,0>; // save last position so we can detect when to walk
13
14 list buttons = ["Sit","Stand","Wag","Range","Home","Help"];
15 integer listener; // handle for menus to use
16 key Owner; // you
17 integer channel; // random channel for listener
18
19 tMenu()
20 {
21 channel = llCeil(llFrand(10000) + 876);
22 listener = llListen(channel,"","","");
23 llDialog(Owner,"Choose an item",buttons,channel);
24 }
25
26 // sets up the vehicle as a car
27 Physics()
28 {
29 llSetBuoyancy(0.0);
38 llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, .1);
41 llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, .1);
48
49 }
50
51 // points the animal in the correct diriction and give it a walk-like push
52 DoMove()
53 {
55 llRotLookAt(llRotBetween(<1,0,0>, Destination - llGetPos()), STRENGTH, DAMPING);
56 llSleep(DAMPING*3);
58 llSleep(0.1);
60
61 }
62
63 // get a new destination
64 next_move()
65 {
66 // random direction
67 Destination = llGetPos();
68 Destination.x += llFrand(roam_range);
69 Destination.y += llFrand(roam_range);
70 }
71
72 DoMenu(string msg)
73 {
74 if(msg == "Sit")
75 {
76 llMessageLinked(LINK_SET,1,"sit","");
77 llListenRemove(listener);
78 }
79 else if(msg == "Wag")
80 {
81 llMessageLinked(LINK_SET,1,"wag","");
82 llListenRemove(listener);
83 }
84 else if(msg == "Stand")
85 {
86 llMessageLinked(LINK_SET,1,"stand","");
87 llListenRemove(listener);
88 }
89 else if(msg == "Range")
90 {
91 llDialog(Owner,"Range from Home:",["5","10","15","20","25","30","40","50","75"],channel);
92 }
93 else if(msg == "Home")
94 {
95 start_pos = llGetPos(); // remember our home
96 llListenRemove(listener);
97 llOwnerSay("Home is set, wander distance is set to " + (string) roam_range + " meters");
98 }
99 else if(msg == "Help")
100 {
101 llLoadURL(Owner,"Click for Help", "http://secondlife.mitsi.com/Secondlife/Posts/Prim-Animator");
102 llListenRemove(listener);
103 }
104 else
105 {
106 roam_range = (float) msg;
107 llOwnerSay("Range set to " + (string) roam_range + " meters");
108 llListenRemove(listener);
109 }
110
111 }
112
113
114
115 // startup state where we sit, stand and wag tail
116 default
117 {
119 {
120 Owner = llGetOwner();
121 llOwnerSay("Range set to " + (string) roam_range + " meters");
122 llOwnerSay("Home set here");
123 llOwnerSay("Click me for help");
124 start_pos = llGetPos(); // remember our home
125
126 state sitting;
127 }
128 }
129
130 state sitting
131 {
133 {
136 }
137
138 listen(integer channel,string name, key id, string msg)
139 {
140 DoMenu(msg);
141 }
142
144 {
145 if(llDetectedKey(0) == Owner)
146 tMenu();
147 }
148
149 timer()
150 {
151 if(what++ %2 == 0)
152 {
153 llMessageLinked(LINK_SET,1,"stand","");
154 llMessageLinked(LINK_SET,1,"wag","");
155 }
156 else
157 {
158 llMessageLinked(LINK_SET,1,"sit","");
159 }
160
161 if(what > 2)
162 {
163 what = 0;
164 state moving;
165 }
166 }
168 {
170 }
171 }
172
173 // walking around
174 state moving
175 {
177 {
178
179 Physics();
180 llMessageLinked(LINK_SET,1,"stand",""); // stand on all 4's
181 llSetStatus(STATUS_PHYSICS, TRUE); // get ready to move
182 llSetTimerEvent(0.1);
183 }
184
185 listen(integer channel,string name, key id, string msg)
186 {
187 DoMenu(msg);
188 }
189
191 {
192 if(llDetectedKey(0) == Owner)
193 tMenu();
194 }
195
196
197 timer()
198 {
199 DoMove();
200
201 if(llVecDist(last_pos, llGetPos()) > .1)
202 {
203 llMessageLinked(LINK_SET,1,"left",""); // left foot forward
204 llMessageLinked(LINK_SET,1,"stand",""); // stand on all 4's
205 llMessageLinked(LINK_SET,1,"right",""); // right foot forward
206 llMessageLinked(LINK_SET,1,"stand",""); // stand on all 4's
207 last_pos = llGetPos();
208 }
209 if(llVecDist(start_pos,llGetPos()) > roam_range)
210 Destination = start_pos;
211
212 if(llVecDist(start_pos,llGetPos()) < .5) // at home
213 state sitting;
214
215 if(llVecDist(Destination,llGetPos()) < .2) // at destination
216 next_move();
217
218
219
220 }
221
223 {
225 }
226
227 }

Prim_Animator_using_one_script

This is a sample run-time script. After you create your animation, you can delete all scripts. Then drop this one in with your notecard and it will play it back.

Category: Prim
By : Ferd Frederix
Created: 2010-10-23 Edited: 2010-10-23
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 // One Script Prim Animation
2 // Playback Script
3
4 // Original Script by: Ferd Frederix
5 // Playback Optimization by: Gino Rascon
6
7
8 string NOTECARD = "Movement"; // the notecard for this script, you can add more than 1 script and notecard, just change this line to match
9 integer playchannel = 1; // the playback channel, this is the channel you use in LinkMessages
10
11
12 integer debug = FALSE; // if set to TRUE, debug info appears
13
14
15 // notecard reading
16 string priorname; // the prior animation name so we can spot differences as we read them in
17 integer iIndexLines; // lines in a card
18 integer inotecardIndex = 0; // notecard counter;
19 integer move = 0; // N movements rea from the notecard
20
21 key kNoteCardLines; // the key of the notecard
22 key kGetIndexLines; // the key of the current line
23
24 //communications
25 integer dialogchannel ; // dialog boxes
26
27 integer nPrims; // total number of prims
28 integer PrimsCounter = 0; // how many have checked in
29 integer timercounter = 0; // how many seconds have gone by
30 integer wantname; // flag indicating we are waiting for a name to be chatted
31
32
33 // the list of coords
34 list masterlist; // master list of all positions
35 list llastPrimList; // storage of the last prim position we learned
36 string curranimation; // what we are playing
37
38 integer STRIDE = 5; // size of the master list
39 integer lastSTRIDE = 4; // size of the last prim list
40
41 integer listener; // temp listener when we are waiting for them to give us a name
42
43 vector InitSize; // the initial size when the prims were recorded
44 list LoadedAnims; // animations read from the notecard added to the Menu display
45
46 // in case of hand editing, we wupe out extra stuff at end
47 string Getline(list Input, integer line)
48 {
49 return llStringTrim(llList2String(Input, line),STRING_TRIM);
50 }
51
52 Record()
53 {
54 if(llStringLength(curranimation) > 0)
55 {
56 integer foundmovement = 0; // will be set if any child moved
57 integer PrimCounter ; // skip past the root prim
58 for (PrimCounter =2; PrimCounter <= nPrims; PrimCounter++ )
59 {
60 list my_list = llGetLinkPrimitiveParams(PrimCounter,[PRIM_POSITION,PRIM_ROTATION, PRIM_SIZE ]);
61 // position is always in region coordinates, even if the prim is a child or the root prim of an attachment.
62 // rot is always the global rotation, even if the prim is a child or the root prim of an attachment.
63
64 // get current prim pos, rot and size
65 vector vrealPrimPos = llList2Vector(my_list,0) - llGetPos(); // position subtract Global Pos
66 vrealPrimPos /= llGetRot();
67 rotation rrealPrimRot = llList2Rot(my_list,1) / llGetRot(); // rotation subtract Global Rot
68 vector vrealPrimSize = llList2Vector(my_list,2); // size
69
70 // compare it to the last one we had, stride of list is a 4, and it is already sorted
71 integer iindex = (PrimCounter - 2) * lastSTRIDE; // zeroth position is PrimCounter - start, or 2
72
73 // get the last thing we remembered about this prim
74 float fprimNum = llList2Integer(llastPrimList, iindex); // must be 0,1,2, in order
75 vector vlastPrimPos = llList2Vector(llastPrimList, iindex+1);
76 rotation rlastPrimRot = llList2Rot(llastPrimList, iindex+2);
77 vector vlastPrimSize = llList2Vector(llastPrimList, iindex+3);
78
79 // if anything changed on this prim, we must record it.
80 if(vlastPrimPos != vrealPrimPos ||
81 rlastPrimRot != rrealPrimRot ||
82 vlastPrimSize!= vrealPrimSize
83 )
84 {
85 foundmovement++;
86
87 // show owner any changes they mnade
88 if(debug)
89 {
90 llOwnerSay("prim:" + (string) PrimCounter);
91
92 if(vlastPrimPos != vrealPrimPos)
93 llOwnerSay("pos delta :" + (string) (vrealPrimPos - vlastPrimPos));
94
95 if(rlastPrimRot != rrealPrimRot)
96 llOwnerSay("rot delta:" + (string) (llRot2Euler(rrealPrimRot - rlastPrimRot) * RAD_TO_DEG));
97
98 if(vlastPrimSize != vrealPrimSize)
99 llOwnerSay("size delta:" + (string) (vrealPrimSize - vlastPrimSize));
100 }
101
102 //Save them in the master list of all animations
103 masterlist += curranimation;
104 masterlist += PrimCounter;
105 masterlist += vrealPrimPos;
106 masterlist += rrealPrimRot;
107 masterlist += vrealPrimSize;
108
109 // save them in the last movement list
110 integer saved = FALSE;
111 integer i;
112 integer imax = llGetListLength(llastPrimList);
113 // save the changes in the last prim list so we can keep our lists smaller
114 for ( i=0; i < imax; i += lastSTRIDE )
115 {
116 if(llList2Float(llastPrimList,i) == PrimCounter)
117 {
118 llastPrimList = llListReplaceList(llastPrimList,[vrealPrimPos],i+1,i+1);
119 llastPrimList = llListReplaceList(llastPrimList,[rrealPrimRot],i+2,i+2);
120 llastPrimList = llListReplaceList(llastPrimList,[vrealPrimSize],i+3,i+3);
121 if(debug) llOwnerSay("In history at position " + (string) (i/lastSTRIDE));
122 saved++;
123 }
124 }
125
126 // never moved before? add it then
127 if(! saved)
128 {
129 if(debug) llOwnerSay("Someone added a new prim and then clicked Record");
130 llastPrimList += PrimCounter;
131 llastPrimList += vrealPrimPos;
132 llastPrimList += rrealPrimRot;
133 llastPrimList += vrealPrimSize;
134 }
135 } // if
136 } // for
137 if(debug) llOwnerSay("history:" + llDumpList2String(llastPrimList,":"));
138
139 if(!foundmovement)
140 llOwnerSay("You must move at least one child prim.");
141 }
142 else
143 {
144 llOwnerSay("You must name your animation.");
145 llOwnerSay("Type the new animation name on channel /" + (string) dialogchannel);
146 wantname++;
147 }
148 }
149
150 // on reset, record the base position in history so we can see changes
151 Clear()
152 {
153 LoadedAnims = []; // wipe out Menu
154 masterlist = []; // wipe all recordings
155 llastPrimList = []; // wipe last animations
156 integer PrimCounter ; // skip 1, which is the root prim
157 integer counter = 0;
158 // save all the current settings in memory
159 for (PrimCounter=2; PrimCounter <= nPrims; PrimCounter++ )
160 {
161 list my_list = llGetLinkPrimitiveParams(PrimCounter,[PRIM_POSITION,PRIM_ROTATION, PRIM_SIZE ]);
162
163 // save the local pos and rot, since llGetLinkPrimitiveParams returns global pos and rot
164 vector primpos = llList2Vector(my_list,0) - llGetPos();
165 rotation primrot = llList2Rot(my_list,1) / llGetRot();
166 vector primsize = llList2Vector(my_list,2) ;
167
168 llastPrimList += PrimCounter;
169 llastPrimList += primpos;
170 llastPrimList += primrot;
171 llastPrimList += primsize;
172 counter++;
173 }
174 if(debug) llOwnerSay("Saved " + (string) counter + " prims initial position in history");
175 }
176
177 DumpBack ()
178 {
179 integer i;
180 integer imax = llGetListLength(masterlist);
181 integer howmany = imax / STRIDE ;
182 llOwnerSay((string) howmany + " movements recorded - copy these and paste them into the notecard");
183
184 integer flag = 0;
185 for (i = 0; i < imax; i+= STRIDE)
186 {
187 if( i == 0 )
188 llOwnerSay( "|start|" + (string) llGetScale());
189
190 string saniName = llList2String(masterlist,i);
191 curranimation = saniName;
192
193 float fprimNum = llList2Integer(masterlist, i+1);
194 integer iprimNum = (integer) fprimNum;
195 vector vprimPos = llList2Vector(masterlist, i+2);
196 rotation rprimRot = llList2Rot(masterlist, i+3) ;
197 vector vprimSize = llList2Vector(masterlist, i+4);
198
199 llOwnerSay("|"+ saniName + "|" + (string) iprimNum + "|" + (string) vprimPos + "|" + (string) rprimRot + "|" + (string) vprimSize );
200 flag++;
201 }
202 if(! flag)
203 llOwnerSay("No recording was made, nothing to play back." );
204 }
205
206
207 rotation calcChildRot(rotation rdeltaRot)
208 {
209
211 return rdeltaRot/llGetLocalRot();
212 else
213 return rdeltaRot/llGetRootRotation();
214
215 }
216
217
218 PlayBack (string name)
219 {
220 integer i;
221 integer imax = llGetListLength(masterlist);
222
223 integer linknum = 0;
224
225 for (i = 0; i < imax; i+= STRIDE)
226 {
227 string saniName = llList2String(masterlist,i);
228 if(saniName == name)
229 {
230 float fprimNum = llList2Float(masterlist,i+1);
231 vector vPos = llList2Vector(masterlist,i+2);
232 rotation rRot = llList2Rot(masterlist,i+3) ;
233 vector vprimSize = llList2Vector(masterlist,i+4) ;
234
235 vector scale = llGetScale();
236 float delta = scale.x / InitSize.x ; // see if the root prim has grown or shrunk as a percentage
237
238 vPos *= delta; // add any difference in size to it positions there
239 vprimSize *= delta; // grow the child prim, too
240
241
242 // support negative prim numbers as a delay
243 if(fprimNum < 0)
244 {
245 if(debug) llOwnerSay("Sleeping " + (string) (fprimNum * -1));
246 llSleep((float) fprimNum * -1);
247 }
248 else
249 {
250 if(fprimNum > 1 )
251 {
252 // set the local pos and locat rot to the prims orientation and position
253 rRot = calcChildRot(rRot);
254
255 list actions = [PRIM_POSITION,vPos,PRIM_ROTATION,rRot,PRIM_SIZE,vprimSize];
256 if(debug) llOwnerSay("Moving prim :" + (string) fprimNum + ":" + llDumpList2String(actions,":"));
257
258 llSetLinkPrimitiveParamsFast((integer) fprimNum,actions);
259 }
260 }
261 }
262 }
263 }
264
265 MakeMenu()
266 {
267 list amenu = ["Reset","Record","Help","Name","Notecard","Pause"] + LoadedAnims;
268
269 llListenRemove(listener);
270 listener = llListen(dialogchannel,"","","");
271
272 llDialog(llGetOwner(), "Pick a command",amenu,dialogchannel);
273 }
274
275
276
277 default
278 {
280 {
281 InitSize = llGetScale(); // save the size when we recorded the prims
282 nPrims = llGetNumberOfPrims(); // how many we are recording
283 if(debug) llOwnerSay(" Total Prims = " + (string) nPrims);
284 Clear();
285
287
288 if(llStringLength(notecardname) > 0)
289 {
290 kNoteCardLines = llGetNumberOfNotecardLines(NOTECARD);
291 kGetIndexLines = llGetNotecardLine(NOTECARD,0);
292 }
293 else
294 {
295 llOwnerSay("If you add a notecard, you can save your animations permanently in a notecard named " + NOTECARD);
296 }
297 dialogchannel = (integer) (llFrand(100) +600);
298
299 }
300
301 // read notecard on bootup
302 dataserver(key queryid, string data)
303 {
304 if(queryid == kNoteCardLines)
305 {
306 iIndexLines = (integer) data;
307 }
308
309 if(queryid == kGetIndexLines)
310 {
311 if(data != EOF)
312 {
313 queryid = llGetNotecardLine(NOTECARD, inotecardIndex);
314 list lLine = (llParseString2List(data, ["|"], []));
315
316 string junk = llList2String(lLine,0);
317 string aniname = llList2String(lLine,1);
318 string aNum = (string) Getline(lLine,2);
319
320 // check for the prim size,and save it, the fiorst line will look like this:
321 // [18:06] prim position 1.2: |start|<1.02306, 1.02306, 1.02306>
322
323 if(inotecardIndex == 0 && aniname == "start")
324 {
325 InitSize = (vector) aNum;
326 }
327 else if(inotecardIndex == 0 && aniname != "start")
328 {
329 llOwnerSay("The notecard " + NOTECARD + " is incorrect, it must begin with 'start|<x,y,z>' with the size of the original prim");
330 }
331 else
332 {
333
334 float Num = (float) aNum;
335
336 vector vPos = (vector) Getline(lLine,3); // global for calcChild()
337 rotation rRot = (rotation) Getline(lLine,4); // global for calcChild()
338 vector Size = (vector) Getline(lLine,5);
339
340 vector scale = llGetScale();
341 float delta = scale.x / InitSize.x ; // see if the root prim has grown or shrunk as a percentage
342
343
344 if(aniname != priorname)
345 {
346 llOwnerSay("Loading animation " + aniname);
347 priorname = aniname;
348 LoadedAnims += aniname;
349 }
350
351 if(Num != 1) // skip root prim
352 {
353 masterlist += [aniname];
354 masterlist += [Num];
355 masterlist += [vPos];
356 masterlist += [rRot];
357 masterlist += [Size];
358
359 if(Num > 1) // not the pauses
360 {
361 rRot = calcChildRot(rRot);
362 vPos *= delta; // add any difference in size to it positions there
363 Size *= delta; // grow the child prim, too
364
365 llSetLinkPrimitiveParamsFast((integer) Num,[PRIM_POSITION,vPos,PRIM_ROTATION,rRot,PRIM_SIZE,Size]);
366 move++;
367 }
368
369 }
370 }
371 inotecardIndex++;
372 integer InitPerCent = (integer) llRound(( (inotecardIndex+1) / (float) iIndexLines) * 100);
373 llSetText("Initialising... \n" + (string) InitPerCent + "%" , <1,1,1>, 1.0);
374 if(InitPerCent >= 100)
375 llSetText("" , <1,1,1>, 1.0);
376 kGetIndexLines = llGetNotecardLine(NOTECARD,inotecardIndex);
377
378 }
379 else
380 {
381 llOwnerSay("initialized with " + (string) move + " movements");
382 llSetText("" , <1,1,1>, 1.0);
383 }
384 }
385 }
386
387
388 // touch_start(integer total_number)
389 //{
390 // if(llDetectedKey(0) == llGetOwner())
391 //{
392 // MakeMenu();
393 //}
394
395 // add any control code here
396 // example:
397 // llMessageLinked(LINK_SET,playchannel,"All",""); // will play Animation named "All"
398
399 //}
400
401 listen( integer channel, string name, key id, string message )
402 {
403
404 if(channel == dialogchannel)
405 {
406 if(message == "Reset")
407 {
408 Clear();
409 if(debug) llOwnerSay("Reset = " + llDumpList2String(llastPrimList,":"));
410 MakeMenu();
411 }
412 else if(message =="Pause")
413 {
414 masterlist += curranimation;
415 masterlist += -1;
416 masterlist += <0,0,0>; // pos
417 masterlist += <0,0,0,1>;// rot
418 masterlist += <0,0,0>; // size
419 MakeMenu();
420 }
421 else if(message == "Record")
422 {
423 Record();
424
425 MakeMenu();
426 }
427 else if(message == "Name")
428 {
429 llOwnerSay("Type the current animation name on channel /" + (string) dialogchannel);
430 wantname++;
431 MakeMenu();
432 }
433 else if(message =="Menu")
434 {
435 MakeMenu();
436 }
437 else if(message == "Notecard")
438 {
439 DumpBack();
440 MakeMenu();
441 }
442 else if(message == "Help")
443 {
444 llLoadURL(llGetOwner(),"View online help", "http://secondlife.mitsi.com/secondlife/Posts/Prim-Animator");
445 }
446 else if(wantname)
447 {
448 curranimation = message;
449
450 LoadedAnims += message;
451
452 MakeMenu();
453 llOwnerSay("Recording is ready for animation '" + curranimation + "'");
454 llOwnerSay("Position all child prims, then select the Menu item 'Record', and repeat as necessary. When finished, click 'PlayBack' to play back the animation, or click the animation name. Click 'Name' to start a new animation sequence");
455 wantname = 0;
456 PrimsCounter = 0;
457 timercounter = 0;
458 llSetTimerEvent(1.0);
459 }
460 else
461 {
462 if(llListFindList(LoadedAnims,[message]) != -1)
463 {
464 PlayBack(message);
465 MakeMenu();
466 }
467 }
468
469
470 }
471 }
472
473
474
475 link_message(integer sender_num, integer num, string message, key id)
476 {
477 if(num == playchannel)
478 {
479 if(debug) llOwnerSay("playback animation " + message);
480 PlayBack(message);
481 }
482 }
483
484
485
486
487 }

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