Jump to content
Sign in to follow this  
mgjackson

How do you build a Dome?

Recommended Posts

Looking closely at some of the buildings built is SL, I am constantly amazed by the level of detail that goes into them; it seems as much effort is required as building the real thing.

I've been looking at the Abbotts Spaceport and thought I'd have a go at building something similar - there's also a similar version on one of the University Campus Sims.

However, what as got me flumoxed is creating the huge dome the goes over the top - I'd assumed it was simply a large hollowed out semi-sphere, but its not.  Its actually hundreds of transparent rectangular prims put together.  The first few rows are rectangular, but then on the uppers rows, each prim is tapered to neatly fit.

I've tried to do this by hand and its is very difficult  -  I don't know how to work out the relative rotation of each prim and to calculate the actual tapering so it fits neatly to the next one.

Having tried a couple of attemps, including trying to build a scaffold to line the prims up, I can't see how its done.

Are these things actually built using a script that lines the prims up and calculates the angles etc, or are they really all done by hand.

Thanks,

Matthew

 

 

 

 

 

 

Share this post


Link to post
Share on other sites

Altho it is not totally impossible to do it by hand --with a lot of determination and a TPV which can put the axis of rotation on a prim instead of in the middle of nowhere-- a script will do it within minutes instead of hours... so, it is more likely that a faceted dome is a scripted build.

I wrote such a script a long time ago. It is a simple problem of topology which does not even require a lot of mathematics.

Share this post


Link to post
Share on other sites

Hi, i cannot remember the exact name right now but that could be done with a Prim-Skirt-Builder.

Some of this scripts are available for free. Search Marketplace ?

Monti

Share this post


Link to post
Share on other sites

Thanks, a script was what I was starting to suspect :-)

A newbie question: Can a script create prims though - seems quite dangerous if a runaway script started creating thousands of prims.

Share this post


Link to post
Share on other sites

Dangerous?  Yes.  If you write a script that rezzes new objects continuously, you can overwhelm a sim quickly.  You can also get yourself banned from SL for engaging in "malicious or disruptive conduct that impedes or interferes with other users' normal use of the Service."  Not a good idea.  In general, though, rezzers are an important part of SL. They're everywhere.

Share this post


Link to post
Share on other sites

Before megaprims were generally available, the only way to build a dome larger than 10M in diameter was to use a LOT of small prims, and build it like an igloo, with a series of tapered rings stacked atop each other. There are scripted rezzers that do this. You put one prim that you created into the rezzer's inventory, with a name that the script knows to use for that prim. It then rezzes copies of the prim, changes its dimensions and taper, and places the prims to make a ring, repeating the process until the last cap is made with triangular prims (100% taper).

A much more efficient way today is to use a hollowed sphere, cut in half. You can make up to a 64 M diameter dome that way these days, and only use one prim to do it.

If you need adome larger than 64 M in diameter, I believe Mesh would be the right solution now. Model the dome in an external application and import the mesh for it into SL. The land impact will most likely be far lower than hundreds of tapered rectangular prims stacked in rings.

Share this post


Link to post
Share on other sites

With mesh the maximum size would still be 64 meters, but you could ofcourse chop up the dome in smaller sections, four would give you 128 meters....

Share this post


Link to post
Share on other sites

@ mgjackson

To Answer your question. A Script can be used to create objects and position them as scripted... The object must contain another communication script in it and instructions how to build and rez said object

This script is used to make Geodesic Domes with multiple prims

Made by Shine Renoir

The first script goes into the "Builder Object" Just a simple cube will be perfect

