Space Frame Loop Rezzer

From Second Life Wiki
Revision as of 09:38, 7 September 2009 by Nikolai Vaniva (talk | contribs) (more pics)
Jump to navigation Jump to search

Definition and Uses of Space Frame

A space frame is an architectural element consisting only of struts and hubs. A space frame can provide great strength in a light open structure and is used in many modern buildings. The key to its strength is that the struts are always in tension or compression and never see any torque.

This space frame is built by the loop rezzer SFRezzer and has all the struts of the same length with flat top and bottom grids made of squares. The grits are connected by struts at compound angles. The top grid has one more square each way than the bottom grid. The normal structural supports are the four corner hubs in the bottom grid but in Second Life it makes no difference how you use your space frame.

Example of a 3 x 2 space frame

Loop Rezzer Use Summary

The process of building a custom Space Frame in Second Life is detailed below and includes the following these steps:

  1. Use click and point to move the Space Frame Rezzer Prim from you inventory to a Second Life area where you have permission to build.
  2. Edit the included script to show the size on the X and Y axis you need. (You may exceed the 10 meter limit.)
  3. Edit the nominal length of the strut.
  4. Save the script.
  5. Exit the editor
  6. Left click on the Space Frame Rezzer prim.
  7. The Space Frame will then be automatically generated. (The process takes about two minute.)
  8. Inspect the Space Frame visually and check the height and strut length in the communications window. (Erase and repeat steps 2 through 7 if needed.)
  9. Select all the struts for linking. (The limit is 256.)
  10. Select the base plate at the origin last.
  11. Be sure that the Space Frame Rezzer prim is not selected.
  12. Link all the selected prims in the Space Frame.
  13. Right click the linked Space Frame and Take it.

There are some limitations:

  1. The strut cannot exceed 10 meters.
  2. Space frames require a large number of prims.

A space frame can be used in Second Life for:

  1. Architectural element such as roof support
  2. Bridge or other landscape element
  3. Hat, shield, or other clothing

Peculiarities of this Space Frame Rezzer

To rez a space frame, decide how big a space you need to span. The space frame will be rezzed along the X and Y axis but can be repositioned after it has been rezzed and linked. All measurements are in meters and may be entered to three significant figures. Neither span is restricted by the 10 meter limit but be sure to stay in an open working space.

Decide the nominal length of the strut you wish to use. For best results, both the X and Y span distances should be integer multiples of the strut length. If you enter numbers that are not multiples, then the strut length will be adjusted to fit the X span and there may be an error on the Y span.

The number of primes needed for a space frame can run up very quickly. Using larger values of the strut length reduces the number of prims needed while increasing the height. The maximum number of primes that can be linked is 256.

Example of Space Frame Strut extensions to form hub

The struts overlap slightly to form the hubs, so no extra prims are needed for them.

The height of the space frame is always 0.707 times the actual strut length.

The loop rezzer sends messages to the user through the local communication window giving such information as:

  1. number of X nodes
  2. number of Y nodes
  3. strut length
  4. height
  5. errors in Y
  6. number of prims used

All measurements are in meters. If more than 255 prims are used, you may wish to reconsider your inputs.

Credits

This Space Frame Rezzer was written by:

Please email this author for additional information or a working copy of SFRezzer.

This script incorporates key software from two other rezzers:

  • // "Building Prim Skirts using the Loop Rezzer"
  • // LoopRez v0.6, by Ged Larsen, 20 December 2006

And

  • // Shine Renoir's Geodesic Dome Builder
  • // One time scale script
  • // 2007 Copyright by Shine Renoir ( fb@frank-bus.de )

This rezzer was developed using the sandbox at:

  • NASA eEducation (223,115,24)

Building the Loop Rezzer

The loop rezzer prim provided is a twisted sphere. You may use any prim you like as long as it is distinctive.

A very detailed step-by-step procedure for a loop rezzer can be found in:

  • // "Building Prim Skirts using the Loop Rezzer"
  • // LoopRez v0.6, by Ged Larsen, 20 December 2006

The following script listing must be included under Content in the loop rezzer:

