llMoveToTarget()-like movement when cant set object as physical?
|
|
Naryu Yue
Interrupted?
Join date: 23 Jul 2007
Posts: 15
|
08-24-2007 11:32
ok... so i am making a boat, right? and i want people to ride it, ok? the boat will go on a pre-defined track, people wont steer it. Its a big boat, supposed to be for a lot of people. Unfortunally, the number of prims has gone above 31 >_> now i cant set that *&%$#@ to physical.
Im trying to make the boat move along the track using llRotLookAt and llSetPos with some success, BUT the *&%@#@$# wont move smoothly, see? it goes on with grotesque steps and jumps...
is there a llMoveToTarget-like function that will actually work on non-physicals?]
*note* modifying the values for strength and damping on llRotLookoAt wont do a thing. it just always rotates and one goddamn speed (of light)... causing it to move instantly yuck!!
|
|
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
|
08-24-2007 12:13
I think you want lots of small moves.
Since llSetPos() has a 0.2 second delay, you need some way to trick around that. One approach is to use a list of moves in llSetPrimParams() (I think that is the name).
Another way is to use multiple scripts. This is trickier. Imagine this case. Two scripts. On is responsible for moving on even tenths of seconds, and another is responsible for moving on odd tenths of seconds. Thereby giving a move every tenth of a second.
With 20 such scripts, you can move every .01 seconds, which is pretty smooth.
|
|
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
|
08-24-2007 12:23
From: Lee Ponzu One approach is to use a list of moves in llSetPrimParams() (I think that is the name). I've never really gotten satisfyingly smooth motion from multiple moves in the llSetPrimitiveParams rule list; it seems to behave like it does with warpPos, and batch everything into one update. In my experience, the slave script approach works better--but of course it's a non-trivial source of lag, especially moving around a large non-phantom assembly of prims.
|
|
Naryu Yue
Interrupted?
Join date: 23 Jul 2007
Posts: 15
|
08-24-2007 13:05
well ... what i got to so far is exactly like: rotation getRotToPointAxisAt(vector axis, vector target) { return llGetRot() * llRotBetween(llVecNorm(axis * llGetRot()), llVecNorm(target - llGetPos())); } llRotLookAt(getRotToPointAxisAt(AXIS_FWD, target), strength, damping); while (llVecDist(llGetPos(), target) > 0.001) { llSetPos(llGetPos()+<0.1,0,0>  ; } see? thats the smoother movement i could get, and it looks a bit "jumpy" if you know what I mean... thing is... i COULD live with that sorta "jumpiness" (not so bad really, you see it when you zoom out a lot) IF the llRoTLookAt line would work before the damned while loop. if i remove the while loop, the boat rotates, fine. then after rotated, id like to slide it in some direction, k? x axis in that case. BUT if i use the damn while statement to slide the boat, it wont rotate anymore its driving me crazy @_@ i was thinking of making small rotations and drag the boar a bit in the x direction, then rotate a bit more, drag a bit more... until the damn thing reaches a target. and that point, it would assume a new target, kinda like the multiple scripts approach, see?]] edit: its behaving oddly... it DOES rotates, but after a time. which doesnt seem to be affected by damping, it just becomes fully rotated at some point. might be lagging.
|
|
Senuka Harbinger
A-Life, one bit at a time
Join date: 24 Oct 2005
Posts: 491
|
08-24-2007 13:32
what you could do is tear apart a non-physical vehicle script, and then have your own AI control the acceleration/deceleration parameters, as well as rotation towards and/or away from your target. I posted a list of simple logic gates a while back that will help your AI tell where the target is relative to itself (search for "logic gates" should turn it up), and that should provide a solid platform from which you can build your AI to drive the object.
typically, I'd have the AI in it's own script, driven on a very fast timer loop, which would issue out the commands via link messages to the actual vehicle script, which then would substitute those commands for control input and would behave just as if a person were driving it. It's a fairly simple concept and should be fast to lay out such a frame work. it's tweaking the AI's responses which will take some work.
This is more involving than a simple stepped non-physical movement script, but the end results will be much more believable and worth the effort.
_____________________
My SLExchange shopTypos are forgiven; desecrating the english language with reckless abandon and necrophilic acts is not. The function is working perfectly fine. It's just not working the way you wanted it to work.
|
|
Naryu Yue
Interrupted?
Join date: 23 Jul 2007
Posts: 15
|
08-27-2007 07:35
ive been researching onto this and i actually found the Jesrad Seraph's non-physical flying vehicle and it seems easy enough to substitute the controls based on keys in Jesrad's script by a sequence of commands, aka my own AI. It does produce the smooth movement I was aiming to get, but theres stuff in it that seems beyond me lol... I "can" just copy-paste stuff and have it working in no time, but i dont like that. id rather try to understand whats being done. so far, i noticed that the moving/rotating part is not that different from waht i was doing, it simply uses repetitions of small movements that last as long as you press a movement key. But the mothod used is beyond me. I mean... max_vel = (float)((string)id); llSleep(0.05 * (integer)llGetSubString(llGetScriptName(), -1, -1));
while(TRUE) { llSetPos(max_vel * (llGetColor(hidden_face) + veloff) + llGetPos()); llSetPos(max_vel * (llGetColor(hidden_face) + veloff) + llGetPos()); llSetPos(max_vel * (llGetColor(hidden_face) + veloff) + llGetPos()); llSetPos(max_vel * (llGetColor(hidden_face) + veloff) + llGetPos()); llSetPos(max_vel * (llGetColor(hidden_face) + veloff) + llGetPos()); }
- what does the scriptname have to do with the freaking time it will be sleeping? - its a damn loop-forever while-loop... why does it have 5 lines exactly alike there? jeez... - when does the damn thing figures you stopped pressing the key and exists a true-forver loop? - what does the face color have to do with the position it will move to? its obviously using that property to control something that has nothing to do with color itself.... its probably using that to transport values from script to script... but that still doesnt make sense to me that we need those 5 lines (that are all the same line) in that loop; and doesnt make sense that something will ever get out that loop...
|
|
Kenn Nilsson
AeonVox
Join date: 24 May 2005
Posts: 897
|
08-27-2007 08:56
Without seeing the entirety of the script, it's hard to guess at exactly what the answers to most of those questions are...however:
--using the color of a hidden side of a prim is a very easy to way to grab a vector position.
--it's possible that the sleep-time is being stored in the script name.
--I'm not sure...but...it's possible the five repeated lines are there just in case your total desired jump in movement is more than 10 meters?
--It's possible that the loop never exits, but rather that the color of the box changes such that the movement rate is 0.0 when you stop pressing a button.
_____________________
--AeonVox--Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms chasing ghosts, eating magic pills, and listening to repetitive, addictive, electronic music.
|
|
Shadow Subagja
Registered User
Join date: 29 Apr 2007
Posts: 354
|
08-27-2007 10:20
That script is using a lot of performance hacks to make a vehicle more responsive. It is using multiple calls and a loop to handle movements as fast as possible. The face color is used to circumvent message passing, especially in laggy sims (like sandboxes). It contains a vector, consider the color there to be the target position vector or some such. There are many threads on this sort of thing, using prims for storage and shared data. His vehicle probably had a lot of parallel movement scripts as well, to further increase responsiveness. Basically its working its little butt off and probably using a fair chunk of sim resources to try and get updates fast enough to get something that even resembles physical movement. From: Naryu Yue ive been researching onto this and i actually found the Jesrad Seraph's non-physical flying vehicle and it seems easy enough to substitute the controls based on keys in Jesrad's script by a sequence of commands, aka my own AI. It does produce the smooth movement I was aiming to get, but theres stuff in it that seems beyond me lol... I "can" just copy-paste stuff and have it working in no time, but i dont like that. id rather try to understand whats being done. so far, i noticed that the moving/rotating part is not that different from waht i was doing, it simply uses repetitions of small movements that last as long as you press a movement key. But the mothod used is beyond me. I mean... max_vel = (float)((string)id); llSleep(0.05 * (integer)llGetSubString(llGetScriptName(), -1, -1));
while(TRUE) { llSetPos(max_vel * (llGetColor(hidden_face) + veloff) + llGetPos()); llSetPos(max_vel * (llGetColor(hidden_face) + veloff) + llGetPos()); llSetPos(max_vel * (llGetColor(hidden_face) + veloff) + llGetPos()); llSetPos(max_vel * (llGetColor(hidden_face) + veloff) + llGetPos()); llSetPos(max_vel * (llGetColor(hidden_face) + veloff) + llGetPos()); }
- what does the scriptname have to do with the freaking time it will be sleeping? - its a damn loop-forever while-loop... why does it have 5 lines exactly alike there? jeez... - when does the damn thing figures you stopped pressing the key and exists a true-forver loop? - what does the face color have to do with the position it will move to? its obviously using that property to control something that has nothing to do with color itself.... its probably using that to transport values from script to script... but that still doesnt make sense to me that we need those 5 lines (that are all the same line) in that loop; and doesnt make sense that something will ever get out that loop...
|
|
Tiarnalalon Sismondi
Registered User
Join date: 1 Jun 2006
Posts: 402
|
08-27-2007 11:02
Essentially this is how the non-physical flight script reads the flight changes to the secondary scripts using the color and transparency of a face # of the root prim they are in. At the top of the script it has the integer variable so that you can specify which face it should use. if you set everything up, you can actually watch this neat little show if you use a prim you can see and a face that is not hidden. The control script just changes these values while the secondary scripts read and interpret those for the movement/rotation. The control script resets these at specific points to keep them sync'd up (let's face it, timers kinda suck when it comes to lag and no 2 timers are gonna keep the same time 90% of the time...the reset helps get them back on track and keep the movement smooth)
Which, to the response to the post directly before mine that I didn't see until I had posted....
From what I can tell the resources don't tend to be as bad as one would think. Of course it mainly depends on how many secondary scripts you use to get the smoothness you desire, and what else you have going on. When I used to have Admin tools at group sim, I had monitored a non-physical ship on the script time and it would spike above our physical ships...but normally did not pass 2.0 other than the occasional spike. Mouselook seemed to be the worst, but then again there's more vector data that's going to be processed from that.
|
|
Boss Spectre
Registered User
Join date: 5 Sep 2005
Posts: 229
|
08-28-2007 02:02
From: Naryu Yue ...its obviously using that property to control something that has nothing to do with color itself.... its probably using that to transport values from script to script... but that still doesnt make sense to me that we need those 5 lines (that are all the same line) in that loop; and doesnt make sense that something will ever get out that loop... It gets out of that loop when the control script resets the movement script via llResetOtherScript().
|
|
Naryu Yue
Interrupted?
Join date: 23 Jul 2007
Posts: 15
|
08-28-2007 13:23
I see I see ... all those answers made this whole thing make sense... ^^ It was actually very clever in all those ways to parse values and all... Just to not let this be unfished like this... I finally managed to finish the boat, and its working fine \o/ Unfortunally I chose not to use that code I posted before, specially cuz of the sim-resources issue, and I decided I dont need that much accuracy anyway. I figured myself a way to both smoothen out the movement of my boat, and make sure I could control it remotely, as it was intended to be a guided-tour sorta thingy. in the end I made it using 2 separate scripts, both in the boat: - one to make the tour start when someone sits on the boat and control the tour itself, by issuing the remote commands - another to move the boat around and wait for the commands I made a command-queue to receive and store the commands to be timely flushed and executed, and made it so it would keep going in some direction until a command to change direction or stop has come. The result is the code below, but i wont put here the commander script, cuz its very poluted by sitting controls and other ugly stuff lol. I tried to use the FIFO socket approach, in which an interruption is raised every time theres data in the socket. //Smooth Movement Script by Naryu Yue //Feel free to use, modify and distribute as long as you keep my name in credits
list commands = ["forward","back","left","right","stop"]; list queue;
string currCommand;
float delay = 0.1; float strength = 10; float damping = 0.1;
vector AXIS_UP = <0,0,1>; vector AXIS_LEFT = <0,1,0>; vector AXIS_RIGHT = <0,-1,0>; vector AXIS_FWD = <1,0,0>; vector AXIS_BACK = <-1,0,0>;
queueCommand(string command) { queue = queue + [command]; }
string flushCommand() { string Command = llList2String(queue, 0); queue = llDeleteSubList(queue, 0,0); if (Command == "forward") forward(); if (Command == "back") back(); if (Command == "left") left(); if (Command == "right") right(); if (Command == "stop") stop(); Command = llList2String(queue, llGetListLength(queue)-1); return Command; }
forward() { llSetPos(llGetPos()+((0.1*AXIS_FWD)*llGetRot())); }
back() { llSetPos(llGetPos()+((0.1*AXIS_BACK)*llGetRot())); }
left() { llSetRot(llGetRot()*llEuler2Rot(DEG_TO_RAD*<0,0,1>)); llSetPos(llGetPos()+((0.1*AXIS_FWD)*llGetRot()*llAxisAngle2Rot(AXIS_UP, DEG_TO_RAD*10))); }
right() { llSetRot(llGetRot()*llEuler2Rot(DEG_TO_RAD*<0,0,-1>)); llSetPos(llGetPos()+((0.1*AXIS_FWD)*llGetRot()*llAxisAngle2Rot(AXIS_UP, DEG_TO_RAD*10))); }
stop() { llSay(0,"stopping all movement"); queue = []; }
rotation getRotToPointAxisAt(vector axis, vector target) { return llGetRot() * llRotBetween(llVecNorm(axis * llGetRot()), llVecNorm(target - llGetPos())); }
default { state_entry() { llListen(90,"",NULL_KEY,""); llSetTimerEvent(delay); } listen(integer channel, string name, key who, string msg) { integer index = llListFindList(commands, [msg]); if (index != -1) { queueCommand(msg); } else { llSay(0,msg+": Invalid Command"); } } timer() { string lastCommand = flushCommand(); queueCommand(lastCommand); } }
|