damping to position with non-physical objects
|
|
Aakanaar LaSalle
Registered User
Join date: 1 Sep 2006
Posts: 132
|
09-26-2006 15:46
The llMoveToTarget looks like exactly what I need for an elevator type script, except that it only works with Physical objects. I'd like to get the same effect with a non-physical object, mainly an elevator.
I tried to set the elevator to physical, and it moved to target then flipped upside down, and rolled off to some other location. Obviously this isn't the effect I want.
Would using a timer and llSetPos work? It seems that this might produce a somewhat choppy animation..
Basically I want to move from <113.0, 151.0, 50.45> to <113.0, 151.0, 54.95> in an adjustable amount of time, between 1 and 3 seconds. (I need to fine tune the length of time when I see it in action)
Any Thoughts?
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
09-26-2006 16:03
You can do it, it will be choppy. But you can fake damping with logic like: * While TRUE - If distance between currentPos and finalPos > 1m, move 0.2m towards finalPos - Else if distance between currentPos and finalPos > 0.5m, move 0.1m towards finalPos - Else if distance between currentPos and finalPos > 0.1m, move 0.05m towards finalPos - Else setPos to finalPos (you're within 0.1m of finalPos) and break out of the loop ... or something like that. You need to be careful of how you calculate the value for a setPos. If you use getPos + x, you run the risk of getting close to the destination, and then your math puts you at a point past your destination, so you end up moving past and then jerking back, which doesn't look good. If things go really wrong, you could end up in an endless loop at the end, always jerking back and forth, because your movement step is too big compared to your distance check. So, "while TRUE" loops are a bad idea  But this should give you some idea of how to simulate damping. You could use multiple scripts to smooth out the built-in 0.2s delay in llSetPos. Look for code Jesrad Seraph has posted about non-physical movement in the forums. You can pull the basic idea from that, which is to use multiple scripts and stagger them in time a bit.
|
|
Aakanaar LaSalle
Registered User
Join date: 1 Sep 2006
Posts: 132
|
09-26-2006 17:47
bah.. yea.. using the llSetPos is really choppy, i need something smoother.. but is there then a way to keep a physical object from falling back down, or rotating in some odd direction or doing all kinds of wierd stuff other than to move Up and Down when requested?
bah..s cratch that.. no matter what I do, if i set it physical, it falls over, rolls around.. even with set hover height, i try to walk onto it and it floats off towards a sim border
I have to use this non-physical object.. but that leaves me stuck with choppy motion..
Is there nothing that can be done?
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
09-27-2006 10:15
Depends on what the object needs to do. You could make it phantom, that would avoid collisions with other objects. But then it can't carry people, it'll go through objects, and so on. So whether that works or not depends on what the object is. You could try the llSetStatus(STATUS_ROTATE_X, FALSE) stuff to try and prevent it from rotating around certain axes. I don't remember the conditions under which those work and don't work. Try setting buoyancy to 1 right after you set it to physical, that could keep the object 'afloat', depending on its mass.
If you want to get really creative, try turning teh object into a vehicle, and then you get many more parameters to play with. There's a 'vertical attraction' that you can set that will prevent it from falling over. Again, I haven't played with this too much. AFAIK, once you turn something into a vehicle, it's recommended you not use the MoveToTarget calls on it, so you'll have to use the vehicle motor functions to move the object around.
|
|
Aakanaar LaSalle
Registered User
Join date: 1 Sep 2006
Posts: 132
|
09-27-2006 17:11
Basically I'm trying to create an elevator.. that's all
I tried stairs.. had a beautiful set created.. only cost me 35 prims.. too many on a 512sq meter plot..
Teleporter would work, but while this is a virtual world, I'd like to keep it realistic.. so If i can't go stairs, then an elevator would do nicely.
I tried doing something where I set the STATUS_PHYSICS to TRUE, used llMoveToTarget and once at_target() set the STATUS_PHYSICS to false.. unfortunatly it would stop just prior to the target and never turn the physics back off.
I checked the llGetEnergy() function but it seems it wasn't an energy problem.. though the ROTATE_X, ROTATE_Y, and ROTATE_Z all set to false did prevent the object from going all over..
There was also the problem of when I set it to Physical, the short delay between that and the call to llMoveToTarget would cause the object to drop half a foot quickly then start going up.. And at the other end, between the llStopMoveToTarget and setting it non-physical it would drop a half foot at that end too, whenever i even made it all the way to the target. which was seldom.
I'm just going to have to look around and see if i can find someone's script for an elevator that DOES work.
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
09-27-2006 17:24
From: someone unfortunatly it would stop just prior to the target and never turn the physics back off. That's controlled by the error margin you specify in the llTarget function, right? So you can make it arbitrarily precise (or imprecise). also, you could get it very close with physics, then turn physics off and do a non-physical llSetPos call to precisely position the elevator in its final position. If you get it close enough, the final non-physics call won't cause any perceptible jerk, and you'll ensure that the elevator ends up in the right place. From: someone There was also the problem of when I set it to Physical, the short delay between that and the call to llMoveToTarget would cause the object to drop half a foot quickly then start going up.. I know I've faced this one... did you try setting buoyancy to 1.0 *before* you turn on physics? I don't remember how I fixed this, but I did.
|
|
Landing Normandy
Proposing 4968
Join date: 28 Nov 2005
Posts: 240
|
09-27-2006 17:57
Funny you're having this problem, I need to make a non-physical elevator too for a helipad. I have a lift made of two objects that just won't work, and the platform if made of just one prim, never resets to the same spot, so when I tried the two objects running individually they never lined up ever again...
I can't believe there is no way to make a non-physical lift that will lift who/whatever is stood on it...
|
|
Aakanaar LaSalle
Registered User
Join date: 1 Sep 2006
Posts: 132
|
09-27-2006 21:04
From: someone That's controlled by the error margin you specify in the llTarget function, right? So you can make it arbitrarily precise (or imprecise). also, you could get it very close with physics, then turn physics off and do a non-physical llSetPos call to precisely position the elevator in its final position. If you get it close enough, the final non-physics call won't cause any perceptible jerk, and you'll ensure that the elevator ends up in the right place.
I had set that range to 0.1, 0.01, even 0.05, but the closest it would get is about 0.2m away from the target. This is still too far to jump it with that llSetPos (which did cross my mind).. It would still jerk at the end, and likely anyone riding it would then fall. Also, with the range set to 0.1 since it never got within that 0.1 from target, it never triggered the at_target event.. which is what I was saying before. I first started off with a cylinder sized to 4.0, 4.0, 0.1 with path cut at 0.5 to 1.0. It dawned on me the hidden part of the cylinder was hitting the next floor (actually was about 0.1 away from that second floor.) So I changed it to a cube, 4.0, 2.0, 0.1, removed the path cut (0.0, 1.0) and set to not overlap the floor.. but still same problem. I read somewhere that the prim needs to be 0.1m away from another prim to avoid collision (this is in the wiki, i think under llMoveToTarget) so I moved it 0.15 away, but still the same problem. It's like it's colliding with that other prim. From: someone I know I've faced this one... did you try setting buoyancy to 1.0 *before* you turn on physics? I don't remember how I fixed this, but I did.
I hadn't tried this, I may try it when I next attempt the elevator. Though I wonder how the weight of the riders will effect that buoyancy.. From: someone I can't believe there is no way to make a non-physical lift that will lift who/whatever is stood on it...
It can be done, using llSetPos and a while loop or a timer to step it up a small amount at a time. However the llSetPos causes a 0.2 second sleep after each call, and it ends up being choppy and not a smooth animation at all. Usually when trying to do that with a rider, the rider ends up falling through it. At least it did with me.
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
09-28-2006 10:13
From: someone I had set that range to 0.1, 0.01, even 0.05, but the closest it would get is about 0.2m away from the target. Weird. You're right, that'll cause a jump at the end, and could throw the person off too. I also wonder if 0.1 is too small for physics. Like I keep saying, I haven't tested the limits of the physics engine  But I do know it has trouble handling small objects, and maybe even objects with small dimensions. Have you tried it with a thicker platform? Just to see if it behaves differently? I know some people build physical objects and put a large transparent prim around it, say a sphere or a cube, just so the physics engine has an easier time calculating collisions. Obviously that won't work for you, but I do believe the engine has problems with small objects or odd shapes. And I think there were discussions on implementing a physical elevator on this forum a while back. Not sure if those threads gave you any useful ideas. Sorry, I'm out of ideas now 
|
|
Aakanaar LaSalle
Registered User
Join date: 1 Sep 2006
Posts: 132
|
09-28-2006 18:02
Ok, i finally manage to come up with something that kinda works.. To begin with.. when using half of a cylinder (using the path cut) the missing half still counts in collisions.. So I can't do a half cylinder elevator off the edge of a square.. 'tis ok, i'll manage with a full round cylinder somewhere else. Also, I finally got to reach the target by adding an overshoot to the MoveToTarget.. then use the at_target event to detect when it reached it's final place. Adding a buoyancy does seem to help prevent it falling when not moving too. The bottom floor, the top edge of the cube is at 50.500 meters regional.. I was originally setting this object at 50.55 regional.. as it's 0.1 high, so center mass is 0.05 higher. I now have it sitting at 50.60 thus giving it about 0.05 space between the floor and the cylinder. Even then, the closest I can get back to the original position is 50.648 which is 0.048 off. I had to adjust the at_target to trigger within 0.05 from targetpos to compensate. (this is not counting the overshoot which doesn't figgure in this. Here's what I have. vector vctOrigin; vector vctOffset = <0.0, 0.0, 4.5>; vector vctOverShoot = <0.0, 0.0, 0.75>; float fltTime = 3.0; float fltRange = 0.2; float fltAtTarget = 0.05;
default { state_entry() { integer STATUS_ROTATE = STATUS_ROTATE_X | STATUS_ROTATE_Y | STATUS_ROTATE_Z; llSetStatus(STATUS_ROTATE, FALSE); llSetStatus(STATUS_BLOCK_GRAB, TRUE); llSetBuoyancy(1.0); vctOrigin = llGetPos(); llListen(0, "", llGetOwner(), ""); } listen(integer c, string n, key id, string msg) { if (llToLower(msg) == "reset") { llStopMoveToTarget(); llSetStatus(STATUS_PHYSICS, FALSE); llSetPos(vctOrigin); llSay(0, "Elevator reset!"); llResetScript(); } if (llToLower(msg) == "f1") { vector vctNew = vctOrigin - vctOverShoot; llSetStatus(STATUS_PHYSICS, TRUE); llMoveToTarget(vctNew, fltTime); llTarget(vctOrigin, fltRange); } if (llToLower(msg) == "f2") { vector vctNew = vctOrigin + vctOffset + vctOverShoot; llSetStatus(STATUS_PHYSICS, TRUE); llMoveToTarget(vctNew, fltTime); llTarget(vctNew - vctOverShoot, fltRange); } } at_target(integer tnum, vector tpos, vector opos) { if (llVecDist(tpos, opos) <= fltAtTarget) { llStopMoveToTarget(); llSetStatus(STATUS_PHYSICS, FALSE); llSay(0, "Target Reached."); llTargetRemove(tnum); } } }
It works.. barely.. My next test will be how close to any side i can get with other prims without it messing up on me.
|