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_Animation_Compiler  

Prim_Animation_Compiler

For more details on how this script works, see http://www.outworldz.com/secondlife/posts/prim-compiler/
This is the Animator menu system. You will also need the compiler script

Category: Prim
By : Ferd Frederix
Created: 2013-02-25 Edited: 2015-08-07
Worlds: Second Life

the Zip file

Download all files for Prim_Animation_Compiler
Contents are in zip format, with .LSL (text) source code and LSLEdit (text + Solution) formats.
Get file # 1. Alternating Up and Down example trigger.lsl
Get file # 2. Another way to alternate on touch example.lsl
Get file # 3. Example listen script.lsl
Get file # 4. Prim_Animation_Compiler by Patchouli Woollahra.lsl
Get file # 5. Prim_Animation_Compiler.lsl
Get file # 6. Prim_Animation_Recorder.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 // Rev 2: allow anyone to use it - just click Finish and others can get an animation menu.
3 // fred@mitsi.com
4 // 2-19-2012
5
6 // Animator front-end for Compiler Script
7 // This is free software, it is not for sale at any price. Yu can use it and sell the object.
8
9 integer playchannel = 1; // the playback channel, this is the channel you use in LinkMessages
10 integer debug = FALSE; // if set to TRUE, debug info appears
11 integer dialogchannel ; // dialog boxes
12 integer nPrims; // total number of prims
13 integer wantname; // flag indicating we are waiting for a name to be chatted
14 integer wantnum; // flag asking for numbers to be chatted.
15 integer finished = FALSE; // flag to only show the recorded animations
16 // Link messages
17 integer CLEAR = -234756;
18 integer DATA = -234757;
19 integer COMPILE = -234758;
20 integer DIE = -234759;
21
22 // the list of coords
23 list masterlist; // master list of all positions
24 list llastPrimList; // storage of the last prim position we learned
25 string curranimation; // what we are playing
26 integer STRIDE = 5; // size of the master list
27 integer lastSTRIDE = 3; // size of the last prim list
28 integer listener; // temp listener when we are waiting for them to give us a name
29 vector InitSize; // the initial size when the prims were recorded
30 list LoadedAnims; // animations added to the Menu display
31
32 DEBUG(string msg)
33 {
34 if(debug) llOwnerSay("// " + msg);
35 }
36
37 Record()
38 {
39 if(llStringLength(curranimation) > 0)
40 {
41 integer foundmovement = 0; // will be set if any child moved
42 integer PrimCounter ; // skip past the root prim
43 for (PrimCounter =2; PrimCounter <= nPrims; PrimCounter++ )
44 {
45 //DEBUG("Checking Prim " + (string) PrimCounter);
46
47 list my_list = llGetLinkPrimitiveParams(PrimCounter,[PRIM_POSITION,PRIM_ROTATION, PRIM_SIZE ]);
48 // position is always in region coordinates, even if the prim is a child or the root prim of an attachment.
49 // rot is always the global rotation, even if the prim is a child or the root prim of an attachment.
50 // get current prim pos, rot and size
51 vector vrealPrimPos = llList2Vector(my_list,0) - llGetPos(); // position subtract Global Pos
52 vrealPrimPos /= llGetRot();
53 rotation rrealPrimRot = llList2Rot(my_list,1) / llGetRot(); // rotation subtract Global Rot
54 vector vrealPrimSize = llList2Vector(my_list,2); // size
55
56 // compare it to the last one we had
57 integer iindex = (PrimCounter - 2) * lastSTRIDE; // zeroth position is PrimCounter - start, or 2
58
59 // get the last thing we remembered about this prim
60 vector vlastPrimPos = llList2Vector(llastPrimList, iindex);
61 rotation rlastPrimRot = llList2Rot(llastPrimList, iindex+1);
62 vector vlastPrimSize = llList2Vector(llastPrimList, iindex+2);
63
64 //if(debug)
65 //{
66 // vrealPrimPos = <1,2,llFrand(1)>; // make a small change for debugging in LSL Editor
67 //}
68
69 // if anything changed on this prim, we must record it.
70 if(vlastPrimPos != vrealPrimPos ||
71 rlastPrimRot != rrealPrimRot ||
72 vlastPrimSize!= vrealPrimSize
73 )
74 {
75 foundmovement++;
76
77 //Save changes in the master list of all animations
78 masterlist += curranimation;
79 masterlist += (float) PrimCounter;
80 masterlist += vrealPrimPos;
81 masterlist += rrealPrimRot;
82 masterlist += vrealPrimSize;
83
84 string msg = curranimation + "|" + (string) PrimCounter + "|" + (string) vrealPrimPos + "|" + (string) rrealPrimRot + "|" + (string) vrealPrimSize ;
85 llMessageLinked(LINK_ROOT,DATA,msg,"");
86
87 // update the last movement list
88 llastPrimList = llListReplaceList(llastPrimList,[vrealPrimPos],iindex,iindex);
89 llastPrimList = llListReplaceList(llastPrimList,[rrealPrimRot],iindex+1,iindex+1);
90 llastPrimList = llListReplaceList(llastPrimList,[vrealPrimSize],iindex+2,iindex+2);
91
92 } // if
93 else
94 {
95 //DEBUG( (string) PrimCounter);
96 }
97 } // for
98
99 //DEBUG("history:" + llDumpList2String(llastPrimList,":"));
100
101 if(foundmovement)
102 {
103 llOwnerSay("Recorded " + (string) foundmovement + " prims" );
104 }
105 else
106 {
107 llOwnerSay("You must move at least one child prim.");
108 }
109 }
110 else
111 {
112 llOwnerSay("You must name your animation.");
113 llOwnerSay("Type the new animation name on channel /" + (string) dialogchannel);
114 wantname++;
115 }
116 }
117
118 // on reset, record the base position in history so we can see changes
119 Clear()
120 {
121 llMessageLinked(LINK_ROOT,CLEAR,"","");
122 LoadedAnims = []; // wipe out Menu
123 masterlist = []; // wipe all recordings
124 llastPrimList = []; // wipe last animations
125 integer PrimCounter ; // skip 1, which is the root prim
126 integer counter = 0;
127 // save all the current settings in memory
128 for (PrimCounter=2; PrimCounter <= nPrims; PrimCounter++ )
129 {
130 list my_list = llGetLinkPrimitiveParams(PrimCounter,[PRIM_POSITION,PRIM_ROTATION, PRIM_SIZE ]);
131
132 // save the local pos and rot, since llGetLinkPrimitiveParams returns global pos and rot
133 vector primpos = llList2Vector(my_list,0) - llGetPos();
134 primpos /= llGetRot();
135 rotation primrot = llList2Rot(my_list,1) / llGetRot();
136 vector primsize = llList2Vector(my_list,2) ;
137
138
139 llastPrimList += primpos;
140 llastPrimList += primrot;
141 llastPrimList += primsize;
142 counter++;
143 }
144 llOwnerSay("There are " + (string) counter + " animatable prims");
145 }
146
147 DumpBack ()
148 {
149 integer imax = llGetListLength(masterlist);
150 integer howmany = imax / STRIDE ;
151 llOwnerSay("Preprocessing " + (string) howmany + " movements. " );
152 llMessageLinked(LINK_ROOT,COMPILE,"","");
153 }
154
155
156 rotation calcChildRot(rotation rdeltaRot)
157 {
158
160 return rdeltaRot/llGetLocalRot();
161 else
162 return rdeltaRot/llGetRootRotation();
163
164 }
165
166
167 PlayBack (string name)
168 {
169 integer i;
170 integer imax = llGetListLength(masterlist);
171
172 integer linknum = 0;
173
174 for (i = 0; i < imax; i+= STRIDE)
175 {
176 string saniName = llList2String(masterlist,i);
177
178 vector scale = llGetScale();
179 float delta = scale.x / InitSize.x ; // see if the root prim has grown or shrunk as a percentage
180 if(saniName == name)
181 {
182 float fprimNum = llList2Float(masterlist,i+1);
183 vector vPos = llList2Vector(masterlist,i+2);
184 rotation rRot = llList2Rot(masterlist,i+3) ;
185 vector vprimSize = llList2Vector(masterlist,i+4) ;
186
187 vPos *= delta; // add any difference in size to it positions there
188 vprimSize *= delta; // grow the child prim, too
189
190 // support negative prim numbers as a delay
191 if(fprimNum < 0)
192 {
193 // DEBUG("Sleeping " + (string) (fprimNum * -1));
194 llSleep((float) fprimNum * -1);
195 }
196 else
197 {
198 // set the local pos and locat rot to the prims orientation and position
199 rRot = calcChildRot(rRot);
200
201 list actions = [PRIM_POSITION,vPos,PRIM_ROTATION,rRot,PRIM_SIZE,vprimSize];
202 //DEBUG("Moving prim :" + (string) fprimNum + ":" + llDumpList2String(actions,":"));
203
204 llSetLinkPrimitiveParamsFast((integer) fprimNum,actions);
205 }
206 }
207 }
208 }
209
210 MakeMenu()
211 {
212 list amenu ;
213 if(finished)
214 amenu = LoadedAnims;
215 else
216 amenu = ["Reset","Record","Help","Name","Compile","Pause", "Finish"] + LoadedAnims;
217
218 llListenRemove(listener);
219 listener = llListen(dialogchannel,"","","");
220 amenu = llDeleteSubList(amenu,12,99);
221 llDialog(llGetOwner(), "Pick a command",amenu,dialogchannel);
222 }
223
224
225 default
226 {
228 {
229 InitSize = llGetScale(); // save the size when we recorded the prims
230 nPrims = llGetNumberOfPrims(); // how many we are recording
231 llOwnerSay("Prim count = " + (string) nPrims);
232 Clear();
233
234 dialogchannel = (integer) (llFrand(100) +600);
235 MakeMenu();
236 }
237
238
239 touch_start(integer total_number)
240 {
241 MakeMenu();
242 }
243
244 listen( integer channel, string name, key id, string message )
245 {
246 if(message == "Finish")
247 {
248 finished =TRUE;
249 MakeMenu();
250 }
251 else if(message == "Reset")
252 {
254 }
255 else if(wantnum)
256 {
257 float num = (float) message;
258 if(num > 0.0)
259 {
260 num = -1 * (num /1000);
261 masterlist += curranimation;
262 masterlist += num;
263 masterlist += <0,0,0>; // pos
264 masterlist += <0,0,0,1>;// rot
265 masterlist += <0,0,0>; // size
266 string msg = curranimation + "|" + (string) num + "|<0,0,0>|<0,0,0,1>|<0,0,0>" ;
267 llMessageLinked(LINK_ROOT,DATA,msg,"");
268 }
269 else
270 {
271 llOwnerSay("Please enter numbers in milliseconds. 1000=1000ms = 1 second. 500=500ms = 1/2 a second.");
272 llOwnerSay("What is a milliHelen? A milliHelen is a face that can launch one ship!");
273 }
274 wantnum = FALSE;
275 MakeMenu();
276 }
277 else if(message =="Pause")
278 {
279 wantnum= TRUE;
280 llListenRemove(listener);
281 listener = llListen(dialogchannel,"","","");
282 llTextBox(llGetOwner(), "Enter a delay in milliseconds:\n1000 = 1 second\n500 = 1/2 second",dialogchannel);
283 }
284 else if(message == "Record")
285 {
286 Record();
287 MakeMenu();
288 }
289 else if(message == "Name")
290 {
291 llOwnerSay("Enter a new name, or type the animation name on channel /" + (string) dialogchannel);
292
293 wantname = TRUE;
294 MakeMenu();
295 llTextBox(llGetOwner(),"Enter an Animation Name",dialogchannel);
296 }
297 else if(message == "Compile")
298 {
299 DumpBack();
300 MakeMenu();
301 }
302 else if(message == "Help")
303 {
304 llLoadURL(llGetOwner(),"View online help", "http://secondlife.mitsi.com/secondlife/Posts/Prim-Compiler");
305 }
306 else if(wantname)
307 {
308 curranimation = message;
309 LoadedAnims += message;
310
311 MakeMenu();
312 llOwnerSay("Recording is ready for animation '" + curranimation + "'");
313 llOwnerSay("Position any child prims, then select the menu item 'Record', and repeat as necessary. When finished, click 'Compile' to save the animation, or click the animation name to play it back. Click 'Name' to start a new animation sequence");
314 wantname = 0;
315 }
316 else
317 {
318 if(llListFindList(LoadedAnims,[message]) != -1)
319 {
320 PlayBack(message);
321 MakeMenu();
322 }
323 }
324
325
326 }
327 }

