Returning vehicle to upright position
|
|
Katah Baryl
Registered User
Join date: 16 Jun 2008
Posts: 13
|
06-16-2008 15:10
This is the first time I've worked with vehicles, and all's going well and making sense so far. I'm a bit stuck though on one part.
The bird turns and dives a lot while being flown, which is what I want, so sometimes when I land it's not in a straight standing position. I'm just looking for a way to tell it to return to a previously set upright orientation, without changing the direction it's currently facing.
In other words, when the rider lands the bird, it should straighten itself out to stand properly while still facing 'forward' in the direction it was facing when it landed.
If it helps any, I intend to make the vehicle no longer physical when it's on the ground to keep it from jittering around or skimming the ground in flightmode (it'll go back to physical when it 'launches'.)
Any suggestions? And thank you in advance!
|
|
ArchTx Edo
Mystic/Artist/Architect
Join date: 13 Feb 2005
Posts: 1,993
|
06-16-2008 17:16
When it lands, call llSetRot() inputing the values of the object when it is properly oriented. I just did something like this in this example: /54/a0/221457/1.html#post2035046
_____________________
 VRchitecture Model Homes at http://slurl.com/secondlife/Shona/60/220/30 http://www.slexchange.com/modules.php?name=Marketplace&MerchantID=2240 http://shop.onrez.com/Archtx_Edo
