Jump to content
Wandering Soulstar

HELP! Distance to furthest Prim point

Recommended Posts

Hi All,

Hope that someone can lend a hand here. I have been going around in circles with this for the past couple of days and at this point feel that my head is going to explode.

What I want to do if determine the distance from the center of a prim to the furthest point of the prim along a particular world axis. With prims that are at zero rotation, or only rotated 90/180/270 on any axis it is simple. If I want the distance along the x-axis, for example, Zero Rotation it would be 1/2 the x size; rotated 90/270 on y it would be1/2 z size, and 90/270 rotation on z would be 1/2 y  size. The problem I am having is when there is a non-right angle rotation on an axis .. or even more, when there is a rotation on more that one axis. The size no longer is all I need as the furthest point becomes an edge/corner not the face.

I have tried multiple ways of figuring this out, but it has been way too many decades since I studied trig. Have some half solutions, but these are based on too many variables and having to check what is rotated where etc that I know there must be a simpler mathematical formula for doing this ... so hoping the math wizards out there could lend a hand.

 

Thanks in advance!

Wanda

Edited by Wandering Soulstar
spelling

Share this post


Link to post
Share on other sites

Is a bounding box solution good enough? This will get you the bounding  box of an object in world coordinates.

 

float pathMin(float a, float b) { if (a<b) { return(a); } else { return(b); }} // usual min and max, avoiding name clashes
float pathMax(float a, float b) { if (a>b) { return(a); } else { return(b); }}
//
//  pathGetBoundingBoxWorld -- get object bounding box in world coordinates
//
//  LSL gives us the bounding box in object coordinates. We have to rotate it
//  and get the limits.  One vertex at a time.
//
list pathGetBoundingBoxWorld(key id)
{
    list info = llGetObjectDetails(id, [OBJECT_POS, OBJECT_ROT]) + llGetBoundingBox(id);
    vector pos = llList2Vector(info, 0);            // position in world coords
    rotation rot = llList2Rot(info, 1);             // rotation in world coords
    integer ix;
    integer iy;
    integer iz;
    //  Convert each corner of the original bounding box to world coordinates.
    vector mincorner;                               // bounding box in world coords
    vector maxcorner;
    integer first = TRUE;                           // first time through
    for (ix=0; ix<2; ix++)                          // do all vertices of bounding box
    {   vector vx = llList2Vector(info, ix+2);
        for (iy=0; iy<2; iy++)
        {   vector vy = llList2Vector(info, iy+2);
            for (iz=0; iz<2; iz++)
            {   vector vz = llList2Vector(info, iz+2);
                vector pt = <vx.x, vy.y, vz.z>;     // one corner of the bounding box in obj coords
                vector ptworld = pt * rot + pos;    // in world coords
                if (first)
                {   mincorner = ptworld;
                    maxcorner = ptworld;
                    first = FALSE;
                }  else {
                    mincorner = <pathMin(mincorner.x,ptworld.x), pathMin(mincorner.y, ptworld.y), pathMin(mincorner.z, ptworld.z)>;
                    maxcorner = <pathMax(maxcorner.x,ptworld.x), pathMax(maxcorner.y, ptworld.y), pathMax(maxcorner.z, ptworld.z)>;
                }
            }
        }
    }
    return([mincorner, maxcorner]);                 // min and max corners, in world coordinates
}

 

  • Thanks 1

Share this post


Link to post
Share on other sites

Assuming that these "prims" are cubes... (They don't have to be.)

A cube has 8 corners, but let's focus on just one first. The one with relative position <1,1,1> from the center.

vector corner = <1,1,1>;

corner = <1,1,1> * llEuler2Rot(<0,-45,-45> * DEG_TO_RAD);

// Or more simply
corner *= llGetRot();

That's how you calculate the new position of the corner in any rotation (<0,-45,-45> in this case). (You'll need a list of corners and do the same for each one.)

Then, when you want to know which corner is the furthest away from the center, you go through the list of corner positions and check the absolute value of the axis you want, and always store the highest value and possibly record which corner it was. Easy peasy.

Edited by Wulfie Reanimator
  • Thanks 1

Share this post


Link to post
Share on other sites

Thanks!!!!!

@animats I see yours will give me the max/min position for each xyz, which is very good. For what I need though I only every need to find one and so the base formula as pointed out by  @Wulfie Reanimator.

Following is the sample code off the back of these guides. I knew it had to be simpler than what I was doing 🙂

