Don't click here unless you want to be banned.

LSL Wiki : LibraryPrimTorture

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawl338.us.archive.org

Prim Torture


Q: What is prim torture?
A: Prim torture is the art of using shape changes to produce shapes that are otherwise impossible.

Q: How does prim torture work?
A: All prims share the same attributes, even if the attributes can't be directly modified (in the prim's current shape) they are still responsible for the shape of the prim. By using multiple shape changes these otherwise hidden attributes can be set.

The trouble with torturing prims through scripts is that it requires constantly changing complex llSetPrimitiveParams calls. There are 13 different shape changes that can be done, with about 8 different syntaxes total. To complicate things, SL has restrictions on some shape changes that will result in the prim being deleted instead of the change going through. Each of the 13 shape changes results in restrictions being applied to the attributes; each with it's own unique restrictions.

Simple easy to use prim torture function, not the most efficient but gets the job done with minimal hassle.

SetPrimType(integer version, integer type, 
            integer holeshape, vector cut, float hollow, vector twist, vector topsize, vector topshear,
            vector advancedcut, vector taper, float revolutions, float radiusoffset, float skew)
{
    if(1 == version )
    {//legacy PRIM_TYPE interface, still active for backwards compatability. Introduced in 1.3, phased out in 1.5.
        if(3 == type)//PRIM_TYPE_SPHERE
            llSetPrimitiveParams([version, type, cut, hollow, advancedcut]);
        else if(type >= 0 && type <= 2)//PRIM_TYPE_BOX,PRIM_TYPE_CYLINDER,PRIM_TYPE_PRISM
            llSetPrimitiveParams([version, type, cut, hollow, twist.y, topsize, topshear]);
        else if(4 == type)//PRIM_TYPE_TORUS
            llSetPrimitiveParams([version, type, cut, hollow, twist.y, topsize.y, topshear, advancedcut]);
        else if(5 == type)//PRIM_TYPE_TUBE
            llSetPrimitiveParams([version, type, cut, hollow, twist.y, topshear.x]);
//        else if(PRIM_TYPE_RING == p) ring shape not arround when this interface was implemented
    }
    else if(version == 9)
    {//new PRIM_TYPE interface. introduced in 1.5, various revisions have added new restrictions
        if(3 == type)//PRIM_TYPE_SPHERE
            llSetPrimitiveParams([version, type, holeshape, cut, hollow, twist, advancedcut]); 
        else if(type >= 0 && type <= 2)//PRIM_TYPE_BOX,PRIM_TYPE_CYLINDER,PRIM_TYPE_PRISM
            llSetPrimitiveParams([version, type, holeshape, cut, hollow, twist, topsize, topshear]);
        else if(type >= 4 && type <= 6)//PRIM_TYPE_TORUS,PRIM_TYPE_TUBE,PRIM_TYPE_RING
            llSetPrimitiveParams([version, type, holeshape, cut, hollow, twist, topsize, topshear, advancedcut, taper, revolutions, radiusoffset, skew]);
    }

}


Chained Prim Torture Script


This allows for easy chaining of prim torture commands. If you do alot of prim torture this will save some script time.

SetPrimTypeChained(list versions, list types, 
            integer holeshape, vector cut, float hollow, vector twist, vector topsize, vector topshear,
            vector advancedcut, vector taper, float revolutions, float radiusoffset, float skew)
{
    integer version;
    integer type = -llGetListLength(types);
    integer len = -llGetListLength(versions);
    if(type > len) len = type;
    for(;len;++len)
    {
        if(1 == (version = llList2Integer(versions,len)))
        {//legacy PRIM_TYPE interface, still active for backwards compatability. Introduced in 1.3, phased out in 1.5.
            if(3 == (type = llList2Integer(types,len)))//PRIM_TYPE_SPHERE
                llSetPrimitiveParams([version, type, cut, hollow, advancedcut]);
            else if(type >= 0 && type <= 2)//PRIM_TYPE_BOX,PRIM_TYPE_CYLINDER,PRIM_TYPE_PRISM
                llSetPrimitiveParams([version, type, cut, hollow, twist.y, topsize, topshear]);
            else if(4 == type)//PRIM_TYPE_TORUS
                llSetPrimitiveParams([version, type, cut, hollow, twist.y, topsize.y, topshear, advancedcut]);
            else if(5 == type)//PRIM_TYPE_TUBE
                llSetPrimitiveParams([version, type, cut, hollow, twist.y, topshear.x]);
    //        else if(PRIM_TYPE_RING == p) ring shape not arround when this interface was implemented
        }
        else if(version == 9)
        {//new PRIM_TYPE interface. introduced in 1.5, various revisions have added new restrictions
            if(3 == (type = llList2Integer(types,len)))//PRIM_TYPE_SPHERE
                llSetPrimitiveParams([version, type, holeshape, cut, hollow, twist, advancedcut]); 
            else if(type >= 0 && type <= 2)//PRIM_TYPE_BOX,PRIM_TYPE_CYLINDER,PRIM_TYPE_PRISM
                llSetPrimitiveParams([version, type, holeshape, cut, hollow, twist, topsize, topshear]);
            else if(type >= 4 && type <= 6)//PRIM_TYPE_TORUS,PRIM_TYPE_TUBE,PRIM_TYPE_RING
                llSetPrimitiveParams([version, type, holeshape, cut, hollow, twist, topsize, topshear, advancedcut, taper, revolutions, radiusoffset, skew]);
        }
    }
}

