Change font size
It is currently Sun Jul 22, 2018 3:25 pm

Forum rules


{L_IMAGE}



Post a new topicPost a reply Page 1 of 1   [ 1 post ]
Author Message
 Post subject: Pipe maker script
PostPosted: Sat Sep 17, 2011 4:01 am 
OSG Elite

Joined: Wed Aug 05, 2009 1:59 am
Posts: 417
The PipeMaker lets you create long, continuous lines of piping using cylinders and torus pieces that line up perfectly, end to end. You can continue for as long as you want, and you can adjust several parameters of the pipes. This version lets you change the length of straight segments, and the radius, arc, and tilt of curved segments, which should be enough to create some really nifty industrial pipework sculptures in a flash.

I have found this script somewhere on the net, I am not the creator. I have tested in-world, and it works.
You can pick up a working copy in my freebie shop here: https://util.osgrid.org/region/The%20Gu ... /108/90/22
Have fun with it,
Odd

{L_CODE}:
// PipeMaker by Lex Neva
//
// 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.
//
// This script is released under the GNU Public License (http://www.gnu.org for a copy).  In short, this means you may copy,
// redistribute, and modify this script to your heart's content, so long as my name stays in it and your new version is also
// freely redistributable.  For more details, read the full license.  If you really must provide me with some kind of compensation
// 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
// store in Eldora.
//
// Okay, now that's out of the way.  Here's how to use this thing.
//
// 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.
//
// 1. Build a default cylinder, name it PipeMaker (the name's important)
// 2. Place this script in the PipeMaker cylinder.
// 3. Take a copy.  (leave one rezzed)
// 4. Find the copy in your inventory, and place it in the rezzed one.
// 5. Take the whole mess into your inventory.
// 6. Rez a copy and get started!
//
// The above process is necessary because the pipemaker uses a safe form of self-replication.
//
// Now, how to actually make pipes.
//
// 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
// 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. 
// Commands like "length+" will make the length of a straight piece longer.  The more pluses, the longer it'll get.  Minuses will
// shrink it instead.
//
// Click the "curve" button if you want to turn a corner instead.  The radius commands will change how sharp the curve is: bigger
// radius means a more gradual curve.  The arc commands will determine how much of a circle the curved piece uses.  90 means to
// 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
// make the curved piece rotate up or down.  Just play with it, you'll get it.
//
// 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
// can still do things like "radius+++" if the radius+ button isn't going fast enough: just type /1 radius+++.  You can use up to
// three pluses or minuses.
//
// When you're done, just delete the extra red piece.  I didn't have enough room for a "finish" button.
//
// If you want to have a hollow pipe, rez the first PipeMaker, and change its hollow value.  Tweak the length so that the red
// pipe updates.  From then on, the hollow will carry through.  You could, if you want, change the hollow at any time, and
// the setting will carry on to pieces after that one.  If you want to change the thickness of the pipe, just change the
// 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
// it work with oval pipes.  You can change the size any time, but I don't recommend messing with curved pieces, because getting
// everything to match up nicely is difficult.
//
// The rest is for advanced users.  You can skip this stuff.
//
// Why isn't there finer control for arc and tilt?  Why does radius change in such weird increments?
//
// The simple answer is that the object properties this script uses, such as hole size and cut, only allow two decimal places of
// 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
// doesn't join on perfectly.  Radius is even more complicated.  You can set the radius of a torus to a fairly fine degree of
// precision, but the real limiting factor is the hole size.  If the hole size that would be needed for a certain radius
// 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-
// buttons, I actually decrement and increment the hole size, and figure out the torus's radius from that, which guarantees that
// everything lines up beautifully.  Incidentally, I also change the tilt value in increments of 15 degrees, because that way
// the vertices of the cylinders and tori always line up nicely.
//
// That said, you can override these limits manually if you really want to.  I figure if you want to do this, you probably have
// a good reason.  Just utter these commands on channel 1 (by prefixing them with "/1"):
//
// radius 2.5
// tilt 35.0
// arc 90.0
// length 5.0
// radius+++
// (any other command on the buttons)
// reset (use only if the red prim fails to rez or is accidentally deleted)
//
// 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
// due to the limits of primitive properties.  The dialog optiosn should give you a fair degree of freedom.
//