// Script Name: Geodesic_Dome_Builder.lsl//This code makes beautiful geodesic domes// Dome Builder// 2007 Copyright by Shine Renoir (fb@frank-buss.de)// Use it for whatever you want, but keep this copyright notice// and credit my name in notecards etc., if you use it in// closed source objectsinteger subdivision = 2;float length = 3.0;vector base;float r;move(vector destination){    // llSetPos is limited to 10m distances,    // so it is called until the target is reached    vector p = ZERO_VECTOR;    while (p.z != destination.z) {        llSetPos(destination);        p = llGetPos();    }}drawLine(vector v1, vector v2){    vector line = v2 - v1;    vector pos = base + line / 2 + v1;    float len = llVecMag(line);    vector size = <0.1, 0.1, len>;    vector up = <0, 0, 1>;    rotation rot = llRotBetween(up, llVecNorm(line));    move(pos);    llRezObject("Line", pos, ZERO_VECTOR, rot, 0);    llSay(-42, (string) size);}drawTriangle(vector v1, vector v2, vector v3){    // assuming a normal triangle: no zero area    // make v1-v3 the longest side    integer i = 0;    for (i = 0; i < 2; i++) {        float a = llVecDist(v2, v3);        float b = llVecDist(v1, v3);        float c = llVecDist(v1, v2);        if (a > b || c > b) {            vector tmp = v1;            v1 = v2;            v2 = v3;            v3 = tmp;        }    }        // calculate side lengths    float a = llVecDist(v2, v3);    float b = llVecDist(v1, v3);    float c = llVecDist(v1, v2);    // b=b1+b2, a^2=h^2+b2^2, c^2=b1^2+h^2, solving:    float b2 = (a*a + b*b - c*c)/2.0/b;    float b1 = b - b2;    float h = llSqrt(a*a - b2*b2);  // triangle height    // calculate triangle height vector and shear value    float hPosition = b1 / b;    vector vb1 = (v3 - v1) * hPosition;    vector vh = v2 - (v1 + vb1);    float shear = hPosition - 0.5;    // calculate position and rotation    vector pos = base + v1 + (v3 - v1) / 2 + vh / 2;    vector size = <b, 0.05, h>;    vector up = <0.0, 0.0, 1.0>;    rotation rot = llRotBetween(up, llVecNorm(vh));    vector fwd = llVecNorm(v3 - v1);  // fwd is the base    vector left = llVecNorm(vh);    left = llVecNorm(left % fwd);  // "left" is cross product (orthogonal to base and left)    rot = llAxes2Rot(fwd, left, fwd % left);  // calculate the needed rotation        // create object    llRezObject("Triangle", pos, ZERO_VECTOR, rot, 0);        // set size and shear value    list send = [size, shear ] ;    llSay(-42, llList2CSV(send));}vector scaleToSphere(vector v){    float l = llVecMag(v);    return r / l * v;}drawSide(vector bottomLeft, vector top, vector bottomRight){    integer i;    integer segments = subdivision + 1;    vector dx = (bottomRight - bottomLeft) / segments;    vector dy = (top - bottomLeft) / segments;    for (i = 0; i < segments; i++) {        integer j;        for (j = 0; j < subdivision * 2 + 1 - 2 * i; j++) {            if ((j % 2) == 0) {                // even, draw left and bottom line                integer l = j / 2;                vector v1 = scaleToSphere(bottomLeft + l * dx + i * dy);                vector v2 = scaleToSphere(bottomLeft + l * dx + (i+1) * dy);                vector v3 = scaleToSphere(bottomLeft + (l+1) * dx + i * dy);                drawLine(v1, v2);                drawLine(v1, v3);                drawTriangle(v1, v2, v3);            } else {                // odd, draw right line                integer l = (j - 1) / 2;                vector v1 = scaleToSphere(bottomLeft + l * dx + (i+1) * dy);                vector v2 = scaleToSphere(bottomLeft + (l+1) * dx + i * dy);                vector v3 = scaleToSphere(bottomLeft + (l+1) * dx + (i+1) * dy);                drawLine(v1, v2);                drawTriangle(v1, v2, v3);            }        }    }}drawDome(){    float l2 = length / 2.0;    vector bottomLeft = <-l2, -l2, 0.0>;    vector topLeft = <-l2, l2, 0.0>;    vector topRight = <l2, l2, 0.0>;    vector bottomRight = <l2, -l2, 0.0>;    vector top = <0, 0, length * llSqrt(6.0) / 3.0>;    r = llVecMag(bottomLeft - topRight) / 2.0;    drawSide(bottomLeft, top, bottomRight);    drawSide(topLeft, top, bottomLeft);    drawSide(topRight, top, topLeft);    drawSide(bottomRight, top, topRight);}initialize(){    llSetSitText("Build");    llSetText("Right click and 'Build'", <1, 0, 0>, 1.0);    llSitTarget(<0.5, 0.0, 0.7>, ZERO_ROTATION);    base = llGetPos();}default{    touch_start(integer total_number)    {        llSay(0, "Right click me and choose 'Build' to start build");    }    on_rez(integer start_param)     {        initialize();    }        state_entry()    {        initialize();    }        changed(integer change)    {        // sitdown or standup        if (change & CHANGED_LINK) {            key av = llAvatarOnSitTarget();            if (av) {                // sitdown                initialize();                drawDome();                base.z += length + 1.0;                move(base);            }        }    }}

 The next script below, put in an Rod Object Named "LIne"