One of my favorite chains is
SetPrimTypeChained([9,1],[PRIM_TYPE_RING,PRIM_TYPE_SPHERE],PRIM_HOLE_DEFAULT,
        <0.0, 1.0, 0>,0.95,<0.0, 0.5, 0>,<0.0, 0.5, 0>,<0.0, 0.0, 0>,<0.47, 0.53, 0>,<0.0, 0.0, 0>,1,0,0);


Updatable Prim Torture Script


To help minimize prim deletion from happening, the script passes safe values when it knows they will later be overwritten.

Script that could be updated via a linked message to support new formats.
Definitely overkill.

Changes Since 1.0:

//----------------------------------------------//
//    Universal Prim Torture Script 1.2.2.1     //
//    Copyright (C) 2005  Strife Onizuka        //
//    http://home.comcast.net/~mailerdaemon/    //
//----------------------------------------------//
//
// To Use:
// Change the values in the state_entry
//
//--------------------------------------------------------------------//
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public License
//  as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//  
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
//  
//  You should have received a copy of the GNU Lesser General Public 
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, 
//  Boston, MA  02111-1307  USA
//
//  Any changes to this please post to:
//  http://secondlife.com/badgeo/wakka.php?wakka=LibraryPrimTorture
//
//--------------------------------------------------------------------//
//
//How to update if LL revises PRIM_TYPE or release new shapes:
//1. Add new PRIM_TYPE definition if it is needed (in init and below).
//2. Create TAGS for unique variables (variables that don't overlap with
//      others).
//3. Add new shapes, and unique variables.
//4. Add new overlapping code to Force Value (in state_entry) if
//      variables unevenly overlap.
//5. Adjust and add variables to llSetPrimitiveParams in state_entry.
//6. Update comments.
//
//--------------------------------------------------------------------//

integer status;    //set in state_entry with flags listed below.

//these need to be unique to the PRIM_TYPE value and shape.
//flag numbers need to be greater then zero

//PRIM_TYPE == 1
integer PRIM_TYPE_a_BOX         =    1;
integer PRIM_TYPE_a_CYLINDER    =    2;
integer PRIM_TYPE_a_PRISM       =    3;
integer PRIM_TYPE_a_SPHERE      =    4;
integer PRIM_TYPE_a_TORUS       =    5;
integer PRIM_TYPE_a_TUBE        =    6;

//PRIM_TYPE == 9
integer PRIM_TYPE_b_BOX         =    7;
integer PRIM_TYPE_b_CYLINDER    =    8;
integer PRIM_TYPE_b_PRISM       =    9;
integer PRIM_TYPE_b_SPHERE      =    10;
integer PRIM_TYPE_b_TORUS       =    11;
integer PRIM_TYPE_b_TUBE        =    12;
integer PRIM_TYPE_b_RING        =    13;

//bit fields for type definitions
//if these are changed then forceValue conditionals will need changing.

integer HOLESHAPE       =    0x1;       //i 0  old shapes abuse
integer CUT             =    0x2;       //v 1  
integer HOLLOW          =    0x4;       //f 2  
integer TWIST           =    0x8;       //v 3  twist - new shapes
integer TWISTY          =    0x10;      //f 4  twist - old shapes
integer TOPSIZE         =    0x20;      //v 5  holesize - new shapes
integer TOPSIZEY        =    0x40;      //f 6  holesize - old torus
integer TOPSHEAR        =    0x80;      //v 7  
integer TOPSHEARX       =    0x100;     //f 8  holesize - old tube
integer ADVANCEDCUT     =    0x200;     //v 9  
integer TAPER           =    0x400;     //v 10 new shapes
integer REVOLUTIONS     =    0x800;     //f 11 new shapes
integer RADIUSOFFSET    =    0x1000;    //f 12 new shapes
integer SKEW            =    0x2000;    //f 13 new shapes
//integer AVAILABLE       =    0x4000;    //  14 
//integer AVAILABLE       =    0x8000;    //  15 
//integer AVAILABLE       =    0x10000;   //  16 
//integer AVAILABLE       =    0x20000;   //  17 
//integer AVAILABLE       =    0x40000;   //  18 
//integer AVAILABLE       =    0x80000;   //  19 

