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:
- changed the default values
- Added commented out jump to avoid new return code. If you don't want the extra return data just uncomment the line "jump end;"
- Added nice return from the function.
- Changed default values for non-forced attributes.
- Changed the values of all flags.
- New feature: Making a flag negative forces it to use the specified values and not use the non-forced attribute defaults. It does the exact same thing as if you had called the function twice with the negative flag being the last flag of the first call.
- Made Script into a function
- Changed default values for non-forced attributes.
//----------------------------------------------//
// 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 |
|
- Values in parentheses: The first value is the script range, the second value is the client range. To convert between the two do (1.0 - value)
- If values are supplied in the table that is the range the value is forced to be within when that shape change is preformed by llSetPrimitiveParams.
- Blue boxes are attributes supplied to llSetPrimitiveParams to perform the shape change.
- If ranges are absent in the table that indicates the attribute is not checked.
- Client-based shape changes are governed by different restrictions (usually more restrictive).
- Version is the value of PRIM_TYPE.
- Type is represent the PRIM_TYPE_* constants.
- Hole Shape only uses bits 4, 5, 6 & 7; bits 0->3 are ignored; valid values range from 0->63 inclusive. [PRIM_HOLE_DEFAULT, 0x0], [PRIM_HOLE_CIRCLE, 0x10], [PRIM_HOLE_SQUARE, 0x20], [PRIM_HOLE_TRIANGLE, 0x30].
- Radius Delta's range is dependent on Taper Y. Radius Delta must have the same sign as Taper Y.
- Taper / Holesize is a different attribute then Taper
- Skew's range is affected by Hole Size X and Taper.
As you can see by this table, old-style spheres rock the Casbah.
Script Library |
Examples