float torus_radius;
float torus_rot;
float torus_arc;

float cylinder_length;

integer type;
integer channel;

integer listenHandle;

vector offsetRot(vector initial_position, vector center_position, rotation rot_amount)
{
   
    vector offset = initial_position - center_position;
       
    vector final_position;
                   
    //The following line calculates the new coordinates based on
    //the rotation & offset
    final_position = offset * rot_amount;
   
    //Since the rotation is calculated in terms of our offset, we need to add
    //our original center_position back in - to get the final coordinates.
    final_position += center_position;
   
    return final_position;
}

makeTorus() {
    //llSay(0,"Making torus part with radius " + (string)torus_radius + " rotation " + (string)torus_rot + " arc " + (string)torus_arc);
   
    vector myScale = llGetScale();
    rotation torus_rotation;
    vector torus_position;
    vector torus_scale;
    vector torus_cut;
    vector torus_hole_size;
    list params = llGetPrimitiveParams([PRIM_TYPE]);
    float hollow = llList2Float(params,3);

    if (llList2Integer(params,0) == PRIM_TYPE_CYLINDER) {
   
        torus_rotation = llGetRot();
        torus_position = llGetPos() + llRot2Up(torus_rotation) * myScale.z * 0.5 - llRot2Left(torus_rotation) * (torus_radius - myScale.x/2.0);
       
        vector face_center = llGetPos() + llRot2Up(torus_rotation) * myScale.z * 0.5;
        rotation rot = llAxisAngle2Rot(llRot2Up(torus_rotation), DEG_TO_RAD * torus_rot);
       
        torus_position = offsetRot(torus_position, face_center, rot);
        torus_rotation = torus_rotation * rot;
        torus_scale = <myScale.x, torus_radius*2.0, torus_radius*2.0>;
        torus_hole_size = <1.0,myScale.y/(2*torus_radius),0.0>;       
    } else {

        vector cut = llList2Vector(params,2);
        vector hole_size = llList2Vector(params,5);
        float d = hole_size.y * myScale.y;
       
        torus_rotation = llGetRot();
        torus_position = llGetPos();
       
        torus_rotation *= llAxisAngle2Rot(llRot2Fwd(torus_rotation),cut.y*TWO_PI);
        torus_position += llRot2Left(torus_rotation) * (myScale.z/2.0 - torus_radius);
       
        vector face_center = torus_position + llRot2Left(torus_rotation) * (torus_radius - d/2.0);
        rotation rot = llAxisAngle2Rot(llRot2Up(torus_rotation), DEG_TO_RAD * torus_rot);
       
        torus_position = offsetRot(torus_position, face_center, rot);
        torus_rotation = torus_rotation * rot;
         
        torus_scale = <d, torus_radius*2.0, torus_radius*2.0>;
        torus_hole_size = <1.0,d/(2*torus_radius),0.0>;             
    }
       

    torus_cut = <0.0, torus_arc/360.0, 0.0>;
   

    llSay(channel,"TORUS," + (string)torus_position + "," + (string)torus_rotation + "," + (string)torus_scale + "," + (string)torus_cut + "," + (string)hollow + "," + (string)torus_hole_size);
}

makeCylinder() {
    //llSay(0,"Making cylinder with length " + (string)cylinder_length);

    vector myScale = llGetScale();
    rotation cylinder_rotation;
    vector cylinder_position;
    vector cylinder_scale;
    float d;
    list params = llGetPrimitiveParams([PRIM_TYPE]);
    float hollow = llList2Float(params,3);

    if (llList2Integer(params,0) == PRIM_TYPE_TORUS) {

        vector cut = llList2Vector(params,2);
        vector hole_size = llList2Vector(params,5);
        d = hole_size.y * myScale.y;   
       
        cylinder_rotation = llGetRot();
        rotation rot = llAxisAngle2Rot(llRot2Fwd(cylinder_rotation),cut.y*TWO_PI);
       
        cylinder_rotation *= rot;
       
        cylinder_position = llRot2Left(llGetRot()) * ((myScale.y - d)/2.0);
        cylinder_position *= rot;
        cylinder_position += llGetPos();
        cylinder_position += llRot2Up(cylinder_rotation) * (cylinder_length/2.0);
    } else {
        d = myScale.y;
        cylinder_position = llGetPos();
        cylinder_rotation = llGetRot();
        cylinder_position += llRot2Up(cylinder_rotation) * ((myScale.z + cylinder_length)/2.0);
    }
   
    cylinder_scale = <d,d,cylinder_length>;
       
    llSay(channel,"CYLINDER," + (string)cylinder_position + "," + (string)cylinder_rotation + "," + (string)cylinder_scale + "," + (string)hollow);
}

