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
Building Pipe_maker  

Pipe_maker

Pipemaker helps you easily create continuous lengths of pipe using cylinders and torus segments. The simple dialog-driven interface always lines pieces up perfectly to give you one long continuous pipe.
It's useful for creating industrial complicated pipe messes, weird curlicues, and, of course, for writing your name in prims in the air.

Retrieved from from Free SL Scripts on http://www.freeSLscripts.com or www.freeslscripts.gendersquare.org

Category: Building
By : Lex Neva
Created: 2010-01-10 Edited: 2010-01-10
Worlds: Second Life

the Zip file

Download all files for Pipe_maker
Contents are in zip format, with .LSL (text) source code and LSLEdit (text + Solution) formats.
Get file # 1. Pipe_maker_1.lsl
1 // PipeMaker by Lex Neva
2 //
3 // This script is released under the GNU Public License (http://www.gnu.org for a copy). In short, this means you may copy,
4 // redistribute, and modify this script to your heart's content, so long as my name stays in it and your new version is also
5 // freely redistributable. For more details, read the full license. If you really must provide me with some kind of compensation
6 // for my work, feel free to heap praises upon me in the forums, rate me, and/or send me lindens. You can also check out my
7 // store in Eldora.
8 //
9
10
11 // Okay, now that's out of the way. Here's how to use this thing.
12 //
13 // If you've managed to pick up a copy of this script in the wild, you'll have to build the object. Fortunately, that's easy.
14 //
15 // 1. Build a default cylinder, name it PipeMaker (the name's important)
16 // 2. Place this script in the PipeMaker cylinder.
17 // 3. Take a copy. (leave one rezzed)
18 // 4. Find the copy in your inventory, and place it in the rezzed one.
19 // 5. Take the whole mess into your inventory.
20 // 6. Rez a copy and get started!
21 //
22 // The above process is necessary because the pipemaker uses a safe form of self-replication.
23 //
24 // Now, how to actually make pipes.
25 //
26 // You should be able to just rez the PipeMaker object and go to it. A dialog will pop up, and a new pipe piece will stick itself
27 // onto the end of the first one. This new piece (the red one) is the one you're currently working on. Poke a few buttons.
28 // Commands like "length+" will make the length of a straight piece longer. The more pluses, the longer it'll get. Minuses will
29 // shrink it instead.
30 //
31 // Click the "curve" button if you want to turn a corner instead. The radius commands will change how sharp the curve is: bigger
32 // radius means a more gradual curve. The arc commands will determine how much of a circle the curved piece uses. 90 means to
33 // turn a right angle, 180 means to do a "U" bend, etc. 360 probably won't be useful, but the option IS there. Tilt will
34 // make the curved piece rotate up or down. Just play with it, you'll get it.
35 //
36 // There are only so many buttons allowable in a script dialog, so I wasn't able to include all of the commands I wanted to. You
37 // can still do things like "radius+++" if the radius+ button isn't going fast enough: just type /1 radius+++. You can use up to
38 // three pluses or minuses.
39 //
40 // When you're done, just delete the extra red piece. I didn't have enough room for a "finish" button.
41 //
42 // If you want to have a hollow pipe, rez the first PipeMaker, and change its hollow value. Tweak the length so that the red
43 // pipe updates. From then on, the hollow will carry through. You could, if you want, change the hollow at any time, and
44 // the setting will carry on to pieces after that one. If you want to change the thickness of the pipe, just change the
45 // X and Y size of the starting cylinder. I recommend that the X and Y settings should be the same. I was too lazy to make
46 // it work with oval pipes. You can change the size any time, but I don't recommend messing with curved pieces, because getting
47 // everything to match up nicely is difficult.
48 //
49 // The rest is for advanced users. You can skip this stuff.
50 //
51 // Why isn't there finer control for arc and tilt? Why does radius change in such weird increments?
52 //
53 // The simple answer is that the object properties this script uses, such as hole size and cut, only allow two decimal places of
54 // precision. If I let you use any arc value, SL will "round" to the nearest 18 or so degrees, and that'll mean the next pipe
55 // doesn't join on perfectly. Radius is even more complicated. You can set the radius of a torus to a fairly fine degree of
56 // precision, but the real limiting factor is the hole size. If the hole size that would be needed for a certain radius
57 // of curve doesn't line up on an even 0.01, the pipe's cross-section won't match up. When you use the radius+ and radius-
58 // buttons, I actually decrement and increment the hole size, and figure out the torus's radius from that, which guarantees that
59 // everything lines up beautifully. Incidentally, I also change the tilt value in increments of 15 degrees, because that way
60 // the vertices of the cylinders and tori always line up nicely.
61 //
62 // That said, you can override these limits manually if you really want to. I figure if you want to do this, you probably have
63 // a good reason. Just utter these commands on channel 1 (by prefixing them with "/1"):
64 //
65 // radius 2.5
66 // tilt 35.0
67 // arc 90.0
68 // length 5.0
69 // radius+++
70 // (any other command on the buttons)
71 // reset (use only if the red prim fails to rez or is accidentally deleted)
72 //
73 // Just be careful, especially with radius. If you don't watch it, you can find that things aren't lining up nicely... it's just
74 // due to the limits of primitive properties. The dialog optiosn should give you a fair degree of freedom.
75 //
76
77
78 float torus_radius;
79 float torus_rot;
80 float torus_arc;
81
82 float cylinder_length;
83
84 integer type;
85 integer channel;
86
87 integer listenHandle;
88
89 vector offsetRot(vector initial_position, vector center_position, rotation rot_amount)
90 {
91
92 vector offset = initial_position - center_position;
93
94 vector final_position;
95
96 //The following line calculates the new coordinates based on
97 //the rotation & offset
98 final_position = offset * rot_amount;
99
100 //Since the rotation is calculated in terms of our offset, we need to add
101 //our original center_position back in - to get the final coordinates.
102 final_position += center_position;
103
104 return final_position;
105 }
106
107 makeTorus() {
108 //llSay(0,"Making torus part with radius " + (string)torus_radius + " rotation " + (string)torus_rot + " arc " + (string)torus_arc);
109
110 vector myScale = llGetScale();
111 rotation torus_rotation;
112 vector torus_position;
113 vector torus_scale;
114 vector torus_cut;
115 vector torus_hole_size;
117 float hollow = llList2Float(params,3);
118
119 if(llList2Integer(params,0) == PRIM_TYPE_CYLINDER) {
120
121 torus_rotation = llGetRot();
122 torus_position = llGetPos() + llRot2Up(torus_rotation) * myScale.z * 0.5 - llRot2Left(torus_rotation) * (torus_radius - myScale.x/2.0);
123
124 vector face_center = llGetPos() + llRot2Up(torus_rotation) * myScale.z * 0.5;
125 rotation rot = llAxisAngle2Rot(llRot2Up(torus_rotation), DEG_TO_RAD * torus_rot);
126
127 torus_position = offsetRot(torus_position, face_center, rot);
128 torus_rotation = torus_rotation * rot;
129 torus_scale = <myScale.x, torus_radius*2.0, torus_radius*2.0>;
130 torus_hole_size = <1.0,myScale.y/(2*torus_radius),0.0>;
131 } else {
132
133 vector cut = llList2Vector(params,2);
134 vector hole_size = llList2Vector(params,5);
135 float d = hole_size.y * myScale.y;
136
137 torus_rotation = llGetRot();
138 torus_position = llGetPos();
139
140 torus_rotation *= llAxisAngle2Rot(llRot2Fwd(torus_rotation),cut.y*TWO_PI);
141 torus_position += llRot2Left(torus_rotation) * (myScale.z/2.0 - torus_radius);
142
143 vector face_center = torus_position + llRot2Left(torus_rotation) * (torus_radius - d/2.0);
144 rotation rot = llAxisAngle2Rot(llRot2Up(torus_rotation), DEG_TO_RAD * torus_rot);
145
146 torus_position = offsetRot(torus_position, face_center, rot);
147 torus_rotation = torus_rotation * rot;
148
149 torus_scale = <d, torus_radius*2.0, torus_radius*2.0>;
150 torus_hole_size = <1.0,d/(2*torus_radius),0.0>;
151 }
152
153
154 torus_cut = <0.0, torus_arc/360.0, 0.0>;
155
156
157 llSay(channel,"TORUS," + (string)torus_position + "," + (string)torus_rotation + "," + (string)torus_scale + "," + (string)torus_cut + "," + (string)hollow + "," + (string)torus_hole_size);
158 }
159
160 makeCylinder() {
161 //llSay(0,"Making cylinder with length " + (string)cylinder_length);
162
163 vector myScale = llGetScale();
164 rotation cylinder_rotation;
165 vector cylinder_position;
166 vector cylinder_scale;
167 float d;
169 float hollow = llList2Float(params,3);
170
171 if(llList2Integer(params,0) == PRIM_TYPE_TORUS) {
172
173 vector cut = llList2Vector(params,2);
174 vector hole_size = llList2Vector(params,5);
175 d = hole_size.y * myScale.y;
176
177 cylinder_rotation = llGetRot();
178 rotation rot = llAxisAngle2Rot(llRot2Fwd(cylinder_rotation),cut.y *TWO_PI);
179
180 cylinder_rotation *= rot;
181
182 cylinder_position = llRot2Left(llGetRot()) * ((myScale.y - d)/2.0);
183 cylinder_position *= rot;
184 cylinder_position += llGetPos();
185 cylinder_position += llRot2Up(cylinder_rotation) * (cylinder_length/2.0);
186 } else {
187 d = myScale.y;
188 cylinder_position = llGetPos();
189 cylinder_rotation = llGetRot();
190 cylinder_position += llRot2Up(cylinder_rotation) * ((myScale.z + cylinder_length)/2.0);
191 }
192
193 cylinder_scale = <d,d,cylinder_length>;
194
195 llSay(channel,"CYLINDER," + (string)cylinder_position + "," + (string)cylinder_rotation + "," + (string)cylinder_scale + "," + (string)hollow);
196 }
197
198 update() {
199 if(type == PRIM_TYPE_CYLINDER)
200 makeCylinder();
201 else
202 makeTorus();
203 }
204
205 rezNext() {
206 channel = 10000 + llFloor(llFrand(1000000));
207
208 //llOwnerSay("Channel = " + (string)channel);
209
210 llRezObject("PipeMaker",llGetPos(), ZERO_VECTOR, ZERO_ROTATION, channel);
211 llSleep(1.0);
212 }
213
214 sendDialog() {
215
216 if(type == PRIM_TYPE_CYLINDER) {
217 llDialog(llGetOwner(),"Straight piece\n\nlength = " + (string)cylinder_length + " meters",["length+","length++","length+++","length-","length--","length---","curve","next"],1);
218 } else {
219 llDialog(llGetOwner(),"Curve piece\n\nradius = " + (string)torus_radius + " meters\narc = " + (string)torus_arc + " degrees\ntilt = " + (string)torus_rot + " degrees",["tilt+","tilt++","next","tilt-","tilt--","straight","radius+","arc+","arc++","radius-","arc-","arc--"],1);
220 }
221 }
222
223
224 float getDiameter() {
225 vector scale = llGetScale();
226 return scale.x;
227 }
228
229 init() {
230 float d = getDiameter();
231
232 if(d > 2.5) {
233 torus_radius = d;
234 } else {
235 torus_radius = d*2.0;
236 }
237
238 torus_rot = 0.0;
239 torus_arc = 90.0;
240 cylinder_length = 1.0;
241 type=PRIM_TYPE_CYLINDER;
242 }
243
244 default
245 {
246 on_rez(integer param) {
247 if(param) {
248 llListen(param,"","","");
249 llSetColor(<1.0,0.0,0.0>,ALL_SIDES);
250 } else {
251 llSetColor(<1,1,1>,ALL_SIDES);
252 state configure;
253 }
254 }
255
256 listen(integer c, string name, key id, string message) {
257 list params = llCSV2List(message);
258 list primParams;
259 if(llList2String(params,0) == "TORUS") {
260 primParams = [PRIM_POSITION, (vector)llList2String(params,1),
262 PRIM_SIZE, (vector)llList2String(params,3),
264 PRIM_TYPE_TORUS, // type
265 PRIM_HOLE_DEFAULT, // hole type
266 (vector)llList2String(params,4), // cut
267 (float)llList2String(params,5), // hollow
268 <0.0,0.0,0.0>, // twist
269 (vector)llList2String(params,6), // hole size
270 <0.0,0.0,0.0>, // top shear
271 <0.0,1.0,0.0>, // advanced cut
272 <0.0,0.0,0.0>, // taper
273 1.0, // revolutions
274 0.0, // radius offset
275 0.0 // skew
276 ];
277 } else if(llList2String(params,0) == "CYLINDER") {
278 primParams = [PRIM_POSITION, (vector)llList2String(params,1),
280 PRIM_SIZE, (vector)llList2String(params,3),
282 PRIM_TYPE_CYLINDER, // type
283 PRIM_HOLE_DEFAULT, // hole type
284 <0.0,1.0,0.0>, // cut
285 (float)llList2String(params,4), // hollow
286 <0.0,0.0,0.0>, // twist
287 <1.0, 1.0, 0.0>, // top size
288 <0.0,0.0,0.0> // top shear
289 ];
290 } else if(llList2String(params,0) == "DONE") {
291 llSetColor(<1.0,1.0,1.0>,ALL_SIDES);
292 state configure;
293 }
294
295 llSetPrimitiveParams(primParams);
296
297 }
298 }
299
300 state configure {
301 state_entry() {
302 listenHandle = llListen(1,"",llGetOwner(),"");
303
304 init();
305
306 sendDialog();
307 rezNext();
308 update();
309 }
310
311 on_rez(integer param) {
312 llListenRemove(listenHandle);
313 listenHandle = llListen(1,"",llGetOwner(),"");
314 llSetColor(<1,1,1>,ALL_SIDES);
315
316 init();
317
318 sendDialog();
319 rezNext();
320 update();
321 }
322
323 changed(integer change) {
324 if(change & CHANGED_SHAPE) {
325 // hollow
326 update();
327 } else if(change & CHANGED_SCALE) {
328 float d = getDiameter();
329
330 // must make sure the hole size will be nice and prim size will be under 10.0
331 if(d > 2.5)
332 torus_radius = d;
333 else
334 torus_radius = d * 2.0;
335 update();
336 }
337 }
338
339 moving_end() {
340 update();
341 }
342
343 listen(integer c, string name, key id, string message) {
344 list parts = llParseString2List(message,[" "],[]);
345 string command = llList2String(parts,0);
346
347 // start with chat-only commands, don't resend dialog (it gets spammy)
348 if(command == "radius") {
349 torus_radius = (float)llList2String(parts,1);
350 } else if(command == "rot" || command == "tilt") {
351 torus_rot = (float)llList2String(parts,1);
352 } else if(command == "arc") {
353 torus_arc = (float)llList2String(parts,1);
354 } else if(command == "length") {
355 cylinder_length = (float)llList2String(parts,1);
356 } else if(command == "done" || command == "next") {
357 llSay(channel,"DONE");
358
359 // now commit suicide
361 state default; // and just in case, stop doing anything until the script's removed.
362 } else {
363 // dialog-driven commands follow, this big else block is so I can send a dialog only for dialog commands
364
365 if(command == "curve") {
366 type = PRIM_TYPE_TORUS;
367 } else if(command == "straight") {
368 type = PRIM_TYPE_CYLINDER;
369 } else if(llGetSubString(command,0,5) == "length") {
370 integer strength = llStringLength(command) - 6;
371 float change = llList2Float([0.1,0.5,1.0],strength - 1);
372
373 if(llGetSubString(command,6,6) == "-")
374 change *= -1;
375
376 cylinder_length += change;
377
378 if(cylinder_length < 0.01)
379 cylinder_length = 0.01;
380 if(cylinder_length > 10.0)
381 cylinder_length = 10.0;
382 } else if(llGetSubString(command,0,5) == "radius") {
383 integer strength = llStringLength(command) - 6;
384 float change = llList2Float([0.01,0.05,0.1], strength - 1);
385
386 if(llGetSubString(command,6,6) == "+")
387 change *= -1;
388
389 float d = getDiameter();
390 float hole_size = d/(torus_radius * 2.0);
391
392 hole_size += change;
393
394 if(hole_size < 0.05) {
395 //llOwnerSay("clamped to 0.05");
396 hole_size = 0.05;
397 } if(hole_size > 0.5) {
398 //llOwnerSay("clamped to 0.5");
399 hole_size = 0.5;
400 }
401
402 float new_radius = d/(hole_size * 2.0);
403
404 if(new_radius <= 5.0) {
405 torus_radius = new_radius;
406 }
407 } else if(llGetSubString(command,0,2) == "arc") {
408 integer strength = llStringLength(command) - 3;
409 float change = llList2Float([0.05,0.1,0.2], strength - 1);
410
411 if(llGetSubString(command,3,3) == "-")
412 change *= -1;
413
414
415 float cut = torus_arc / 360.0;
416
417 cut += change;
418
419 if(cut > 1.0)
420 cut = 1.0;
421 if(cut < 0.05)
422 cut = 0.05;
423
424 torus_arc = cut * 360.0;
425 } else if(llGetSubString(command,0,3) == "tilt") {
426 integer strength = llStringLength(command) - 4;
427 float change = llList2Float([15.0,45.0,90.0], strength - 1);
428
429 if(llGetSubString(command,4,4) == "-")
430 change *= -1;
431
432
433 torus_rot += change; // boundaries wrap
434 } else if(command == "reset") {
435 init();
436 rezNext();
437 } else {
438 return; // invalid command
439 }
440
441 sendDialog();
442 }
443
444 // in any case, if we get here, it's time to update the next segment's properties
445 update();
446 }
447
448 touch_start(integer num) {
449 sendDialog();
450 }
451
452 object_rez(key id) {
453 llGiveInventory(id, "PipeMaker");
454 }
455 }

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