Prim_Animation_Compiler

This script produces optimized LSL code that can be triggered by link messages.
For more details on how this script works, see http://www.outworldz.com/secondlife/posts/prim-compiler/

Category: Prim
By : Ferd Frederix
Created: 2013-02-25 Edited: 2015-08-07
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 // fred@mitsi.com
2 // 3-7-2012
3 // Rev 1.1, added a missing } at the end of multiple recordings.
4
5
6 // Author: Ferd Frederix
7 // Based on an excellent script by Allen Firethorn
8 // This is free software, it is not for sale at any price. Yu can use it and sell the object.
9
10 // Tunable stuff:
11 integer OpenSim = FALSE; // Set to FALSE for Second Life to save memory
12 string fast="Fast"; // Set this to an empty string if you don't want to use the fast animation
13 integer debug = FALSE; // set to TRUE to see stuff inside as it runs
14
15 list animations; // holds a list of all animation names
16 list receivedData; // the data from the main program
17 integer STRIDE = 5; // size of the data packets in receivedData
18 integer currentLine; // the line we are processing
19
20 // Link messages
21 integer CLEAR = -234756;
22 integer DATA = -234757;
23 integer COMPILE = -234758;
24 integer DIE = -234759;
25
26 DEBUG(string msg)
27 {
28 if(debug) llOwnerSay("// " + msg);
29 }
30
31 // speak without the name of the prim in the way
32 SayCode (string story){
33 llOwnerSay(story);
34 llSleep(0.1);
35
36 }
37
38 default {
39
40 link_message(integer sender_num,integer num, string msg, key id) {
41
42 if(num == DIE && msg =="die") // clear
43 {
44 llOwnerSay("Compiler has been removed");
45 if(! debug) {
47 }
48 }
49
50 if(num == CLEAR) // clear
51 {
52 animations = [];
53 receivedData = [];
54 currentLine = 0;
55 llOwnerSay("Compiler Ready");
56 }
57 else if(num == DATA) // data
58 {
59 // data formatted like this:
60 // name|primnum|vector Pos|rotation rot|vector size
61 // test1|2|<0.026306,-0.150208,0.191069>|<-0.000008,0.956309,-0.292356,0.000000>|<0.074010,0.074010,0.074010>
62 list primList = llParseString2List(msg,["|"],[]);
63 string name = llList2String(primList,0);
64
65 receivedData += name;
66 receivedData += (float) llList2String(primList,1); // prim Number or ms to sleep
67 receivedData += (vector) llList2String(primList,2); // pos
68 receivedData += (rotation) llList2String(primList,3); // rot
69 receivedData += (vector) llList2String(primList,4); // size
70
71 // Store the name of the animation if it is not already stored
72 integer i = llListFindList(animations, [name]);
73
74 if( i < 0 ){
75 DEBUG("Adding Animation named " + name);
76 animations += name;
77 }
78
79 currentLine++;
80 }
81 else if(num == COMPILE) // finish, compile it
82 {
83
84 //DEBUG("Animations:" + llDumpList2String(animations,":"));
85 //DEBUG("Length:" + ((string) llGetListLength(animations)));
86 //DEBUG("history:" + llDumpList2String(receivedData,":"));
87 //DEBUG("Length:" + ((string) llGetListLength(receivedData)));
88
89
90 string code;
91 integer i;
92
93 llOwnerSay("Compiler processing " + (string)currentLine + " prim movements and " + (string) llGetListLength(animations) + " animations");
94
95 llOwnerSay("Copy everything below this line and paste it into a new script\n");
96
97 string oldname = llGetObjectName();
98 llSetObjectName("Compiler");
99
100 vector scale = llGetScale();
101 SayCode("// Prim animation compiler //\n"
102 + "// Ferd Frederix - http://www.outworldz.com\n"
103 + "integer playbackchannel = 1; // The default llMessageLinked number\n"
104 + "rotation calcChildRot(rotation rdeltaRot){\n"
105 + "\tif(llGetAttached())\n"
106 + "\t\treturn rdeltaRot/llGetLocalRot();\n"
107 + "\telse\n"
108 + "\t\treturn rdeltaRot/llGetRootRotation();\n"
109 + "}\n"
110 + "vector originalScale = "
111 + (string) scale
112 + ";"
113 );
114
115
116
117 // Go through each animation and create a function for each one
118 for(i = 0; i < llGetListLength(animations); i++){
119 integer j;
120 string animationName = llList2String(animations, i);
121
122 //DEBUG("Processing " + animationName);
123
124 SayCode(animationName
125 + "(){\n"
126 + "\tvector currentSize = llGetScale();\n"
127 + "\tfloat scaleby = currentSize.x/originalScale.x;\n"
128 );
129
130
131
132 //Read through the list and print out the instructions for this animation
133 integer count = llGetListLength(receivedData);
134 for(j=0; j < count; j += STRIDE)
135 {
136 string name = llList2String(receivedData,j);
137 float primNum = (float) llList2String(receivedData,j+1);
138
139 //DEBUG("name: " + name + " Prim Num: " + primNum);
140 if( name == animationName){
141 if(primNum > 1){ // not a root prim or sleep
142 SayCode( "\tllSetLinkPrimitiveParams"
143 + fast
144 + "("
145 + (string) ((integer)primNum)
146 + ", [PRIM_POSITION, "
147 + (string) llList2Vector(receivedData,j+2)
148 + "*scaleby, "
149 + "PRIM_ROTATION,calcChildRot("
150 + (string) llList2Rot(receivedData,j+3)
151 + "), "
152 + "PRIM_SIZE, "
153 + (string) llList2Vector(receivedData,j+4)
154 + "*scaleby]);"
155 );
156 } else {
157 SayCode("\tllSleep("
158 +(string)(primNum*-1) // negative numbers are sleep times
159 +");"
160 );
161 }
162 } // if name
163 } // for j
164 SayCode ("\n}");
165 } // for animations
166
167 SayCode (
168 "\n\n"
169 + "default{\n"
170 );
171 if(!OpenSim)
172 SayCode("\tstate_entry(){\n"
173 +"\t\tllSetMemoryLimit(llGetUsedMemory() + 512);\n"
174 + "\t\t}");
175
176 code = "\n\tlink_message(integer sender_num, integer num, string message, key id){\n"+
177 "\t\tif(num == playbackchannel){\n";
178 for(i=0; i<llGetListLength(animations);i++){
179 code+="\t\t\tif(message == \""+llList2String(animations,i)+"\"){\n"+
180 "\t\t\t\t"+llList2String(animations,i)+"();\n"+
181 "\t\t\t}\n";
182 }
183 code += "\t\t}\n"+
184 "\t}\n}";
185 SayCode(code);
186
187 SayCode("// Done! Copy everything above to a new script, and Search/Replace the time stamp and Compiler: on the left to be blank");
188 llSetObjectName(oldname);
189
190 }
191 }
192
193
194 }