//PRIM_TYPE_BOX         0
//PRIM_TYPE_CYLINDER    1
//PRIM_TYPE_PRISM       2
//PRIM_TYPE_SPHERE      3
//PRIM_TYPE_TORUS       4
//PRIM_TYPE_TUBE        5
//PRIM_TYPE_RING        6

init()
{
    if(status&1) return;
    integer a = CUT | HOLLOW;
    integer b = HOLESHAPE | CUT | HOLLOW | TWIST;
    integer c = TOPSIZE | TOPSHEAR;
    integer d = ADVANCEDCUT | TAPER | REVOLUTIONS | RADIUSOFFSET | SKEW;

    addType(PRIM_TYPE_a_BOX,        1, PRIM_TYPE_BOX,       
            TWISTY | c | a);
    addType(PRIM_TYPE_a_CYLINDER,   1, PRIM_TYPE_CYLINDER, 
            TWISTY | c | a);
    addType(PRIM_TYPE_a_PRISM,      1, PRIM_TYPE_PRISM,     
            TWISTY | c | a);
    addType(PRIM_TYPE_a_SPHERE,     1, PRIM_TYPE_SPHERE,    
            ADVANCEDCUT | a);
    addType(PRIM_TYPE_a_TORUS,      1, PRIM_TYPE_TORUS,     
            ADVANCEDCUT | TWISTY | TOPSIZEY | TOPSHEAR | a);
    addType(PRIM_TYPE_a_TUBE,       1, PRIM_TYPE_TUBE,      
            TOPSHEARX | TWISTY | a);
    
    addType(PRIM_TYPE_b_BOX,        9, PRIM_TYPE_BOX,       c | b);
    addType(PRIM_TYPE_b_CYLINDER,   9, PRIM_TYPE_CYLINDER,  c | b);
    addType(PRIM_TYPE_b_PRISM,      9, PRIM_TYPE_PRISM,     c | b);
    addType(PRIM_TYPE_b_SPHERE,     9, PRIM_TYPE_SPHERE,    
            ADVANCEDCUT | b);
    addType(PRIM_TYPE_b_TORUS,      9, PRIM_TYPE_TORUS,     d | c | b);
    addType(PRIM_TYPE_b_TUBE,       9, PRIM_TYPE_TUBE,      d | c | b);
    addType(PRIM_TYPE_b_RING,       9, PRIM_TYPE_RING,      d | c | b);
    status = status | 1;
}

list recType;
list recDef = [0];    //do not change,
//it allows the script to ignore bad types.

addType(integer fake, integer type, integer real, integer flag)
{
    integer c=llListFindList(recType,[fake]);
    flag = (flag & 0xFFFFF) | ((real&0xF)<<20) | ((type&0xFF)<<24);
    if(c+1)
        recDef=llListInsertList(llDeleteSubList(recDef,c,c),[flag],c);
    else
    {
        recDef=llListInsertList(recDef,[flag],llGetListLength(recType));
        recType+=fake;
    }
}

list test(integer m, integer n, integer t, list b)
{
    if(m & t) {
        t = ((n & t)!=0);
        return llList2List(b,t,t);
    }
    return [];
}