list CORNERS = [<1.0, 1.0, 1.0>, <-1.0, 1.0, 1.0>, <-1.0, -1.0, 1.0>, <-1.0, 1.0, -1.0>, <-1.0, -1.0, -1.0>, <1.0, -1.0, -1.0>, <1.0, 1.0, -1.0>, <1.0, -1.0, 1.0>];

float get_mod(string axis, integer min)
{
    rotation rot = llGetRot();
    list vals = [];
    integer x;

    for (x = 0; x < 8; x++)
    {
        vector corner = llList2Vector(CORNERS, x) * rot;
        //now grab just the axis we are looking for
        if (axis == "x"){vals += [corner.x];}
        else if (axis == "y"){vals += [corner.y];}
        else if (axis == "z"){vals += [corner.z];}
    }

    //now sort according to which value we are looking for
    vals = llListSort(vals, 1, min);

    //and return the first
    return llList2Float(vals, 0);
}
    

default
{
    touch_start(integer total_number)
    {
        float mod = get_mod("x", FALSE);
        float dist = ((llGetScale().x)/2) * mod;
        float posit = llGetPos().x + dist; 
    }
}

 

Edited by Wandering Soulstar

Share this post


Link to post
Share on other sites

Since the time has past for me to be able to edit it, please ignore the above post. I had tested this out, but only briefly and must have hit the one scenario/time it was right. I have just these past days been finally in full testing of the system where this code was .. and found out that it did not work at all. After struggling with it for much longer than I should have (being stubborn) .. I went back to @animats code .. and wouldn't you know it .. worked perfectly. For my scenario though there was one problem ... llGetBoundingBox returns for the whole linkset, whilst I need it for the specific prim ... but actually calculating the prim's bounding box is fairly simple .. at least I believe so .. basically it is just the prim scale vector with each xyz divided by 2 (max) and -2 (min) ... if this is not always correct please let me know ...

My final version is as follows .. mainly animat's code .. with formating changes based on how I like it (to each their own style) , the bounding box change, passing in the values as I do need this code to get these values for other prims as well and llGetObjectDetails does not bring back scale, and as well I have scenarios where I need to call this passing a scale that the prim does not have ... and then finally removing the pathMax, pathMin functions (again personal preference).

 

vector div_vector_num(vector dividend, float divisor)
{
    dividend.x = dividend.x/divisor;
    dividend.y = dividend.y/divisor;
    dividend.z = dividend.z/divisor;

    return dividend;
}

//find the global positions of the max and min corners of a prim
//developed by animats
//minor modifications by Wanda Soulstar 
list get_corners(vector pos, rotation rot, vector size)
{
    // bounds in local dist from center, min & max
    list bound = [div_vector_num(size, -2), div_vector_num(size, 2)];
    
    //resulting corner positions
    vector minCorner;                               
    vector maxCorner;
    //loop through the x,y,z vertices
    //ctrs
    integer ix;
    integer iy;
    integer iz;
    //vertices
    vector vx;
    vector vy;
    vector vz;
    //calculations
    vector pt;
    vector ptWorld;
    
    for (ix = 0; ix < 2; ix++)                          
    {
        vx = llList2Vector(bound, ix);        
        for (iy = 0; iy < 2; iy++)
        {
            vy = llList2Vector(bound, iy);          
            for (iz = 0; iz < 2; iz++)
            {
                vz = llList2Vector(bound, iz);
                //now get the corner ... in obj coords
                pt = <vx.x, vy.y, vz.z>;
                //translate to world coords     
                ptWorld = pt * rot + pos;

                //first time through set base
                if ((ix + iy + iz) == 0)
                {
                    minCorner = ptWorld;
                    maxCorner = ptWorld;
                }                
                else
                {                    
                    //calc min corner
                    if (ptWorld.x < minCorner.x){minCorner.x = ptWorld.x;}
                    if (ptWorld.y < minCorner.y){minCorner.y = ptWorld.y;}
                    if (ptWorld.z < minCorner.z){minCorner.z = ptWorld.z;}
                    //and then max corner
                    if (ptWorld.x > maxCorner.x){maxCorner.x = ptWorld.x;}
                    if (ptWorld.y > maxCorner.y){maxCorner.y = ptWorld.y;}
                    if (ptWorld.z > maxCorner.z){maxCorner.z = ptWorld.z;}
                }
            }
        }
    }
    return([minCorner, maxCorner]);                 
}

 

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.


×
×
  • Create New...