<lsl> /////////////////////////////////////////////////////////////////////// // Space Frame Rezzer V2.0 with Scaling // Square grid, 2 user dimensions, strut scaled , span not limited in X and Y // by Tom Riley a.k.a. Nikolai Vaniva, August 29, 2009 // Best known for // "Woodware Designs" http://www.charm.net/~jriley/woodware.html // Modified from: // LoopRez v0.6, by Ged Larsen, 20 December 2006 // ///////////////////////////////////////////////////////////////////// //

// User entered information: (3 items)

float gSizeX = 3.000 ; // Distance between Space Frame supports in meters along X axis; best if an integer multiple of gStrutLength

float gSizeY = 2.000 ; // Distance between Space Frame supports in meters along Y axis; best if an integer multiple of gStrutLength

float gStrutLength = 1.000 ; // Nominal strut length float gStrutDia = 0.060 ; // strut diameter

//////////////////////////////////////////////////////////

// No user changes are needed below this line!

string objectName = "StrutScale" ; // object for Strut; // will need to be in the inventory of the prim containing this script integer gStrutPrim = 1 ; // Number of prims per strut string rootPrimName = "Space Frame Pad" ; // root prim that will appear at origin support

integer gNumStruts = 0 ; // count number of struts vector rotOffset = <0.0, 0.0, 0.0> ; // rotation offset in DEGREES vector posOffset = <0.0, 0.0, 1.5> ; // position offset from rezzing prim to root prime

move(vector destination) {

   // llSetPos is limited to 10 m distances,
   // so it is called until the target is reached
   vector p = ZERO_VECTOR;   // need to check Y too ???
   while (p.x != destination.x ) {
       llSetPos(destination); 
       p = llGetPos();
   }

}

