Slowing down flight?
|
|
Maya Remblai
The one with pink hair.
Join date: 25 Mar 2006
Posts: 434
|
03-03-2008 16:30
Here's a new one: Is it possible to SLOW DOWN your flight speed? A friend showed me a nice mermaid tail, and there are lots of nice undersea sims, but you're stuck either using the Swimmer or flying. The Swimmer is great if you're a humanoid, but if you're of the aquatic persuasion you'll look silly bobbing at the surface. So I want a way to slow down flight to swimming speed so the mermaids aren't stuck to the ground using run over rides. So far my attempts have only resulted in either no affect at all or I get flung backwards half way across the sim. Any ideas?
|
|
Lightwave Valkyrie
Registered User
Join date: 30 Jan 2004
Posts: 666
|
03-03-2008 16:41
try pushing back? llApplyImpulse(<0,0,-5> * llGetMass(), FALSE);
_____________________
L$ is the root of all evil videos work! thanks SL 
|
|
Viktoria Dovgal
…
Join date: 29 Jul 2007
Posts: 3,593
|
03-03-2008 16:46
Before rolling your own, you might give Mystitool's flight assist a try. The 1L version includes the fight script, and it has a "slow" setting that might work for you.
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
03-03-2008 17:59
This should be a decently close approximation of air/water resistence, though I don't know how well it will interact with SL's propulsion for normal movement. Heh. Probably do this periodically with a pretty quick timer or something. // Play with the following two constant values (picked out of my --- and untested for this demo) float LINEAR_DAMPING = 0.2; // N / (m/s) float QUADRATIC_DAMPING = 0.5; // N / (m/s)^2
vector v = llGetVel(); vector u = LINEAR_DAMPING+QUADRATIC_DAMPING*v; vector force = -v * u; llSetForce(force, FALSE);
EDIT: You may want to remove the force if velocity is below a certain threshold, and/or if no control keys are being held. May also want to put a maximum on the value of the force if the timer isn't fast enough to keep it from going bonkers when controls or directions change.
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
03-03-2008 18:08
You could aso try making the above a relative force, and see which tends to work best with normal user movement: // Play with the following two constant values (picked out of my --- and untested for this demo) float LINEAR_DAMPING = 0.2; // N / (m/s) float QUADRATIC_DAMPING = 0.5; // N / (m/s)^2
rotation rot = llGetRot(); vector v = llGetVel()/rot; vector u = LINEAR_DAMPING+QUADRATIC_DAMPING*v; vector force = -v * u; llSetForce(force, TRUE);
|
|
Tyken Hightower
Automagical
Join date: 15 Feb 2006
Posts: 472
|
03-03-2008 19:54
From: Hewee Zetkin You could aso try making the above a relative force, and see which tends to work best with normal user movement: // Play with the following two constant values (picked out of my --- and untested for this demo) float LINEAR_DAMPING = 0.2; // N / (m/s) float QUADRATIC_DAMPING = 0.5; // N / (m/s)^2
rotation rot = llGetRot(); vector v = llGetVel()/rot; vector u = LINEAR_DAMPING+QUADRATIC_DAMPING*v; vector force = -v * u; llSetForce(force, TRUE);
Does this work? Wouldn't you need to have this running on a loop as well? I am of the impression that the force vector from llSetForce will stay in the same direction (either global or local). Personally I'd just use llApplyImpulse with a small negative factor of choice multiplied by llGetVel, but of course, it would need to be constantly applied as well. Edit: Well, nevermind, I missed your edit. But I'd suggest llApplyImpulse over llSetForce mainly because llSetForce would end up pushing more than you need, I think..
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
03-03-2008 22:35
llApplyImpulse()--if the attachment has enough energy--will instantaneously change your velocity. So, what should you change the velocity to? Just put a maximum cap on avatar speed? I suppose that could work. I like the water resistance type physical resistance myself, but probably what it'll come down to in the end is what gives the most aesthetically pleasing user experience anyway. So try both. 
|
|
Tyken Hightower
Automagical
Join date: 15 Feb 2006
Posts: 472
|
03-04-2008 00:10
From: Hewee Zetkin llApplyImpulse()--if the attachment has enough energy--will instantaneously change your velocity. So, what should you change the velocity to? Just put a maximum cap on avatar speed? I suppose that could work. I like the water resistance type physical resistance myself, but probably what it'll come down to in the end is what gives the most aesthetically pleasing user experience anyway. So try both.  Ah, well, it's thrust, really. You can instantaneously stop by using llApplyImpulse with a value of -0.9 * llGetMass * llGetVel, but with a much smaller constant at the front there, it'll actually be more like the resistance of a viscous medium.
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
03-04-2008 00:46
From: Tyken Hightower Ah, well, it's thrust, really. I agree with the rest of your assessment, but this isn't QUITE the same concept you would call thrust in physics, and I must digress slightly to bring out my inner physicist geek. It might be useful in helping to think about/solve a problem in an LSL context (I personally find it useful in most cases, but sometimes you do run into the limitations of the physics engine/platform...), or it might not. Feel free to skip if you don't really care. Thrust is really a force, or change in momentum over TIME (dp/dt). Typically it is used to refer to a force generated by a process such as the expulsion of fuel, but it would still refer to a rate, not a net change. I guess in combination with a timer event you could sort of call the whole construct thrust, but a single call to llApplyImpulse() can really only be called...well, an impulse. Impulse is defined as a difference in momentum. As in, subtract momentum after an event (such as the function call) from momentum before the event (p2-p1). In the real world, it may be possible to measure impulse when the forces involved in an event that contribute to that impulse are not easily measureable. A big example is when you have a collision, where many forces (due to friction and structural deformation) act on the objects involved, and typically act over a very short period of time. You can't quite have a finite instantaneous impulse until you get to the quantum level because that would require infinite force, but when the timeframe is small enough, it's often easier to treat it as instantaneous in many ways. From a practical point of view, llSetForce() continues to influence the avatar between timer events (function calls). I suspect (non-rotational) control events handled according to the system defaults really cause forces to be applied to the avatar, and my hope is that llSetForce() would interact with these forces pretty nicely--especially when corrected as often as possible--but I could be wrong. llApplyImpulse() creates an "instantaneous" change in momentum (and thus velocity) from the perspective of LSL. You can even predict with pretty good accuracy what the difference in velocity will be in the next server frame, as you indicate by your example of stopping with an applied impulse.
|
|
Maya Remblai
The one with pink hair.
Join date: 25 Mar 2006
Posts: 434
|
03-04-2008 01:38
From: Hewee Zetkin You could aso try making the above a relative force, and see which tends to work best with normal user movement: // Play with the following two constant values (picked out of my --- and untested for this demo) float LINEAR_DAMPING = 0.2; // N / (m/s) float QUADRATIC_DAMPING = 0.5; // N / (m/s)^2
rotation rot = llGetRot(); vector v = llGetVel()/rot; vector u = LINEAR_DAMPING+QUADRATIC_DAMPING*v; vector force = -v * u; llSetForce(force, TRUE);
Both of these result in a type mismatch error at vector u = LINEAR_DAMPING+QUADRATIC_DAMPING*v;
|
|
Dylan Rickenbacker
Animator
Join date: 11 Oct 2006
Posts: 365
|
03-04-2008 02:50
BTW, there are AOs for merpeople, replacing the walk with a merfolk-like swimming animation. Most places that sell mer-tails have them.
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
03-04-2008 08:41
Oops. Sorry. That should've been the MAGNITUDE of v: Absolute: // Play with the following two constant values (picked out of my --- and untested for this demo) float LINEAR_DAMPING = 0.2; // N / (m/s) float QUADRATIC_DAMPING = 0.5; // N / (m/s)^2
vector v = llGetVel(); vector u = LINEAR_DAMPING+QUADRATIC_DAMPING*llVecMag(v); vector force = -v * u; llSetForce(force, FALSE);
Relative: // Play with the following two constant values (picked out of my --- and untested for this demo) float LINEAR_DAMPING = 0.2; // N / (m/s) float QUADRATIC_DAMPING = 0.5; // N / (m/s)^2
rotation rot = llGetRot(); vector v = llGetVel()/rot; vector u = LINEAR_DAMPING+QUADRATIC_DAMPING*llVecMag(v); vector force = -v * u; llSetForce(force, TRUE);
|
|
Maya Remblai
The one with pink hair.
Join date: 25 Mar 2006
Posts: 434
|
03-05-2008 13:23
That still causes the same error Hewee. I'd correct it myself but I have little experience with physics scripts and I'm bad at math anyway ;P I did get a script to slow down flight fairly well, but there's a problem with it: When I turned, I'd slow down more, eventually coming to a complete stop until I let off all keys. Thanks for the input thus far 
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
03-05-2008 14:47
My apologies. I should've qualified as I usually do that it hadn't been compiled and might need a little fixing. Neither of the fixes may have been completely obvious though. Here is a fixed version that DOES compile: // Play with the following two constant values (picked out of my --- and untested for this demo) float LINEAR_DAMPING = 0.2; // N / (m/s) float QUADRATIC_DAMPING = 0.5; // N / (m/s)^2
rotation rot = llGetRot(); vector v = llGetVel()/rot; float u = LINEAR_DAMPING+QUADRATIC_DAMPING*llVecMag(v); vector force = -v * u; llSetForce(force, TRUE);
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
03-05-2008 14:51
And here's an example script that contains it. I've mucked with the values with a velocity readout up (Client -> HUD Info -> Velocity) and it seems pretty smooth with the 0.05 second timer. The constants as given reduce flight spee from about 14 to about 8. You could increase the constants to pull it down even further, as that's an awfully fast swim (this IS SL though). Note that you might want to use more conditions to turn it on (such as being below water height, or only when flying, or only while movement controls are being applied--might even replace the timer with the control event handler). Also, for underwater movement you also may want to turn on buoyancy, or add your own buoyancy force equal to <0.0, 0.0, 9.8*llGetMass()> to the force exerted by the script. // Play with the following two constant values (picked out of my --- and untested for this demo) float LINEAR_DAMPING = 0.15; // N / (m/s) float QUADRATIC_DAMPING = 0.4; // N / (m/s)^2 integer RELATIVE = FALSE;
float TIMER_PERIOD = 0.05;
default { state_entry() { if (llGetAttached()) { state running; } } attach(key id) { if (id != NULL_KEY) { state running; } } }
state running { state_entry() { llSetTimerEvent(TIMER_PERIOD); } state_exit() { llSetTimerEvent(0.0); } on_rez(integer startParam) { if (!llGetAttached()) { state default; } } attach(key id) { if (id == NULL_KEY) { llSetForce(ZERO_VECTOR, FALSE); state default; } } timer() { vector v; if (RELATIVE) { rotation rot = llGetRot(); v = llGetVel()/rot; } else { v = llGetVel(); } float u = LINEAR_DAMPING+QUADRATIC_DAMPING*llVecMag(v); vector force = -v * u; llSetForce(force, RELATIVE); } }
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
03-05-2008 15:04
(BTW, remember that you have to detach and attach any attachment objects that affect avatar movement in order to get the scripts to work after compile/addition. That's one that I always find easy to forget.)
|