list PrimTorture(list flags, integer holeshape, vector cut,
             float hollow, vector twist, vector topsize,
             vector topshear, vector advancedcut, vector taper,
             float revolutions, float radiusoffset, float skew)
{
    init();
    integer p = llGetListLength(flags);
    integer m;
    integer n;
    integer r;
    list force;
    list k;
    while(p + 1)
    {
        n = n | (llList2Integer(recDef, llListFindList(recType,
                [llAbs(m)])) & 0xFFFFF);
        r = r | n;
        if(n & TWIST)
            n = n | TWISTY;
        if(n & TOPSIZE)
            n = n | TOPSIZEY;
        if(n & TOPSHEAR)
            n = n | TOPSHEARX;
        if(p--)
        {
            m = llList2Integer(flags, p);
            if(m<0)
                n = 0;
        }
        force = [n] + force;
    }
    //--------------------//
    p=-llGetListLength(flags);
    while(p)
    {
        //k = llList2Integer(flags,p);
        m = llList2Integer(recDef, llListFindList(recType,
            [llAbs(llList2Integer(flags, p))]));
        n = llList2Integer(force, p++);
        if(m)
        {
            k = [(m>>24)&0xFF, (m>>20)&0xF]
                +    test(m,n,HOLESHAPE,     [holeshape,    0       ])
                +    test(m,n,CUT,           [cut,          <0,1,0> ])
                +    test(m,n,HOLLOW,        [hollow,       0.5     ])
                +    test(m,n,TWIST,         [twist,        <0,0,0> ])
                +    test(m,n,TWISTY,        [twist.y,      0.0     ])
                +    test(m,n,TOPSIZE,       [topsize,      <1,0,0> ])
                +    test(m,n,TOPSIZEY,      [topsize.y,    0.0     ])
                +    test(m,n,TOPSHEAR,      [topshear,     <0,0,0> ])
                +    test(m,n,TOPSHEARX,     [topshear.x,   0.0     ])
                +    test(m,n,ADVANCEDCUT,   [advancedcut,  <0,1,0> ])
                +    test(m,n,TAPER,         [taper,        <0,0,0> ])
                +    test(m,n,REVOLUTIONS,   [revolutions,  1.0     ])
                +    test(m,n,RADIUSOFFSET,  [radiusoffset, 0.0     ])
                +    test(m,n,SKEW,          [skew,         0.0     ]) 
//                +    test(m,n,AVAILABLE,     [,        ])
                    ;
//            llWhisper(0,llList2CSV(k));
            llSetPrimitiveParams(k);
        }
    }
    k = [r];
//    jump end;
    if(r & HOLESHAPE)
        k+=["Holeshape = "  +  llList2String(
                ["PRIM_HOLE_DEFAULT", "PRIM_HOLE_SQUARE",
                "PRIM_HOLE_CIRCLE",  "PRIM_HOLE_TRIANGLE",
                "PRIM_HOLE_DEFAULT"],
                llListFindList([PRIM_HOLE_DEFAULT, PRIM_HOLE_SQUARE,
                PRIM_HOLE_CIRCLE, PRIM_HOLE_TRIANGLE],[holeshape]))];
    if(r & CUT)
        k+=["Cut = "            +   clean(cut)];
    if(r & HOLLOW) 
        k+=["Hollow  = "        +   strip(hollow)];
    if(r & TWIST)
        k+=["Twist = "          +   clean(twist)];
    else if(r & TWISTY)
        k+=["Twist.y = "        +   strip(twist.y)];
    if(r & TOPSIZE)
        k+=["Topsize = "        +   clean(topsize)];
    else if(r & TOPSIZEY)
        k+=["Topsize.y = "      +   strip(topsize.y)];
    if(r & TOPSHEAR)
        k+=["Topshear = "       +   clean(topshear)];
    else if(r & TOPSHEARX)
        k+=["Topshear.x = "     +   strip(topshear.x)];
    if(r & ADVANCEDCUT)
        k+=["Advanced Cut = "   +   clean(advancedcut)];
    if(r & TAPER)
        k+=["Taper = "          +   clean(taper)];
    if(r & REVOLUTIONS)
        k+=["Revolutions = "    +   strip(revolutions)];
    if(r & RADIUSOFFSET)
        k+=["Radius Offset = "  +   strip(radiusoffset)];
    if(r & SKEW)
        k+=["Skew = "           +   strip(skew)];
    @end;
    return k;
}

string strip(float a)
{
    string b = (string)a;
    integer c = 5;
    while(c-- && llGetSubString(b,-1,-1)=="0")
        b = llGetSubString(b,0,-2);
    return b;
}

string clean(vector a)
{
    return "<"+llList2CSV([strip(a.x),strip(a.y)])+">";
}

