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
Color The_Color_Master_by_Tyken_Hightower  

The_Color_Master_by_Tyken_Hightower

The Color Master by Tyken Hightower.lsl

Category: Color
By : Anonymous
Created: 2010-01-10 Edited: 2010-01-10
Worlds: Second Life

the Zip file

Download all files for The_Color_Master_by_Tyken_Hightower
Contents are in zip format, with .LSL (text) source code and LSLEdit (text + Solution) formats.
Get file # 1. The_Color_Master_by_Tyken_Hightower_1.lsl
1
2 //********************************************************
3 //This Script was pulled out for you by YadNi Monde from the SL FORUMS at http://forums.secondlife.com/forumdisplay.php?f=15, it is intended to stay FREE by it s author(s) and all the comments here in ORANGE must NOT be deleted. They include notes on how to use it and no help will be provided either by YadNi Monde or it s Author(s). IF YOU DO NOT AGREE WITH THIS JUST DONT USE!!!
4 //********************************************************
5
6
7
8
9
10
11
12
13 //The Color Master
14 //UPDATE 02/26/07: Pasted new code into this post. Allows for prims to be part of multiple groups (explained in the script comments at top), and fixed minor bugs.
15 //
16 //One night, out of boredom, I decided it would be fun and potentially useful to make a script that acts as a coloring engine (including alpha) for any whole object. I know many people tend to rely on color-changing abilities in their products by means of putting a script in every prim and having them take commands link messages. While this is generally an elegant solution that takes relatively little time to implement (all you need to do is make a script for each set of prims that needs to be colored, or, more tediously, for individual prims if they require different faces).
17 //However, we've probably all seen things like the 170-prim (or more) wings, cars, etc., that have a script in every prim. Clearly, at this point, the solution is no longer efficient for simulator performance. So to that end, I made a solution that allows for all of this, in a single script.
18 //
19 //Current Features (at time of posting)
20 //> Fully menu-driven user interface
21 //> Optional full-feature object-only control through link messages, plus the ability to trigger a menu for a specific avatar
22 //> Definitions for specific sets of prims to color
23 //> Definitions for specific faces on any prim
24 //> Coloring options for specific prims on touch
25 //> Coloring options for defined sets or all prims (can be a part of multiple groups)
26 //
27 //In order to define sets of prims and faces, I store information in the linked prims' names, as well as the object's description. The arguments are separated by the '/' character. In the object description are the names of all the defined groups, the group the root prim belongs to (if any), and the predefined faces for the root prim (if any). The child prims store the same data in their names, except that the first argument in any child is the name of the child (if you want to name it), not the names of all of the groups. Finally, names of the groups are separated by commas, and the predefined faces are separated just by '/'s.
28 //
29 //An example would look like this:
30 //Root prim's description: "Foo,Bar/Foo/0/1/3"
31 //
32 //This means that there are two predefined groups, "Foo" and "Bar". The root prim is a member of "Foo," and the example child prim is a member of "Bar." The predefined faces to color on the root prim are 0, 1, and 3; the predefined faces on the child prim are 0, 2, and 3.
33 //
34 //Play around with it; comments/inquiries/suggestions are welcome. Most of the code is not commented well, except the link message controls. I personally believe the purposes of many functions and such are obvious, although that's clearly only IMHO.
35 //I've mildly tested everything (except the link message controls), but it should all work fluidly. I made this in 2 days off and on, so it's not entirely as elegant as it could be. Some parts (particularly the listen conditionals) are spaghetti code (definitely needs comments, too lazy), and might look cleaner with revision. The script uses 2 separate listens on random, rare channels that automatically close themselves after 2 minutes of inactivity.
36 //
37 //Cheers!
38
39
40
41 //In order to define sets of prims and faces, I store information in the linked prims' names, as well as the object's description.
42 //The arguments are separated by the '/' character.
43 //In the object description are the names of all the defined possible groups, the group(s) the root prim belongs to (if any), and the predefined faces for the root prim (if any).
44 //The child prims store the same data in their names, except that the first argument in any child is the name of the child (if you want to name it), not the names of all of the possible groups.
45 //Finally, names of the groups are separated by commas, and the predefined faces are separated just by '/'s.
46
47 //An example would look like this:
48 //Root prim's description: "Foo,Bar/Foo/0/1/3"
49 //Example child prim that belongs to both groups: "Random Child Prim Name/Foo,Bar/0/2/3"
50
51 //This means that there are two predefined groups, "Foo" and "Bar".
52 //The root prim is a member of "Foo," and the example child prim is a member of "Bar." The second example belongs to both.
53 //The predefined faces to color on the root prim are 0, 1, and 3; the predefined faces on the child prim are 0, 2, and 3.
54
55
56 integer listener = 0;
57 integer com_channel = 0;
58 integer data_listen = 0;
59 integer data_channel = 0;
60
61 integer touch_active = TRUE;
62 integer plugin_use = FALSE;
63 integer touched_link = -1;
64 string touched_data = "";
65 string touched_name = "";
66 list touched_faces = [];
67 string auto = "ALL_SIDES";
68 string group = "";
69
70 vector color = <1.0,1.0,1.0>;
71 float alpha = 1.0;
72
73 key user_id = "";
74 string last_menu = "";
75 string sub_menu = "";
76 string adjusting = "";
77
78 float touch_timeout = 120.0;
79
80 open_channel() {
81 llListenRemove(listener);
82 llListenRemove(data_listen);
83 com_channel = (integer)(llCeil(llFrand(2000000000.0)) + 1000.0);
84 data_channel = -(integer)(llCeil(llFrand(2000000000.0)) + 1000.0);
85 listener = llListen(com_channel, "", user_id, "");
86 data_listen = llListen(data_channel, "", user_id, "");
87 llSetTimerEvent(touch_timeout);
88 }
89
90 string fetch_name(string data) {
91 if(touched_link == LINK_ROOT || touched_link == 0) return llGetObjectName();
92 else return llList2String(llParseStringKeepNulls(data, ["/"], []), 0);
93 }
94
95 string fetch_group(string data) {
96 return llList2String(llParseStringKeepNulls(data, ["/"], []), 1);
97 }
98
99 list fetch_faces(string data) {
100 list temp = llParseStringKeepNulls(data, ["/"], []);
101 integer i = 0;
102 integer length = (temp != []);
103 for (i = 0; i < length; i = -~i)
104 temp = llListReplaceList(temp, [llList2Integer(temp, i)], i, i);
105 return llList2List(temp, 2, -1);
106 }
107
108 list generate_groups() {
110 integer i = 0;
111 integer length = (groups != []);
112 for (i = 0; i < length; i = -~i) if(llList2String(groups, i) == "") groups = llDeleteSubList(groups, i, i);
113 return groups;
114 }
115
116 string format_color() {
117 return "Current Color: " + (string)((integer)(color.x * 255.0)) + "R " + (string)((integer)(color.y * 255.0)) + "G " + (string)((integer)(color.z * 255.0)) + "B";
118 }
119
120 string format_alpha() {
121 return "Current Opacity: " + (string)((integer)(alpha * 100.0)) + "%";
122 }
123
124 main_menu() {
125 last_menu = "main_menu";
126 string text = "";
127 list buttons = ["Set Prims", "All Prims"];
128
129 if(touched_link >= 0) {
130 buttons = ["This Prim"] + buttons;
131 touched_name = fetch_name(touched_data);
132 if(touched_name != "") text += "Selection: " + touched_name + "\n\n";
133 else text += "Selection: [Unnamed Prim]\n\n";
134 }
135
136 if(plugin_use) buttons += ["Done"];
137
138 text += "Coloring options:";
139
140 open_channel();
141
142 llDialog(user_id, text, buttons, com_channel);
143 }
144
145 prim_menu() {
146 last_menu = "prim_menu";
147 string text = "";
148
149 if(touched_name != "") text += "Selection: " + touched_name + "\n";
150 else text += "Selection: [Unnamed Prim]\n";
151
152 if(touched_faces == []) touched_faces = fetch_faces(touched_data);
153 if(touched_faces == []) touched_faces = [ALL_SIDES];
154
155 text += "Selected Faces: [";
156 if(llList2Integer(touched_faces, 0) == ALL_SIDES) text += "ALL_SIDES]\n";
157 else text += llDumpList2String(touched_faces, ", ") + "]\n";
158
159 text += format_color() + "\n";
160 text += format_alpha() + "\n\n";
161
162 text += "Prim options:";
163
164 llDialog(user_id, text, ["Pick Faces", "Pick Color", "Apply Color", "Main Menu"], com_channel);
165 }
166
167 face_menu() {
168 sub_menu = "face_menu";
169 string text = "";
170
171 if(touched_name != "") text += "Selection: " + touched_name + "\n";
172 else text += "Selection: [Unnamed Prim]\n";
173
174 text += "Selected Faces: [";
175 if(llList2Integer(touched_faces, 0) == ALL_SIDES) text += "ALL_SIDES]\n\n";
176 else text += llDumpList2String(touched_faces, ", ") + "]\n\n";
177
178 text += "Face options:";
179
180 list buttons = [];
181 integer i = 0;
182 for (i = 0; i < 9; i = -~i) {
183 if(llListFindList(touched_faces, [i]) >= 0) buttons += ["- " + (string)i];
184 else buttons += ["+ " + (string)i];
185 }
186 buttons += ["+ ALL_SIDES", "Back"];
187
188 llDialog(user_id, text, buttons, data_channel);
189 }
190
191 color_menu() {
192 sub_menu = "color_menu";
193 string text = "Color Picker\n";
194
195 text += format_color() + "\n";
196 text += format_alpha() + "\n\n";
197
198 text += "Color options:";
199
200 llDialog(user_id, text, ["Red", "Green", "Blue", "Alpha", "Back"], com_channel);
201 }
202
203 color_adjust() {
204 sub_menu = "adjust_menu";
205 string text = adjusting + " Adjustment\n";
206
207 text += format_color() + "\n";
208 text += format_alpha() + "\n\n";
209
210 text += "Adjustment options:";
211
212 string char = llGetSubString(adjusting, 0, 0);
213 list buttons = ["- 1" + char, "- 15" + char, "- 50" + char, "+ 1" + char, "+ 15" + char, "+ 50" + char, "0" + char];
214 if(char == "A") buttons += ["100A", "Back"];
215 else buttons += ["255" + char, "Back"];
216
217 llDialog(user_id, text, buttons, data_channel);
218 }
219
220 check_color() {
221 if(color.x < 0.0) color.x = 0.0;
222 else if(color.x > 1.0) color.x = 1.0;
223 if(color.y < 0.0) color.y = 0.0;
224 else if(color.y > 1.0) color.y = 1.0;
225 if(color.z < 0.0) color.z = 0.0;
226 else if(color.z > 1.0) color.z = 1.0;
227 if(alpha > 1.0) alpha = 1.0;
228 else if(alpha < 0.0) alpha = 0.0;
229 }
230
231 apply_color() {
232 if(last_menu == "prim_menu") {
233 integer length = (touched_faces != []);
234 integer i = 0;
235 for (i = 0; i < length; i = -~i) {
236 llSetLinkColor(touched_link, color, llList2Integer(touched_faces, i));
237 llSetLinkAlpha(touched_link, alpha, llList2Integer(touched_faces, i));
238 }
239 } else if(last_menu == "group_menu") {
241 integer i = 0;
242 if(auto == "Automatic") {
243 if(llListFindList(llCSV2List(fetch_group(llGetObjectDesc())), [group]) > -1) {
244 list fetch = fetch_faces(llGetObjectDesc());
245 integer length = (fetch != []);
246 for (i = 0; i < length; i = -~i) {
247 llSetLinkColor(LINK_ROOT, color, llList2Integer(fetch, i));
248 llSetLinkAlpha(LINK_ROOT, alpha, llList2Integer(fetch, i));
249 }
250 }
251 integer n = 0;
252 for (i = 2; i <= prims; i = -~i) {
253 string link = llGetLinkName(i);
254 if(llListFindList(llCSV2List(fetch_group(link)), [group]) > -1) {
255 list fetch = fetch_faces(link);
256 integer length = (fetch != []);
257 for (n = 0; n < length; n = -~n) {
258 llSetLinkColor(i, color, llList2Integer(fetch, n));
259 llSetLinkAlpha(i, alpha, llList2Integer(fetch, n));
260 }
261 }
262 }
263 } else if(auto == "ALL_SIDES") {
264 if(llListFindList(llCSV2List(fetch_group(llGetObjectDesc())), [group]) > -1) {
267 }
268 for (i = 2; i <= prims; i = -~i) {
269 string link = llGetLinkName(i);
270 if(llListFindList(llCSV2List(fetch_group(link)), [group]) > -1) {
271 llSetLinkColor(i, color, ALL_SIDES);
272 llSetLinkAlpha(i, alpha, ALL_SIDES);
273 }
274 }
275 }
276 } else if(last_menu == "object_menu") {
278 integer i = 0;
279 if(auto == "Automatic") {
280 list fetch = fetch_faces(llGetObjectDesc());
281 integer length = (fetch != []);
282 for (i = 0; i < length; i = -~i) {
283 llSetLinkColor(LINK_ROOT, color, llList2Integer(fetch, i));
284 llSetLinkAlpha(LINK_ROOT, alpha, llList2Integer(fetch, i));
285 }
286 integer n = 0;
287 for (i = 2; i <= prims; i = -~i) {
288 fetch = fetch_faces(llGetLinkName(i));
289 length = (fetch != []);
290 for (n = 0; n < length; n = -~n) {
291 llSetLinkColor(i, color, llList2Integer(fetch, n));
292 llSetLinkAlpha(i, alpha, llList2Integer(fetch, n));
293 }
294 }
295 } else if(auto == "ALL_SIDES") {
298 }
299 }
300 }
301
302 group_menu() {
303 last_menu = "group_menu";
304 string text = "";
305
306 if(group != "") text += "Selected Group: [" + group + "]\n";
307 text += "Selected Faces: [" + auto + "]\n";
308 text += format_color() + "\n";
309 text += format_alpha() + "\n\n";
310
311 text += "Group options:";
312
313 llDialog(user_id, text, ["Faces", "Pick Color", "Apply Color", "Pick Group", "Main Menu"], com_channel);
314 }
315
316 group_picker() {
317 sub_menu = "group_picker";
318 string text = "";
319
320 if(group != "") text += "Selected Group: [" + group + "]\n\n";
321
322 text += "Available groups:";
323
324 list buttons = ["Back"];
325 list groups = generate_groups();
326 if(groups != []) buttons += groups;
327
328 llDialog(user_id, text, buttons, data_channel);
329 }
330
331 object_menu() {
332 last_menu = "object_menu";
333 string text = "";
334
335 text += "Selected Faces: [" + auto + "]\n";
336
337 text += format_color() + "\n";
338 text += format_alpha() + "\n\n";
339
340 text += "Object options:";
341
342 llDialog(user_id, text, ["Faces", "Pick Color", "Apply Color", "Main Menu"], com_channel);
343 }
344
345 default
346 {
347 state_entry() {
349 }
350
351 link_message(integer sender, integer data, string msg, key id) {
352 //Opens the touch menu for agent <id>
353 if(msg == "COLOR_MENU_OPEN") {
354 plugin_use = TRUE;
355 user_id = id;
356 main_menu();
357 //Activates the touch menu trigger
358 } else if(msg == "COLOR_MENU_TOUCH_ON") {
359 touch_active = TRUE;
360 //Removes the touch menu trigger
361 } else if(msg == "COLOR_MENU_TOUCH_OFF") {
362 touch_active = FALSE;
363 //Sets the current color 255RGB scale ex: id = "50,100,150"
364 } else if(msg == "COLOR_MENU_COLOR") {
365 list args = llCSV2List(id);
366 color = <llList2Float(args, 0), llList2Float(args, 1), llList2Float(args, 2)> / 255.0;
367 //Sets the current alpha 100% scale ex: id = "40"
368 } else if(msg == "COLOR_MENU_ALPHA") {
369 alpha = (float)((string)id) / 100.0;
370 //Activates predefined prim faces to be painted on
371 } else if(msg == "COLOR_MENU_FACES_ON") {
372 auto = "Automatic";
373 //Disables predefined prim face painting - ALL_SIDES will be used
374 } else if(msg == "COLOR_MENU_FACES_OFF") {
375 auto = "ALL_SIDES";
376 //Paints on the specified prim group <id> ex: id = "Array 1"
377 //This is affected by predefined prim faces, if toggled on
378 } else if(msg == "COLOR_MENU_APPLY_GROUP") {
379 group = (string)id;
380 last_menu = "group_menu";
381 apply_color();
382 //Paints on all prims in the object
383 //This is affected by predefined prim faces, if toggles on
384 } else if(msg == "COLOR_MENU_APPLY_ALL") {
385 last_menu = "object_menu";
386 apply_color();
387 }
388 }
389
390 touch_start(integer number) {
391 if(touch_active) {
392 if(llDetectedKey(0) == llGetOwner()) {
393 plugin_use = FALSE;
394 if(llGetNumberOfPrims() > 1) {
395 touched_link = llDetectedLinkNumber(0);
396 touched_data = llGetLinkName(touched_link);
397 } else {
398 touched_link = 0;
399 touched_data = llGetObjectDesc();
400 }
401 user_id = llDetectedKey(0);
402 main_menu();
403 }
404 }
405 }
406
407 listen(integer channel, string name, key id, string msg) {
408 if(touch_active) llSetTimerEvent(touch_timeout);
409 if(channel == com_channel) {
410 if(msg == "This Prim") prim_menu();
411 else if(msg == "Set Prims") group_menu();
412 else if(msg == "All Prims") object_menu();
413 else if(msg == "Pick Faces") face_menu();
414 else if(msg == "Pick Color") color_menu();
415 else if(msg == "Apply Color") {
416 apply_color();
417 if(last_menu == "prim_menu") prim_menu();
418 else if(last_menu == "group_menu") group_menu();
419 else if(last_menu == "object_menu") object_menu();
420 } else if(msg == "Back") {
421 if(sub_menu == "adjust_menu") color_menu();
422 else if(last_menu == "prim_menu") prim_menu();
423 else if(last_menu == "group_menu") group_menu();
424 else if(last_menu == "object_menu") object_menu();
425 } else if(msg == "Pick Group") {
426 group_picker();
427 } else if(msg == "Main Menu") {
428 main_menu();
429 } else if(msg == "Red" || msg == "Green" || msg == "Blue" || msg == "Alpha") {
430 adjusting = msg;
431 color_adjust();
432 } else if(msg == "Faces") {
433 if(auto == "Automatic") auto = "ALL_SIDES";
434 else if(auto == "ALL_SIDES") auto = "Automatic";
435 if(last_menu == "object_menu") object_menu();
436 else if(last_menu == "group_menu") group_menu();
437 } else if(msg == "Done") {
438 llMessageLinked(LINK_SET, 0, "COLOR_MENU_DONE", "");
439 }
440 }
441 if(channel == data_channel) {
442 if(msg == "Back") {
443 if(sub_menu == "adjust_menu") color_menu();
444 else if(last_menu == "prim_menu") prim_menu();
445 else if(last_menu == "group_menu") group_menu();
446 else if(last_menu == "object_menu") object_menu();
447 } else if(sub_menu == "face_menu") {
448 if(msg == "+ ALL_SIDES") touched_faces = [ALL_SIDES];
449 else if(llList2Integer(touched_faces, 0) == ALL_SIDES) touched_faces = [(integer)llGetSubString(msg, 2, 2)];
450 else if(llGetSubString(msg, 0, 0) == "+") touched_faces += [(integer)llGetSubString(msg, 2, 2)];
451 else if(llGetSubString(msg, 0, 0) == "-") {
452 integer index = llListFindList(touched_faces, [(integer)llGetSubString(msg, 2, 2)]);
453 touched_faces = llDeleteSubList(touched_faces, index, index);
454 }
455 face_menu();
456 } else if(sub_menu == "adjust_menu") {
457 float amount = 0.0;
458 string lead = llGetSubString(msg, 0, 0);
459 if(lead == "0") amount = -255.0;
460 else if(lead == "1" || lead == "2") amount = 255.0;
461 else {
462 amount = (float)(llGetSubString(msg, 2, llStringLength(msg) - 2));
463 if(lead == "-") amount = -amount;
464 }
465 string tail = llGetSubString(msg, -1, -1);
466 if(tail == "R") color.x += (amount / 255.0);
467 else if(tail == "G") color.y += (amount / 255.0);
468 else if(tail == "B") color.z += (amount / 255.0);
469 else if(tail == "A") alpha += (amount / 100.0);
470 check_color();
471 color_adjust();
472 } else if(sub_menu == "group_picker") {
473 group = msg;
474 group_picker();
475 }
476 }
477 }
478
479 timer() {
480 llListenRemove(listener);
481 llListenRemove(data_listen);
482 llSetTimerEvent(0.0);
483 }
484 } // END //

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