Jump to content

Place a disk (child prim) flat against the surface of a sphere (root prim)


You are about to reply to a thread that has been inactive for 4267 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Posted

I want to use llSetLinkPrimitiveParams to put a disk (child prim), flat against the surface of a larger sphere (root prim).


I have found how to calculate the cartesian coordinates (this is starting from latitude/longitude basically) to put the child in the right place with PRIM_POSITION but nothing I have tried with, for example, llRotBetween() seems to put the child in the correct orientation (using either: PRIM_ROTATION or PRIM_ROT_LOCAL).

Has anyone done this (or knows how to)?

Posted

let s try with an instance ...

 

float thinSlice;default{    state_entry()    {       // prim root is a sphere size 2*2*2               llSetLinkPrimitiveParams(1, [        35, <0.000000, 1.000000, 0.000000>, 7, <2.000000, 2.000000, 2.000000>, 9, 3, 0, <0.000000, 1.000000, 0.000000>, 0.000000, <0.000000, 0.000000, 0.000000>, <0.000000, 1.000000, 0.000000> ]);                     // prim child is a sphere size 0.01*0.5*0.5 with a thin slice from 0.48 to 0.5       llSetLinkPrimitiveParams( 2 , [       35, <0.480990, 0.501000, 0.000000>, 7, <0.010000, 0.500000, 0.50000>,        9, 3, 0, <0.000000, 1.000000, 0.000000>, 0.000000, <0.000000, 0.000000, 0.000000>,        <0.480990, 0.501000, 0.000000> ] );                vector slice = llList2Vector(llGetLinkPrimitiveParams( 2, [ PRIM_SLICE] ),0);        thinSlice = (slice.y - slice.x)/2.0 ;    }    touch(integer total_number)    {        if ( llDetectedLinkNumber(0) == 1)        {            vector P = llDetectedTouchPos(0);            if ( P != ZERO_VECTOR )            {                vector N = llDetectedTouchNormal(0);                vector left = llVecNorm(N % llRot2Fwd(llGetLocalRot()));                vector fwd  = left % N;                 rotation curRot = llAxes2Rot( fwd, left, N);
// i add a rotation along Y to have the disk tangent to the sphere curRot = llEuler2Rot(<0,PI_BY_TWO,0>) * curRot ; llSetLinkPrimitiveParamsFast(2, [ PRIM_POS_LOCAL, (P - llGetPos() + thinSlice * N )/llGetLocalRot() , PRIM_ROT_LOCAL, curRot/llGetLocalRot()]); } } }}

 

note : in this instance , we could add too the size of the child prim following X  ( to compute the final position) , but it s neglictable compared to the thin of the slice.

the script must be in the root prim

  • Like 1
Posted

You don't say how you're deciiding where to put the disk on the root prim, but assuming you're touching the sphere, try this:

//see http://www.sluniverse.com/php/vb/scripting/75227-calculations-relative-angles-positions.html#post1617740 and following//for explanationsdefault{    state_entry()    {          }    touch_start(integer total_number)    {        if(1==llDetectedLinkNumber(0)){            vector pos = llGetPos();            vector spot = (llDetectedTouchPos(0) -pos) / llGetRot();            vector v = llDetectedTouchNormal(0)/llGetRot();            rotation r = llRotBetween(<0.0,0.0,1.0>,v);            llSetLinkPrimitiveParamsFast(2,[ PRIM_POSITION,spot,PRIM_ROT_LOCAL,r] );        }    }}

 

  • Like 2
Posted

Thanks for the swift response. The script gets the position from an external source in the form of latitude and longitude. The root prim is a sphere representing the earth, with North at the top.

 

The child prim is ideally a thin cylinder (small z) placed just above the surface of the sphere.

Posted
float NewYorkLatitude = 40.71;float NewYorkLongitude = -74.00;float ParisLatitude = 48.87;float ParisLongitude = 2.34;           vector interp( float destLatitude, float destLongitude, float sourceLatitude, float sourceLongitude , float t ){    vector result;    result.x = ( 1.0 - t ) * sourceLatitude +  t * destLatitude;    result.y = ( 1.0 - t ) * sourceLongitude + t * destLongitude;    return result;}vector latitudeLongitude2Cartesian(float lat , float lon, float R ){    vector result;    result.x = R * llCos(lat * DEG_TO_RAD) * llCos(lon * DEG_TO_RAD);    result.y = R * llCos(lat* DEG_TO_RAD) * llSin(lon* DEG_TO_RAD);    result.z = R * llSin(lat* DEG_TO_RAD);        return result;}default{    state_entry()    {llSetLinkPrimitiveParams( 1, [ PRIM_SLICE , <0.000000, 1.000000, 0.000000>, PRIM_SIZE, <0.500000, 0.500000, 0.500000>, PRIM_TYPE, PRIM_TYPE_SPHERE, 0, <0.000000, 1.000000, 0.000000>, 0.000000, <0.000000, 0.000000, 0.000000>, <0.000000, 1.000000, 0.000000> ] );llSetLinkPrimitiveParams( 2, [ PRIM_SLICE ,<0.000000, 1.000000, 0.000000>, PRIM_SIZE, <0.020000, 0.020000, 0.010000>, PRIM_TYPE, PRIM_TYPE_CYLINDER, 0, <0.000000, 1.000000, 0.000000>, 0.000000, <0.000000, 0.000000, 0.000000>, <1.000000, 1.000000, 0.000000>, <0.000000, 0.000000, 0.000000>,PRIM_COLOR, ALL_SIDES, <1,0,0>, 1.0 ]);    }    touch_start(integer total_number)    {             float lat ; // latitude         float lon ; // longitude        vector coord; // cartesian coordinates in the frame of the sphere        float t = 0.0;         vector size = llList2Vector( llGetLinkPrimitiveParams( 1, [ PRIM_SIZE] ), 0);        float R = size.x / 2.0 ; // diameter of the sphere / 2.0        vector P;                        do         {            coord = interp( ParisLatitude, ParisLongitude, NewYorkLatitude, NewYorkLongitude , t);            lat = coord.x;            lon = coord.y;                    P = latitudeLongitude2Cartesian(lat, lon, R);                        vector spot = P / llGetRot();            vector normal = spot;// the vector normal to a surface for an uniform sphere  is equal to // the vector between the center of the sphere and the spot // so , it s equal to the vector spot.// It won t be the case if your "earth" is ellipsis like the real earth            rotation r = llRotBetween(<0.0,0.0,1.0>, llVecNorm(normal) );            llSetLinkPrimitiveParamsFast(2,[ PRIM_POSITION,spot,PRIM_ROT_LOCAL,r] );            t += 0.01;            llSleep(1/45.0);        } while ( t <= 1.0 );               }}

 

  • Like 1
You are about to reply to a thread that has been inactive for 4267 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...