default
{
    state_entry()
    {
        //Old Flags
        // PRIM_TYPE_a_BOX
        // PRIM_TYPE_a_CYLINDER
        // PRIM_TYPE_a_PRISM
        // PRIM_TYPE_a_SPHERE
        // PRIM_TYPE_a_TORUS
        // PRIM_TYPE_a_TUBE

        //New Flags
        // PRIM_TYPE_b_BOX
        // PRIM_TYPE_b_CYLINDER
        // PRIM_TYPE_b_PRISM
        // PRIM_TYPE_b_SPHERE
        // PRIM_TYPE_b_TORUS
        // PRIM_TYPE_b_TUBE
        // PRIM_TYPE_b_RING
        
        list    flags  =   [PRIM_TYPE_b_TORUS,
//                            -PRIM_TYPE_a_CYLINDER,
                            PRIM_TYPE_a_SPHERE];
        
        integer holeshape       =    PRIM_HOLE_DEFAULT;
        vector  cut             =    <0.0, 1.0, 0>;
        float   hollow          =    0.95;
        vector  twist           =    <0.0, 0.5, 0>;
        vector  topsize         =    <0.0, 0.5, 0>;
        vector  topshear        =    <0.0, 0.0, 0>;
        vector  advancedcut     =    <0.47, 0.53, 0>;
        vector  taper           =    <0.0, 0.0, 0>;
        float   revolutions     =    1;
        float   radiusoffset    =    0;
        float   skew            =    0;
        
        // PRIM_HOLE_DEFAULT
        // PRIM_HOLE_SQUARE
        // PRIM_HOLE_CIRCLE
        // PRIM_HOLE_TRIANGLE
        
        llSay(0,"running");
        list a = PrimTorture(flags, holeshape, cut, hollow,
                    twist, topsize, topshear, advancedcut,
                    taper, revolutions, radiusoffset, skew);
        string b = llDumpList2String(llDeleteSubList(a,0,0),"\n");
        llSetObjectDesc(b);
        llSetText(b,<1,1,1>,1);
    }
}


Restrictions


Shape Version Type Hole Shape Cut Hollow Twist Taper / Holesize Top Size Top Shear Advanced Cut Taper Revolutions Radius Delta* Skew
Begin End Begin End X Y X Y Begin End X Y
Min Max Min Max Min Max Min Max Min Max Min Max Min Max Min Max Min Max Min Max Min Max Min Max Min Max Min Max Min Max Min Max Min Max
Box 1 0 0 0 0 1 0 1 0 0.95

-0.5 0.5 0 1 0 1 -0.5 0.5 -0.5 0.5 0 0 1 1









Cylinder 1 1 0 0 0 1 0 1 0 0.95

-0.5 0.5 0 1 0 1 -0.5 0.5 -0.5 0.5 0 0 1 1









Prism 1 2 0 0 0 1 0 1 0 0.95

-0.5 0.5 0 1 0 1 -0.5 0.5 -0.5 0.5 0 0 1 1









Sphere 1 3 0 0 0 1 0 1 0 0.95











0 1 0 1









Torus 1 4 0 0 0 1 0 1 0 0.95

-0.5 0.5

0 0.5 -0.5 0.5 -0.5 0.5 0 1 0 1









Tube 1 5 0 0 0 1 0 1 0 0.95

-0.5 0.5



0.05 0.45

0 0 1 1









Box 9 0 0 48 0 1 0 1 0 0.95 -0.5 0.5 -0.5 0.5 (0,-1) (2,1) (0,-1) (2,1) -0.5 0.5 -0.5 0.5 0 0 1 1 0 0 0 0 1 1 0 0 0 0
Cylinder 9 1 0 48 0 1 0 1 0 0.95 -0.5 0.5 -0.5 0.5 (0,-1) (2,1) (0,-1) (2,1) -0.5 0.5 -0.5 0.5 0 0 1 1 0 0 0 0 1 1 0 0 0 0
Prism 9 2 0 48 0 1 0 1 0 0.95 -0.5 0.5 -0.5 0.5 (0,-1) (2,1) (0,-1) (2,1) -0.5 0.5 -0.5 0.5 0 0 1 1 0 0 0 0 1 1 0 0 0 0
Sphere 9 3 0 48 0 1 0 1 0 0.95 -1 1 -1 1 1 1 1 1 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 0 0 0
Torus 9 4 0 48 0 1 0 1 0 0.95 -1 1 -1 1 0 1 0 0.5 -0.5 0.5 -0.5 0.5 0 1 0 1 -1 1 -1 1 1 4 -1 1 -1 1
Tube 9 5 0 48 0 1 0 1 0 0.95 -1 1 -1 1 0 1 0 0.5 -0.5 0.5 -0.5 0.5 0 1 0 1 -1 1 -1 1 1 4 -1 1 -1 1
Ring 9 6 0 48 0 1 0 1 0 0.95 -1 1 -1 1 0 1 0 0.5 -0.5 0.5 -0.5 0.5 0 1 0 1 -1 1 -1 1 1 4 -1 1 -1 1


As you can see by this table, old-style spheres rock the Casbah.


Script Library | Examples
There is no comment on this page. [Display comments/form]