sfRezLoop() // primary Space Frame generator {

   vector orgPos = llGetPos() ; // save original position of rez generator
   // Calculate number of X and Y nodes and strut length
    float sfStrutLength =  gStrutLength ;
    
    integer nXNode = (integer) ( gSizeX / sfStrutLength)  + 1 ;
    if ((gSizeX != (float) (nXNode-1) * gStrutLength) ) {
         ++nXNode ;
    }
    sfStrutLength = gSizeX / ((float)nXNode - 1.0) ; // adjust strut length
    float sfRealSizeX = ((float) nXNode -1.0) *  sfStrutLength ;
    float sfErrorX = gSizeX - sfRealSizeX ;
    
    integer nYNode = (integer) (gSizeY / sfStrutLength) + 1;
    float sfRealSizeY = ((float) nYNode -1.0) *  sfStrutLength ;
    float sfErrorY = gSizeY - sfRealSizeY ;
   // calculate internal parameters

   vector sfStrutReSize = < (sfStrutLength + gStrutDia), gStrutDia , gStrutDia > ; // scaling
   float sfStrut05 = sfStrutLength / 2.00 ; // 1/2 step
   float sfStrut025 = sfStrutLength / 4.00 ; // 1/4 step
   float sfDiaXY = llSqrt( 2* (sfStrut05 * sfStrut05 )) ; // diagonal in XY plane
   float sfHeight = llSqrt( ( sfStrutLength *  sfStrutLength) -
                 ( sfDiaXY * sfDiaXY ) ) ;  // height of Space Frame
   float sfHeight05 = sfHeight / 2 ; // half step in height
   
   float sfAngle45 = PI / 4.0 ; // angle around Y and Z axis

    llOwnerSay( "X nodes: " +  (string)nXNode + ", Y nodes: " + (string) nYNode + ", Strut: " + (string) sfStrutLength) ; // report XY node numbers to local talk window
     llOwnerSay( "X error: " +  (string)sfErrorX + ", Y error: " + (string) sfErrorY + ", Height: " + (string) sfHeight) ; // report XY error values to local talk window
   integer nX = 0;           // Step counter in X axis
   integer nY = 0;           // Step counter in Y axis
   integer n = 0 ;           // general counter
   rotation rot;             // rotation in quaternion format

   vector rezzerPos = llGetPos();
   vector rootPrimPos = rezzerPos + posOffset ;
   vector pos = ZERO_VECTOR ;

   // Rez Space Frame pad for root prim
   llRezObject(rootPrimName, rootPrimPos, ZERO_VECTOR, ZERO_ROTATION, 0); 
   // This prim marks the center of the support at local <0.0,0.0,0.0>
   ++gNumStruts ;
   // Rez lower struts || to X axis
   rot = llEuler2Rot(rotOffset * DEG_TO_RAD) ;  // set rotation
   for( nX = 0; nX < nXNode-1 ; ++nX) {
       for( nY=0 ; nY < nYNode ; ++nY) {
           pos = rootPrimPos + < (nX * sfStrutLength + sfStrut05),
                      (nY * sfStrutLength), 0.0> ;  // offset to node 
           move(pos);          
           llRezObject(objectName, pos, ZERO_VECTOR, rot, n) ; // rez the strut
           llSay(-2900, (string) sfStrutReSize ); // send resize message
           gNumStruts = gNumStruts + gStrutPrim ;  // count struts rezzed
       }
    }
    // Rez lower struts || to Y axis
    rot = llEuler2Rot(rotOffset * DEG_TO_RAD) * 
            llEuler2Rot(< 0.0, 0.0, 90.0> * DEG_TO_RAD) ;
    for( nX = 0; nX < nXNode ; ++nX) {
         for( nY=0 ; nY < nYNode-1 ; ++nY) {
             pos = rootPrimPos + < (nX * sfStrutLength),
                (nY * sfStrutLength + sfStrut05), 0.0> ;
             move(pos);         
             llRezObject(objectName, pos, ZERO_VECTOR, rot, n);
             llSay(-2900, (string) sfStrutReSize ); // send resize message
             gNumStruts = gNumStruts + gStrutPrim ;  // count struts rezzed
        }
    }
    // Rez upper struts || to X axis
   rot = llEuler2Rot(rotOffset * DEG_TO_RAD) ; 
   for( nX = 0; nX < nXNode ; ++nX) {
        for( nY=0 ; nY < nYNode+1 ; ++nY) {
             pos = rootPrimPos + < (nX * sfStrutLength),
                      (nY * sfStrutLength - sfStrut05 ), sfHeight > ; 
             move(pos);  
             llRezObject(objectName, pos, ZERO_VECTOR, rot, n);
             llSay(-2900, (string) sfStrutReSize ); // send resize message
             gNumStruts = gNumStruts + gStrutPrim ;  // count struts rezzed
        }
    }
    // Rez upper struts || to Y axis
    rot = llEuler2Rot(rotOffset * DEG_TO_RAD) * 
            llEuler2Rot(< 0.0, 0.0, 90.0> * DEG_TO_RAD);
    for( nX = 0; nX < nXNode+1 ; ++nX) {
          for( nY=0 ; nY < nYNode ; ++nY) {
               pos = rootPrimPos + < (nX * sfStrutLength - sfStrut05),
                      (nY * sfStrutLength), sfHeight> ;
               move(pos);             
               llRezObject(objectName, pos, ZERO_VECTOR, rot, n);
               llSay(-2900, (string) sfStrutReSize ); // send resize message
               gNumStruts = gNumStruts + gStrutPrim ;  // count struts rezzed
         }
    }
  
    // Rez diagonal struts
    // Rez double diagonal struts group 1 (pos ++) of 4 groups
    rot = llEuler2Rot(< 0.0, -sfAngle45, 0.0 > ) *
                 llEuler2Rot(< 0.0, 0.0, sfAngle45 > ) ; // set compound angle
    for( nX = 0; nX < nXNode ; ++nX) {
         for( nY=0 ; nY < nYNode ; ++nY) {
             pos = rootPrimPos + < ((nX * sfStrutLength) + sfStrut025),
                      ((nY * sfStrutLength) + sfStrut025), sfHeight05 > ;
             move(pos);
             llRezObject(objectName, pos, ZERO_VECTOR, rot, n);
             llSay(-2900, (string) sfStrutReSize ); // send resize message
             gNumStruts = gNumStruts + gStrutPrim ;  // count struts rezzed
         }
    }
    // Rez Diagonal struts group 2 (pos +-, clockwise)
    rot = llEuler2Rot(< 0.0, -sfAngle45, 0.0 > ) *
                 llEuler2Rot(< 0.0, 0.0, -sfAngle45 > ) ;
    for( nX = 0; nX < nXNode ; ++nX) {
         for( nY=0 ; nY < nYNode ; ++nY) {
            pos = rootPrimPos + < ((nX * sfStrutLength) + sfStrut025),
                      ((nY * sfStrutLength) - sfStrut025), sfHeight05 > ;
            move(pos);
            llRezObject(objectName, pos, ZERO_VECTOR, rot, n);
            llSay(-2900, (string) sfStrutReSize ); // send resize message
            gNumStruts = gNumStruts + gStrutPrim ;  // count struts rezzed
         }
    }
    // Rez Diagonal struts group 3 (pos --)
    rot = llEuler2Rot(< 0.0, sfAngle45, 0.0 > ) *
                 llEuler2Rot(< 0.0, 0.0, sfAngle45 > ) ;
    for( nX = 0; nX < nXNode ; ++nX) {
        for( nY=0 ; nY < nYNode ; ++nY) {
            pos = rootPrimPos + < ((nX * sfStrutLength) - sfStrut025),
                      ((nY * sfStrutLength) - sfStrut025), sfHeight05 > ;
            move(pos); 
            llRezObject(objectName, pos, ZERO_VECTOR, rot, n);
            llSay(-2900, (string) sfStrutReSize ); // send resize message
            gNumStruts = gNumStruts + gStrutPrim ;  // count struts rezzed
        }
    }
    // Rez Diagonal struts group 4 (pos +-)
    rot = llEuler2Rot(< 0.0, sfAngle45, 0.0 > ) *
                 llEuler2Rot(< 0.0, 0.0, -sfAngle45 > ) ;
    for( nX = 0; nX < nXNode ; ++nX) {
         for( nY=0 ; nY < nYNode ; ++nY) {
             pos = rootPrimPos + < ((nX * sfStrutLength) - sfStrut025),
                      ((nY * sfStrutLength) + sfStrut025), sfHeight05 > ; 
             move(pos);
             llRezObject(objectName, pos, ZERO_VECTOR, rot, n);
             llSay(-2900, (string) sfStrutReSize ); // send resize message
             gNumStruts = gNumStruts + gStrutPrim ;  // count struts rezzed
         }
    }
    llSetPos(orgPos) ; // restore original position of generator 
    llOwnerSay( " Number pims: " + (string) gNumStruts);
    // report number of prims rezzed

}