|
|
Katah Baryl
Registered User
Join date: 16 Jun 2008
Posts: 13
|
06-16-2008 18:10
Thank you, I'll mess around with it and give it a shot 
|
|
Katah Baryl
Registered User
Join date: 16 Jun 2008
Posts: 13
|
06-16-2008 21:00
Hmm. Thus far, I get weird results (rotating at odd angles), as the root prim isn't 0,0,0 (nor can it be at this stage). It seems like the script you showed me is good for returning an object to an exactly positioned state, but not for a position where one axis (z) remains unchanged from where the object ended up, while the other ones are calculated to make the vehicle stand upright.
I'm probably missing something obvious but it feels like I don't have the answer, yet.
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
06-16-2008 21:23
I find it easiest to think about these things in terms of what the object or avatar's local axes (called its reference frame) are doing. I believe what you want is for the horizontal direction of the local x-axis (forward) to remain constant. I'll assume that in the ambiguous case where the x-axis is pointing straight up or down you want the object to pitch to horizontal rather than, say, rolling to horizontal (pitching is the natural way for us to pivot our heads back to horizontal, so I think it "feels" more correct): float EPSILON = 0.001; float PHYSICAL_ROT_STR = 1.0; float PHYSICAL_ROT_TAU = 0.2;
returnToLevel() { rotation rot = llGetRot(); vector localX = llRot2Fwd(rot); vector localY; if (1.0-llFabs(localX.z) < EPSILON) { localY = llRot2Left(rot); localY.z = 0.0; localY = llVecNorm(localY); localX = <localY.y, -localY.x, 0.0>; // localY x z } else { localX.z = 0.0; localX = llVecNorm(localX); localY = <-localX.y, localX.x, 0.0> // z x localX }
rotation newRot = llAxes2Rot(localX, localY, <0.0, 0.0, 1.0>);
if (llGetStatus(STATUS_PHYSICS)) { llRotLookAt(newRot, PHYSICAL_ROT_STR, PHYSICAL_ROT_TAU); } else { llSetRot(newRot); } }
Note: In the physical case you might also want to set a timer and call llStopLookAt(), or at least do it when you're ready for the vehicle to move again. I'll leave that to you.
|
|
Katah Baryl
Registered User
Join date: 16 Jun 2008
Posts: 13
|
06-17-2008 07:33
You rock. Thank you for the help and posting that snippet. I've found that it works great - but for pitching my bird forward on its nose  The root prim is not set at 0,0,0 so I imagine that's the problem. I'm fiddling with it as we speak, but was curious if anyone knew offhand how to adjust for that problem (and I can't reorient the root prim - it has to be fixed in the script.)
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
06-17-2008 10:20
Ah. Okay. Then you're going to need the difference between the root prim's rotation and the "straight forward" vehicle reference frame. If you are using vehicle functions, I believe this might be the same as VEHICLE_REFERENCE_FRAME or its inverse (probably the inverse: ZERO_ROTATION/VEHICLE_REFERENCE_FRAME). Otherwise, point the vehicle so that it is "upright" and "facing" due east. Then touch it with this script inside: default { touch_start(integer nDetected) { rotation rot = llGetRot(); llOwnerSay("rotation BASE_ROT = "+(string)rot); } }
Then replace the line where 'BASE_ROT' is declared with that output in this modified form of the above function: float EPSILON = 0.001; float PHYSICAL_ROT_STR = 1.0; float PHYSICAL_ROT_TAU = 0.2;
rotation BASE_ROT = ZERO_ROTATION;
returnToLevel() { rotation rot = llGetRot()/BASE_ROT; vector localX = llRot2Fwd(rot); vector localY; if (1.0-llFabs(localX.z) < EPSILON) { localY = llRot2Left(rot); localY.z = 0.0; localY = llVecNorm(localY); localX = <localY.y, -localY.x, 0.0>; // localY x z } else { localX.z = 0.0; localX = llVecNorm(localX); localY = <-localX.y, localX.x, 0.0> // z x localX }
rotation newRot = llAxes2Rot(localX, localY, <0.0, 0.0, 1.0>)*BASE_ROT;
if (llGetStatus(STATUS_PHYSICS)) { llRotLookAt(newRot, PHYSICAL_ROT_STR, PHYSICAL_ROT_TAU); } else { llSetRot(newRot); } }
|
|
Katah Baryl
Registered User
Join date: 16 Jun 2008
Posts: 13
|
06-17-2008 15:15
Thanks for the quick responses!
I have applied the llGetRot value to the declaration of BASE_ROT as described (obtained the llGetRot after turning to the east and 'upright'...)
rotation BASE_ROT = <-0.50000, -0.50000, 0.50000, 0.50000>
It works fine if I don't move the vehicle. If I rotate to the side, it flips me upside down or rotates me 90 degrees to the side. I've been fiddling with it to try to make sure I didn't just screw up the code, but it really seems to be the code itself (or my lack of awareness really does extend that far!).
Any thoughts?
|
|
Fiona Branagh
... or her equivalent.
Join date: 1 Feb 2007
Posts: 156
|
06-19-2008 08:55
Just to clarify, which I probably should have done at the start:
The object, when viewed with local rotation, will need to flatten along the X and Z axes, while the Y axis is the one that will need to remain pointing in the direction it's already pointing.
This is due to its non <0,0,0> alignment, which I can't change.
Still fiddling with it myself, so no-one think I won't work through a thing myself - it's just that rotational things are not my forte and this is probably the one thing that's holding up the entire production of my new vehicle. Any and all explanation or suggestion is gratefully accepted, and I'd be happy to pay someone for their time if that is required.
|
|
Katah Baryl
Registered User
Join date: 16 Jun 2008
Posts: 13
|
06-19-2008 08:57
Just to clarify, which I probably should have done at the start:
The object, when viewed with local rotation, will need to flatten along the X and Z axes, while the Y axis is the one that will need to remain pointing in the direction it's already pointing.
This is due to its non <0,0,0> alignment, which I can't change.
Still fiddling with it myself, so no-one think I won't work through a thing myself - it's just that rotational things are not my forte and this is probably the one thing that's holding up the entire production of my new vehicle. Any and all explanation or suggestion is gratefully accepted, and I'd be happy to pay someone for their time if that is required.
|
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
06-19-2008 11:24
Another alternative might be to turn the thing phantom with full buoyancy, then set a strong vertical attractor, which _should_ pay attention to your vehicle reference frame. I'm not sure whether you have that set, but, to have it working with the Y-axis as forward rather than the X-axis, you need, er, llSetVehicleRotationParam(VEHICLE_REFERENCE_FRAME, llEuler2Rot(<0.0, 0.0, PI_BY_TWO>  ) off the top of my head. Then have a timer which waits for a little while until it should have stopped, then turns it non-physical. The phantom and buoyancy would be to prevent unnecessary collisions and let it stay where it is, but I've had some success with having vehicles that have fairly broad skids/wheels/feet and are aligned vertically just fall, then run a regular timer to check whether the magnitude of their current velocity is below a certain amount i.e. they have settled into a stable position.
_____________________
http://ordinalmalaprop.com/forum/ - visit Ordinal's Scripting Colloquium for scripting discussion with actual working BBCode!
http://ordinalmalaprop.com/engine/ - An Engine Fit For My Proceeding, my Aethernet Journal
http://www.flickr.com/groups/slgriefbuild/ - Second Life Griefbuild Digest, pictures of horrible ad griefing and land spam, and the naming of names
|
|
Katah Baryl
Registered User
Join date: 16 Jun 2008
Posts: 13
|
06-19-2008 11:48
After fiddling around with everything I can find in wikis and from suggestions in various related threads, I find myself now tinkering with the simple: rotation rot = llGetRot(); vector fwd = llRot2Fwd(rot); fwd = llVecNorm(<fwd.x, fwd.y, 0.0>  ; llSetRot(llRotBetween(<1.0,0.0,0.0>, fwd)); I understand what is happening in this script which has made me feel comfortable messing with it. It works perfectly in all ways except for pitching forward on the nose. At least it does this in any angle I try, which is perferable to the wrong angles changing depending upon the direction the object is facing, which the previous script was doing to me. I've tinkered with every part of this script in multiple ways (and also the previous script in the thread) and have probably spent about 25+ hours on this so far. Not being educated in the kind of math needed to tweak quaternions, I really feel like I'm spinning my wheels.
|
|
Katah Baryl
Registered User
Join date: 16 Jun 2008
Posts: 13
|
06-19-2008 11:50
Thank you, Ordinal. I'll try that one. I've got the offset already set thankfully, so I'll try the rest.
Part of the issue is that this vehicle is made with sculpties, so a stable standing platform while physical is not possible. My thought so far has been to detect a landing with collisions, and then straighten out the vehicle after turning it phantom and non-physical, but I'll go with anything that works.
|
|
Katah Baryl
Registered User
Join date: 16 Jun 2008
Posts: 13
|
06-19-2008 12:17
Works great in straightening out the side-to-side wobble - but does nothing at all to bring nose-to-tail up in line.
<headdesk>
|
|
Katah Baryl
Registered User
Join date: 16 Jun 2008
Posts: 13
|
06-19-2008 15:38
So I found the solution.
Use the script I indicated already...
Make a tiny prim at rotation <0,0,0> and stick it in the center of the build, attach it as the new root...
Spend hours redoing all the animation and rezzing locators since none of them line up anymore...
And it works.
Hooray.
Thanks in all seriousness however to those who went out of their way to help me in this forum! This is a tricky problem to try to solve.
|