Prim_Animation_Compiler

Simple trigger script example. Alternates playing animation named sit and wag when you touch a prim.
It uses a different way to alternate the action than the Aternating Up and Down example
It divides an ever-increasing number (flag++) by 2, ( flag++ % 2) and looks at the remainder (%). For example, 2/2 = 1 with 0 remaining, 3/2 = 1 with a remainder of 0.5.
so this means it detects ODD or EVEN numbers, which occur ever other touch. Its dioes the same as (x = ~x) in a more general way. You could have it do this every fifth touch with (flag++ % 5), as another example.

Category: Prim
By : Ferd Frederix
Created: 2013-02-25 Edited: 2015-08-07
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 integer flag; // this increments forever,sort of, well, for all practical purposes.
3
4 default
5 {
6 touch_start(integer total_number)
7 {
8 if(flag++ %2 == 0)
9 {
10 llMessageLinked(LINK_SET,1,"wag",""); // wag tail
11 }
12 else
13 llMessageLinked(LINK_SET,1,"sit",""); // sit on rear
14 }
15 }

Prim_Animation_Compiler

simple owner-only chat to animator script.

Category: Prim
By : Ferd Frederix
Created: 2013-02-25 Edited: 2015-08-07
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 default
3 {
4 on_rez(integer param) {
6 }
7
9 llListen(0,"","","");
10 }
11 listen(integer channel, string name, key id, string message)
12 {
13 if(llGetOwner() == id)
14 llMessageLinked(LINK_SET,1,message,"");
15 }
16 }

Prim_Animation_Compiler

This script starts a timer each one second.
Each second, it changes a -1 to a zero, or a zero to a -1. (x= ~x)
So each second, this will be TRUE ( -1) or FALSE (0)
It then sends a link message with the required Number 1 and an UP or a DOWN.

Category: Prim
By : Ferd Frederix
Created: 2013-02-25 Edited: 2015-08-07
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 integer x = -1; // this toggles between -1 and 0
4
5 default
6 {
8 {
9 llSetTimerEvent(1); // once a second
10 }
11
12 timer()
13 {
14 if(x = ~x)
15 llMessageLinked(LINK_SET,1,"UP","");
16 else
17 llMessageLinked(LINK_SET,1,"DOWN","");
18 }
19 }

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