default {

   touch_start(integer total_number)   // start action, click on generator prim
   {
       if (llDetectedOwner(0) == llGetOwner()) // only useful to owner
       {
           sfRezLoop();  // generate Space Frame 
       }
   }

} </lsl>

You will also need to add the following two prims.

Example of support node for a Space Frame

Adding the Space Frame Prim

You need a small simple prim to serve as the archer point for the final linked space frame. A small cylinder is provided but other prims may be used. This prim must be named "Space Frame Pad", but requires no software listing.

Example of Space Frame Strut 1.0 meter long

Adding the Strut

The Space Frame Strut is its construction element and must be named "StrutScale". Any single prime or linked prim group may be used but the number of prims used build up very quickly so a single prim is best.

The example uses a sphere prim that has been stretched along the X axis to provide the needed shape. A cylinder could also be used. A combination of the software in the Loop Rezzer and the strut itself will adjust the length of the strut as needed.

The color and texture of the strut are not changed by the Loop Rezzer so you should edit these to suit your needs before use.

The following software must be include in the Strut prim itself:

<lsl> ///////////////////////////////////////////////////////// // Space Frame Strut V1.0 // Strut resizing function // by Tom Riley a.k.a. Nikolai Vaniva, August 25, 2009 // Best known for "Woodware Designs" // http://www.charm.net/~jriley/woodware.html // Modified from: // One time scale script // 2007 Copyright by Shine Renoir ( fb@frank-bus.de ) // //////////////////////////////////////////////////////// //

integer handle;

default {

   state_entry()
   {
       handle = llListen(-2900, "", NULL_KEY, "" );
   }
   listen(integer channel, string name, key id, string message)
   {
           llSetScale((vector) message); // Resize strut
           llListenRemove(handle);       // no more messages
   }
   on_rez(integer param) 
   {
       llResetScript();  // start new with each rez
   }

} </lsl>