update() {
    if (type == PRIM_TYPE_CYLINDER)
        makeCylinder();
    else   
        makeTorus();
}

rezNext() {
    channel = 10000 + llFloor(llFrand(1000000));   

    //llOwnerSay("Channel = " + (string)channel);
   
    llRezObject("PipeMaker",llGetPos(), ZERO_VECTOR, ZERO_ROTATION, channel);
    llSleep(1.0);
}

sendDialog() {
   
    if (type == PRIM_TYPE_CYLINDER) {
        llDialog(llGetOwner(),"Straight piece\n\nlength = " + (string)cylinder_length + " meters",["length+","length++","length+++","length-","length--","length---","curve","next"],1);
    } else {
        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);
    }
}


float getDiameter() {
    vector scale = llGetScale();
    return scale.x;
}

init() {
    float d = getDiameter();
   
    if (d > 2.5) {
        torus_radius = d;
    } else {
        torus_radius = d*2.0;
    }
   
    torus_rot = 0.0;
    torus_arc = 90.0;
    cylinder_length = 1.0;
    type=PRIM_TYPE_CYLINDER;
}   
       
default
{   
    on_rez(integer param) {
        if (param) {
            llListen(param,"","","");
            llSetColor(<1.0,0.0,0.0>,ALL_SIDES);
        } else {
            llSetColor(<1,1,1>,ALL_SIDES);           
            state configure;
        }
    }
           
    listen(integer c, string name, key id, string message) {
        list params = llCSV2List(message);
        list primParams;
        if (llList2String(params,0) == "TORUS") {
            primParams =           [PRIM_POSITION, (vector)llList2String(params,1),
                                    PRIM_ROTATION, (rotation)llList2String(params,2),
                                    PRIM_SIZE, (vector)llList2String(params,3),
                                    PRIM_TYPE,
                                    PRIM_TYPE_TORUS,                    // type
                                    PRIM_HOLE_DEFAULT,                  // hole type
                                    (vector)llList2String(params,4),    // cut
                                    (float)llList2String(params,5),   // hollow
                                    <0.0,0.0,0.0>,                      // twist
                                    (vector)llList2String(params,6),    // hole size
                                    <0.0,0.0,0.0>,                      // top shear
                                    <0.0,1.0,0.0>,                      // advanced cut
                                    <0.0,0.0,0.0>,                      // taper
                                    1.0,                                // revolutions
                                    0.0,                                // radius offset
                                    0.0                                 // skew
                                   ];
        } else if (llList2String(params,0) == "CYLINDER") {
            primParams =           [PRIM_POSITION, (vector)llList2String(params,1),
                                    PRIM_ROTATION, (rotation)llList2String(params,2),
                                    PRIM_SIZE, (vector)llList2String(params,3),
                                    PRIM_TYPE,
                                    PRIM_TYPE_CYLINDER,                 // type
                                    PRIM_HOLE_DEFAULT,                  // hole type
                                    <0.0,1.0,0.0>,                      // cut
                                    (float)llList2String(params,4),   // hollow
                                    <0.0,0.0,0.0>,                      // twist
                                    <1.0, 1.0, 0.0>,                    // top size
                                    <0.0,0.0,0.0>                       // top shear
                                   ];
        } else if (llList2String(params,0) == "DONE") {
            llSetColor(<1.0,1.0,1.0>,ALL_SIDES);
            state configure;
        }
       
        llSetPrimitiveParams(primParams);
                                   
    }           
}

