Jump to content

Rotations - once again


Darkie Minotaur
 Share

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

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

Recommended Posts

Rotations and me will never be friends. It's a simple task: I have an evelope - the body is the root, the flap is the child. On touching the envelope, I want the flap to open (to rotate up and reset the position, so it is still aligned to the envelope body) - somehow, I don't get to do it correctly. Here is what I have (the script is in the root):

 

default {
    touch_end(integer num_detected) {
    	rotation grIncrementX = llEuler2Rot(<160.0,0.0,0.0>*DEG_TO_RAD);
    	list liposrot = llGetLinkPrimitiveParams(2, [PRIM_POS_LOCAL, PRIM_ROT_LOCAL]);
		rotation newrot = grIncrementX * llList2Rot(liposrot, 1);
    	vector newOffset = llList2Vector(liposrot, 0) * grIncrementX;
    	llSetLinkPrimitiveParams(2, [PRIM_POS_LOCAL, newOffset, PRIM_ROT_LOCAL, newrot]);
    }
}

 Where do I go wrong (yet again)?

Link to comment
Share on other sites

Oh, I still don't get them either ... but it looks like you are rotating the "rot" and "position" in different axis/directions - one is increment * oldrot, the other is oldpos * increment ... shouldn't they both be the same?  in rotations order matters IIRC.  Can't offhand remember which one you need mind :)

(Everything I know about child rotations is here - but its from the point of view of the child, not the root rotating the child - http://kimmscripts.wordpress.com/2011/05/25/child-prim-rotation/)

ETA: Actually, won't you also have to compensate for the centre of rotation being at the edge of the flap?  Unless you've use path-cut type tricks (as you can do with a door).  That is what I had to do in the script on the above link.

When I'm stuck, I tend to look at Void's rotation page on the wiki: https://wiki.secondlife.com/wiki/User:Void_Singer/Rotations

ETA again: fixed link (mumble, grumble ... auto link recognition ... brackets ... mumble, grumble)

Kimm.

 

  • Like 1
Link to comment
Share on other sites

You might be right, Dora.  I never trust myself completely without testing in world to see what happens, and I usually trust your instincts about rotations before I will trust my own.  My general rule, though, is that operations are applied from right to left.  Normally, that means you start with the current rotation (rightmost), then apply a correcting rotation (to the left of it). 

Link to comment
Share on other sites

Thank you for your suggestions.

@Dora: I followed Void's rotation tutorial "To rotate in the Self Frame (prim's own axis):

  • (vRotAmount2ChangeBy * vRotCurrentLocal)"

I tried it, too - the result wasn't any better ;)

 

@Rolig: I do reposition it - flap isn't rotated around the center of the flap. 

Link to comment
Share on other sites

Oh.  I didn't see any position offset in your snippet, so I assumed that your flap was just a cut prim that you have twisted 45 degrees on both X and Y so that it could rotate like a door does around its cut edge.  In that case, your position should be

llSetLinkPrimitiveParamsFast( 2, [PRIM_POS_LOCAL, llList2Vector(liposrot,0) + offset_vector*grIncrementX*llList2Rot(liposrot,1) ] );

where you still need to define the offset_vector.  (Again, I' feel more comfortable if I could test this in world, but it feels right.)

Link to comment
Share on other sites

In this context, it's the amount you want to move the child prim from its current position.  So, if you want to move it 0.1m in the direction of its local X-axis, the offset is <0.1,0.0,0.0> .   The logic of my suggestion was that you want to set the prim's position to its current local position, corrected by moving it some distance that is, itself, adjusted by rotating it by some increment (160.0 degrees) relative to its current local rotation .... if that makes sense.  :smileywink:  

Link to comment
Share on other sites

Darkie --  The easiest way to solve the problem is to avoid it.  I'll send you a demo in world that uses Void's simple hinge script.  It works like a dream.  (I'll still keep poking at your way of doing it, though, because it ought to work, even if it's much harder. :) )

  • Like 1
Link to comment
Share on other sites

Oooo... This turns out to be really tricky if you don't use the easy way out.  (The easy way is to use a cut prim and Void's simple hinge.)  If you don't use a cut prim for the envelope flap, you have to calculate an offset based on the width of the flap and the angle that you will be rotating it through.  Here's what works, including the code necessary to close the flap again on a second touch.  Notice that I was wrong earlier.  You do not need to apply any rotation at all to the position offset, once you calculate how much the offset is.  [Note:  The flap on my envelope is a rectangular prim, flattened on Z and oriented so that it will hinge on its Y-axis, so the offset I need to calculate is on the X-axis.  It's also necessary to offset on the Z axis, because otherwise the leading edge of the envelope flap does not stay level with the envelope as it opens. This was not intuitively obvious to me until I started messing with it, but you'll see what I mean if you leave the Z correction out.]

 

rotation adjust;vector offset;default{    state_entry()    {        adjust = llEuler2Rot(<0.0,-120.0,0.0>*DEG_TO_RAD);        vector Size = llList2Vector(llGetLinkPrimitiveParams(2,[PRIM_SIZE]),0);        offset = <-(1.0-llCos(llRot2Angle(adjust)))*0.5*Size.x,0.0,-llSin(llRot2Angle(adjust))*0.5*Size.x>;    }            touch_start(integer total_number)    {        if (llDetectedLinkNumber(0) == 2)        {            list temp = llGetLinkPrimitiveParams(2,[PRIM_POS_LOCAL,PRIM_ROT_LOCAL]);            vector Lpos = llList2Vector(temp,0);            rotation Lrot = llList2Rot(temp,1);            adjust = ZERO_ROTATION/adjust;            llSetLinkPrimitiveParamsFast(2,[PRIM_POS_LOCAL, Lpos + (offset = -offset), PRIM_ROT_LOCAL,adjust*Lrot]);        }    }}

 

Link to comment
Share on other sites

This is how I ended up doing it, which rotates on a different edge from yours (I'm not quite sure which edge of the child prim it's supposed to use as the pivot):

 

  rotation grIncrementX;  default {    state_entry(){           grIncrementX = llEuler2Rot(<160.0,0.0,0.0>*DEG_TO_RAD);    }    touch_end(integer num_detected) {                       grIncrementX.s*=-1;        list liposrot = llGetLinkPrimitiveParams(2, [PRIM_POS_LOCAL, PRIM_ROT_LOCAL,PRIM_SIZE]);        vector mySize = llList2Vector(liposrot,2);         float myX = mySize.x;        float MyY = mySize.y;        float myXOffset = myX*0.5;        float myYOffset = MyY *0.5;       vector  vVecOffset = <-myXOffset, myYOffset, 0.0>;            rotation local = llList2Rot(liposrot,1);      llSetLinkPrimitiveParamsFast(2, [PRIM_POS_LOCAL, llList2Vector(liposrot,0)+ (vVecOffset - vVecOffset * grIncrementX) *local,                       PRIM_ROT_LOCAL, grIncrementX * local]);    }}

 

  • Like 1
Link to comment
Share on other sites

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