Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

how to get the desired rotation ??

Varun Blitz
Registered User
Join date: 22 May 2008
Posts: 62
07-11-2008 22:01
what i want to achieve is that avatar rotates in a particular direction and stays that way till the animation is over.
the thing attached to my avatar is able to move my avatar to the desired point but since i can't control the rotation of my avatar with that attached thing, it performs the animation in some other direction.
i thought maybe i can place a small platform there and then when avatar reaches it, it senses the rotation of avatar, calculates by how much he is deviated from the required direction and rotates it.
now the trouble is i am a bit confused abt how to calculate the deviation from required direction and then which function to use ??
Kaluura Boa
Polygon Project
Join date: 27 Mar 2007
Posts: 194
07-12-2008 04:34
Now I'm starting to really understand why we use sit targets on objects that need to be manipulated... :D

For your little problem, yes, a small platform is the only way to go. Here is how I see the thing:

float DesiredAngle; // A global variable

DesiredAngle = whatever + PI; // We'll work in radians
if (DesiredAngle > TWO_PI) { DesiredAngle -= TWO_PI; }

The angle I'm talking about is the Z rotation. I add PI (180 degrees) in order not to deal with the zero/2*PI barrier. And that 'whatever' can be (degrees * RAD_TO_DEG).

Use the collision() event.

When llDetectedVel(0) == 0.0, the avatar is not moving on top of the platform any more.

Store the avatar's key in a global variable.

Avatar = llDetectedKey(0);

Jump to another state without collision() event, but a collision_end() to detect when the avatar is leaving.

Turn to physical.

state_entry()
{
llSetBuoyancy(1.0); // To prevent any fall.
llSetStatus(STATUS_PHYSICS, TRUE);
llSetTimerEvent(0.25); // A relatively fast timer
}

timer()
{
float avatar_rot = llList2Rot(llGetObjectDetails(Avatar, [OBJECT_ROT]), 0);
vector euler = llRot2Euler(avatar_rot);
float avatar_angle = euler.z + PI;
if (avatar_angle > TWO_PI) { avatar_angle -= TWO_PI; }
else if (avatar_angle < 0.0) { avatar_angle += TWO_PI; } // That shouldn't happen.

if (avatar_angle < (DesiredAngle - 0.01))
{
llApplyRotationalImpulse(<0.0, 0.0, more>, FALSE)
}
else if (avatar_angle > (DesiredAngle + 0.01))
{
llApplyRotationalImpulse(<0.0, 0.0, less>, FALSE)
}
else
{
llSetTimerEvent(0.0); // We reached the desired rotation, with a little margin
llSetStatus(STATUS_PHYSICS, FALSE);
}
}

collision_end(integer total)
{
state default; // Avatar just left.
}

I know that llApplyRotationalImpulse() is what we need but, honestly, I've never used it... so it's your job to find what 'more' and 'less' are. I used a vector <0, 0, something> because that makes sense for a rotation around the Z axis.

Just my L$ 0.5 of the day...
Varun Blitz
Registered User
Join date: 22 May 2008
Posts: 62
07-12-2008 06:27
but when i asked a similar question for avatar movement on this forum, someone said that there is no way by which we can rotate an avatar. we can only use llmovetotarget and llapplyimpulse to move/push him.
i have yet not tried ur method, have to understand it bit and fill the missing parts, let's see if it works.
Varun Blitz
Registered User
Join date: 22 May 2008
Posts: 62
07-12-2008 06:54
From: Kaluura Boa
Now I'm starting to really understand why we use sit targets on objects that need to be manipulated... :D

For your little problem, yes, a small platform is the only way to go. Here is how I see the thing:

float DesiredAngle; // A global variable

DesiredAngle = whatever + PI; // We'll work in radians
if (DesiredAngle > TWO_PI) { DesiredAngle -= TWO_PI; }

The angle I'm talking about is the Z rotation. I add PI (180 degrees) in order not to deal with the zero/2*PI barrier. And that 'whatever' can be (degrees * RAD_TO_DEG).

Use the collision() event.

When llDetectedVel(0) == 0.0, the avatar is not moving on top of the platform any more.

Store the avatar's key in a global variable.

Avatar = llDetectedKey(0);

Jump to another state without collision() event, but a collision_end() to detect when the avatar is leaving.

Turn to physical.

state_entry()
{
llSetBuoyancy(1.0); // To prevent any fall.
llSetStatus(STATUS_PHYSICS, TRUE);
llSetTimerEvent(0.25); // A relatively fast timer
}

timer()
{
float avatar_rot = llList2Rot(llGetObjectDetails(Avatar, [OBJECT_ROT]), 0);
vector euler = llRot2Euler(avatar_rot);
float avatar_angle = euler.z + PI;
if (avatar_angle > TWO_PI) { avatar_angle -= TWO_PI; }
else if (avatar_angle < 0.0) { avatar_angle += TWO_PI; } // That shouldn't happen.

if (avatar_angle < (DesiredAngle - 0.01))
{
llApplyRotationalImpulse(<0.0, 0.0, more>, FALSE)
}
else if (avatar_angle > (DesiredAngle + 0.01))
{
llApplyRotationalImpulse(<0.0, 0.0, less>, FALSE)
}
else
{
llSetTimerEvent(0.0); // We reached the desired rotation, with a little margin
llSetStatus(STATUS_PHYSICS, FALSE);
}
}