state configure {
    state_entry() {
        listenHandle = llListen(1,"",llGetOwner(),"");
       
        init();
       
        sendDialog();               
        rezNext();
        update();
    }
   
    on_rez(integer param) {
        llListenRemove(listenHandle);
        listenHandle = llListen(1,"",llGetOwner(),"");       
        llSetColor(<1,1,1>,ALL_SIDES);
       
        init();
       
        sendDialog();       
        rezNext();
        update();
    }       
   
    changed(integer change) {
        if (change & CHANGED_SHAPE) {
            // hollow
            update();
        } else if (change & CHANGED_SCALE) {
            float d = getDiameter();
           
            // must make sure the hole size will be nice and prim size will be under 10.0
            if (d > 2.5)
                torus_radius = d;
            else
                torus_radius = d * 2.0;
            update();
        }
    }
   
    moving_end() {
        update();
    }
   
    listen(integer c, string name, key id, string message) {
        list parts = llParseString2List(message,[" "],[]);
        string command = llList2String(parts,0);
       
        // start with chat-only commands, don't resend dialog (it gets spammy)
        if (command == "radius") {
            torus_radius = (float)llList2String(parts,1);
        } else if (command == "rot" || command == "tilt") {
            torus_rot = (float)llList2String(parts,1);
        } else if (command == "arc") {
            torus_arc = (float)llList2String(parts,1);
        } else if (command == "length") {
            cylinder_length = (float)llList2String(parts,1);
        } else if (command == "done" || command == "next") {
            llSay(channel,"DONE");
           
            // now commit suicide
            llRemoveInventory(llGetScriptName());
            state default; // and just in case, stop doing anything until the script's removed.
        } else {
            // dialog-driven commands follow, this big else block is so I can send a dialog only for dialog commands
       
            if (command == "curve") {
                type = PRIM_TYPE_TORUS;
            } else if (command == "straight") {
                type = PRIM_TYPE_CYLINDER;
            } else if (llGetSubString(command,0,5) == "length") {
                integer strength = llStringLength(command) - 6;
                float change = llList2Float([0.1,0.5,1.0],strength - 1);
               
                if (llGetSubString(command,6,6) == "-")
                    change *= -1;
               
                cylinder_length += change;
               
                if (cylinder_length < 0.01)
                    cylinder_length = 0.01;
                if (cylinder_length > 10.0)
                    cylinder_length = 10.0;
            } else if (llGetSubString(command,0,5) == "radius") {
                integer strength = llStringLength(command) - 6;
                float change = llList2Float([0.01,0.05,0.1], strength - 1);
               
                if (llGetSubString(command,6,6) == "+")
                    change *= -1;
               
                float d = getDiameter();
                float hole_size = d/(torus_radius * 2.0);
               
                hole_size += change;
                 
                if (hole_size < 0.05) {
                    //llOwnerSay("clamped to 0.05");
                    hole_size = 0.05;
                } if (hole_size > 0.5) {
                    //llOwnerSay("clamped to 0.5");
                    hole_size = 0.5;
                }
               
                float new_radius = d/(hole_size * 2.0);
               
                if (new_radius <= 5.0) {
                    torus_radius = new_radius;
                }
            } else if (llGetSubString(command,0,2) == "arc") {
                integer strength = llStringLength(command) - 3;
                float change = llList2Float([0.05,0.1,0.2], strength - 1);
               
                if (llGetSubString(command,3,3) == "-")
                    change *= -1;
               
               
                float cut = torus_arc / 360.0;
               
                cut += change;
               
                if (cut > 1.0)
                    cut = 1.0;
                if (cut < 0.05)
                    cut = 0.05;
                   
                torus_arc = cut * 360.0;
            } else if (llGetSubString(command,0,3) == "tilt") {
                integer strength = llStringLength(command) - 4;
                float change = llList2Float([15.0,45.0,90.0], strength - 1);
               
                if (llGetSubString(command,4,4) == "-")
                    change *= -1;
               
               
                torus_rot += change; // boundaries wrap
            } else if (command == "reset") {
                init();
                rezNext();
            } else {
                return; // invalid command
            }
           
            sendDialog();
        }
       
        // in any case, if we get here, it's time to update the next segment's properties
        update();
    }
   
    touch_start(integer num) {
        sendDialog();
    }
   
    object_rez(key id) {
        llGiveInventory(id, "PipeMaker");
    }
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Post a new topicPost a reply Page 1 of 1   [ 1 post ]


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
610nm Style by Daniel St. Jules of Gamexe.net