Jump to content

change point about which a prim rotates


Judy Hynes
 Share

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

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

Recommended Posts

I have a problem with trying to rotate a child prim in a link set.  Id like to use llSetLocalRot in a script, which rotates the child relative to the root prim and is exactly what I'd like to do.  However, the prim rotates about its center and I'd rather it rotated about a different point.  I attached a picture to help make it clearer.  As you can see, the center of the selected gun prim is not at the hinge (marked with the yellow box), which is the point I would ideally like to have it rotate around.

My first thought was to link the gun prim to another prim that is centered at the hinge and then rotate the two as a pair.  This works fine if only these 2 prims are linked, but I still have to link them back to the base prim, which breaks the relationship between the "hinge" prim and the gun prim. Once all 3 are linked, I can rotate the hinge prim all I want but it doesn't move the gun prim along with it anymore.  And if I rotate the gun prim it still rotates about its own center point. so I'm back where I started.

Is there anything I can do to make it seem like the gun prim is rotating at that hinge point (not its own prim center)?  Can I link it in some more clever way than I tried before?  Is there some script magic that will let me pull this off?

turret.png

Link to comment
Share on other sites

The 'Correct' way to pull that off is to rebuild your mesh with a single extra disconnected triangle placed in such a way as to counter balance the rest of the object and cause the center of the mesh to be where you want it to be. If that's impractical, the workaround is to use math.

rotate_prim_intrinsic(integer link,vector axis, float angle, vector offset)
{
    list l = llGetLinkPrimitiveParams(link,[PRIM_POS_LOCAL,PRIM_ROT_LOCAL]);
    vector local_pos = llList2Vector(l,0);
    rotation local_rot = llList2Rot(l,1);
    rotation rot = llAxisAngle2Rot(axis,angle);
    
    vector offset2 = offset*(rot);
    llSetLinkPrimitiveParamsFast(link,
    [   PRIM_POS_LOCAL,local_pos+(offset2-offset)*local_rot,
        PRIM_ROT_LOCAL,rot*local_rot
    ]);
}
Link to comment
Share on other sites

Great, this is very helpful.  After playing with this function a little I was able to apply some simple rotations about the offset axis that I wanted.

I decided to add one more step to my sample by making it apply a rotation to match the angle the user is looking in mouselook.  However, I can't seem to figure out how to determine the angle between camera rotation and horizontal plane, i.e. the angle of elevation that the camera is looking up or down from horizontal.  I feel like this should be simple but I just haven't been able to figure it out.

 

Link to comment
Share on other sites

9 hours ago, Judy Hynes said:

i.e. the angle of elevation that the camera is looking up or down from horizontal.

The technical term for that is the 'pitch' or 'altitude'  of the camera (assuming I parsed what you want correctly).

You can convert a rotation of an x-forward oriented object (like the SL-camera) to yaw-pitch-roll form, with one of:

vector Rot2YPR(rotation q)
{ //implementation by Mollymews
// https://community.secondlife.com/forums/topic/471561-urot2euler/?do=findComment&comment=2293046
    vector v;
    // x-axis
    float s = 2 * (q.s * q.x + q.y * q.z);
    float c = 1 - 2 * (q.x * q.x + q.y * q.y);
    v.z = llAtan2(s, c);
    // y-axis
    s = 2 * (q.s * q.y - q.z * q.x);
    if (llFabs(s) >= 1)
        v.y = (-1 | (s < 0)) * PI_BY_TWO;
    else
        v.y = llAsin(s);
    // z-axis
    s = 2 * (q.s * q.z + q.x * q.y);
    c = 1 - 2 * (q.y * q.y + q.z * q.z);
    v.x = llAtan2(s, c);
    return v;
}

vector Rot2YPR(rotation rot)
{//my alternate implementation
    vector ret;
    vector temp = <1,0,0>*rot;
    ret.x = llAtan2(temp.y,temp.x);
    rot = rot/llEuler2Rot(<0,0,ret.z>); // Grr, I think this is a typo, try replacing with: 
    //rot = rot/llEuler2Rot(<0,0,ret.x>);
    temp = <1,0,0>*rot;
    ret.y = -llAtan2(temp.z,temp.x);
    rot = rot/llEuler2Rot(<0,ret.y,0>);
    temp = <0,1,0>*rot;
    ret.z = llAtan2(temp.z,temp.y);
    return ret;
}

or to just simply to convert a vector to altitude, azimuth:

float vec2Altitude(vector v)
{ return llAtan2(v.z,llVecMag(<v.x,v.y,0>));
  // alternatively
  return llAtan2(v.z,llSqrt((v.x*v.x)+(v.y*v.y)));
}

float vec2Azimuth(vector v)
{ return llAtan2(v.y,v.x);
}

P.S. Probably should have mentioned that like all math things, functions like to work with radians not degrees.

Edited by Quistess Alpha
Link to comment
Share on other sites

Yes, this is what I was after.  I tried using your implementation of Rot2YPR, and it does what I need.  A couple of things I noticed:

  • The line that says "I think this is a typo" seems to be correct that it is a mistake.  I had to comment out that line and use the one below it instead to get the right results for pitch when facing north/south.
  • The pitch value returned is negative for up tilt and positive for down tilt.  I guess this is a right-hand rule thing with orientation of the axes.  I thought people usually use positive pitch to mean up not down for things like airplanes.  In any event, it's easy enough to negate the value if you want to use the "positive means up" frame of reference.  The function rotate_prim_intrinsic that you posted seems to do upward rotation for positive angles, at least the way I'm using it.
  • I guess this should be obvious, but for anyone else new to using this notation, the "roll" for the camera is always zero since there's no way to rotate the camera around the forward direction axis, i.e. you can't "tilt" the camera left or right when looking at something.
  • Like 1
Link to comment
Share on other sites

18 minutes ago, Judy Hynes said:

I guess this should be obvious, but for anyone else new to using this notation, the "roll" for the camera is always zero since there's no way to rotate the camera around the forward direction axis, i.e. you can't "tilt" the camera left or right when looking at something.

To be pedantic (which I just love doing), you can control the camera's roll in flycam mode using a 3D mouse like 3DConnexion's SpaceNavigator.

  • Like 1
Link to comment
Share on other sites

1 hour ago, Judy Hynes said:

The pitch value returned is negative for up tilt and positive for down tilt.  I guess this is a right-hand rule thing with orientation of the axes.  I thought people usually use positive pitch to mean up not down for things like airplanes.  In any event, it's easy enough to negate the value if you want to use the "positive means up" frame of reference.  The function rotate_prim_intrinsic that you posted seems to do upward rotation for positive angles, at least the way I'm using it.

I'll be the first to admit that getting the sign(+or-) correct on these sorts of things can be confusing. Theoretically yes, right hand rule says pitch up is negative and pitch down is positive, although, I agree that most practical things would reverse that convention. my rotate_prim_intrinsic, is not at all trustworthy as far as the signs of things go, and I've noticed some puzzling results from it from time to time, but it works well enough and figuring out where I may have flipped two values or have a negative where there should be a positive, is too fiddly for me to really care about when it works well enough to fudge it when you need it to work.

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 944 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
 Share

×
×
  • Create New...