The rod object is a Cylinder with size <0.1,0.1,1.0> ( I Do not think size matters since the script creates size but do it anyway)

 

// One time scale script// 2007 Copyright by Shine Renoir (fb@frank-buss.de)// Use it for whatever you want, but keep this copyright notice// and credit my name in notecards etc., if you use it in// closed source objectsinteger handle;default{    state_entry()    {        handle = llListen(-42, "", NULL_KEY, "" );    }        listen(integer channel, string name, key id, string message)    {        llSetScale((vector) message);        llListenRemove(handle);    }        on_rez(integer param) {        llResetScript();    }}

 

Now for the triangle object. Create an object and Name it 'Triangle' Just any simple square prim. a "Cube", And put the script below into it

// One time scale and shear script
// 2007 Copyright by Shine Renoir (fb@frank-buss.de)
// Use it for whatever you want, but keep this copyright notice
// and credit my name in notecards etc., if you use it in
// closed source objects

integer handle;

default
{
    state_entry()
    {
        handle = llListen(-42, "", NULL_KEY, "" );
    }
    
    listen(integer channel, string name, key id, string message)
    {
        list tokens = llCSV2List(message);
        vector size = (vector) llList2String(tokens, 0);
        float shear = (float) llList2String(tokens, 1);
        llSetPrimitiveParams([
            PRIM_TYPE, PRIM_TYPE_BOX,
            0,  // hollow shape
            <0.0, 1.0, 0.0>,  // cut
            0.0,  // hollow
            <0.0, 0.0, 0.0>,  // twist
            <0.0, 1.0, 0.0>,  // taper
            <shear, 0.0, 0.0>,  // top shear
            PRIM_SIZE, size
        ]);
        llListenRemove(handle);
    }
    
    on_rez(integer param) {
        llResetScript();
    }
}

 

After you have made the Line Object and the triangle object. Put both objects inside the main Builder object, which has the main Builder Script in it

Then all you do is right click the object and chose build.. ( Maybe reset all scripts before use )

To change the size of the dome. Simply open the main build script and on line 2 of the source code which reads  "float length = 3.0;" The 3 in that line represents meters. Right now it is set to 3 meters. Change the 3 to any size you want.. Its fun too you get to ride the object while it builds the dome

 

 

If you have trouble making this work

IM me in world and I can send you the one I just now made

Share this post


Link to post
Share on other sites

Wow, thank you, most kind.

Shall have a play and see if I can get it to work.

My first attempt to get a script to build something was to link several prims to a root prim which had the script then iterate through the list setting size, colours and position.

(I'd missed the concept of an object being able to rez objects from its own inventory)

Quickly hit the location position is relative to the root prim and the 10M setPos limit (which seems a pain, but stops prims literally dissappearing over the horizon)

 

 

Share this post


Link to post
Share on other sites

It won't help with the linking restriction (the centres of all the prims need to be within 54 metres of the root prim, as I recall) but you can use the new function, llSetRegionPos() , in place of llSetPos() and forget about the 10 metre limit on llSetPos (so long as you stay within the sim, though I think it will also take you 10 metres into the next sim -- though that gets a bit hairy if you are sitting on it, as I have found out by experience).

 

 

Share this post


Link to post
Share on other sites

It works pretty well with 15m prims....didn't want to hog the whole sandbox so didn't go any larger :-)

Very impressive script, thanks again.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...