collision_end(integer total)
{
state default; // Avatar just left.
}

I know that llApplyRotationalImpulse() is what we need but, honestly, I've never used it... so it's your job to find what 'more' and 'less' are. I used a vector <0, 0, something> because that makes sense for a rotation around the Z axis.

Just my L$ 0.5 of the day...



this is what i tried writing using ur script :-

float DesiredAngle; // A global variable
key avatar;
float less= 45;
float more=45;
default
{
state_entry()
{
float DesiredAngle = 90 + PI; // We'll work in radians
if (DesiredAngle > TWO_PI) { DesiredAngle -= TWO_PI; }
}
collision(integer det)
{
avatar=llDetectedKey(0);
if(llDetectedType(0) & AGENT)
{
if(llDetectedVel(0)==<0,0,0>;)
state set;
}
}
}

state set
{
state_entry()
{
llSetBuoyancy(1.0); // To prevent any fall.
llSetStatus(STATUS_PHYSICS, TRUE);
llSetTimerEvent(0.25); // A relatively fast timer
}



timer()
{
rotation avatar_rot =(rotation) llList2String(llGetObjectDetails(avatar, [OBJECT_ROT]), 0);
vector euler = llRot2Euler(avatar_rot);
float avatar_angle = euler.z + PI;
if (avatar_angle > TWO_PI) { avatar_angle -= TWO_PI; }
else if (avatar_angle < 0.0) { avatar_angle += TWO_PI; } // That shouldn't happen.
if (avatar_angle < (DesiredAngle - 0.01))
{
llApplyRotationalImpulse(<0.0, 0.0, more>, FALSE);
}
else if (avatar_angle > (DesiredAngle + 0.01))
{
llApplyRotationalImpulse(<0.0, 0.0, less>, FALSE);
}
else
{
llSetTimerEvent(0.0); // We reached the desired rotation, with a little margin
llSetStatus(STATUS_PHYSICS, FALSE);
}
}

collision_end(integer total)
{
state default; // Avatar just left.
}
}


since u said that try experimenting with more/less thing, i thought maybe i will try putting something then see what happens and then adjust it but the object went off world.
Kaluura Boa
Polygon Project
Join date: 27 Mar 2007
Posts: 194
07-12-2008 17:28
LOL Congratulations! You're an SL h4X0r now. Sending objects off-world isn't that easy.

I can't test right now but I'll do it later. Any way, there is something wrong that I can already see: The angles:

less = -45 * DEG_TO_RAD; // Don't forget the negative sign.
more = 45 * DEG_TO_RAD;

You don't need to use global variables. Just put the values in the vectors in the timer(). And I would try with really smaller values... Something like 5 degrees at maximum.

The same degrees/radians thing for the DesiredAngle:

DesiredAngle = (90 * DEG_TO_RAD) + PI; // We'll work in RADIANS, not degrees!

90 degrees = PI/2 so...

DesiredAngle = 1.5 * PI; // Much shorter!

Besides you redefined DesiredAngle at the beginning of the state_entry() so the global variable is still 0.0 when you reach the timer().

And you can use llList2Rot() instead of (rotation)llList2String(). llGetObjectDetails() returns a "real" rotation, not a string. You are doing a double conversion that introduces more rounding errors than usual.

I'll tell you more later when I'll eat my... *cough! cough!*... test in world. ;-)
Kaluura Boa
Polygon Project
Join date: 27 Mar 2007
Posts: 194
Total failure
07-13-2008 09:58
Alright... The idea looked promising but in SL-reality, it just doesn't work. There are logical errors in the script but that's not the issue. The real problem is that an avatar standing on a rotating object just doesn't rotate.

I tried hard, I even changed the material to have more friction under the feet of the AV... No use! Period. :-(

Sorry...
Varun Blitz
Registered User
Join date: 22 May 2008
Posts: 62
07-13-2008 22:22
From: Kaluura Boa
Alright... The idea looked promising but in SL-reality, it just doesn't work. There are logical errors in the script but that's not the issue. The real problem is that an avatar standing on a rotating object just doesn't rotate.

I tried hard, I even changed the material to have more friction under the feet of the AV... No use! Period. :-(

Sorry...


no problem !! thanx for all that help. i'll compromise on that, when real life has loads of constraints then why not accept them in second life as well.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
07-15-2008 11:33
You might also try setting the camera position and rotation, then releasing it. I know when you stand up the client turns the avatar to point in the direction of the camera. I'm hoping that when the scripted camera is released, it tries to maintain some of its orientation rather than snapping completely back to where it was before being grabbed, and that the client/server will perform the same logic as when the avatar stands up. It's all wishful thinking so far though; just another thing to try where it otherwise looks hopeless.