|
Zuzu Fassbinder
Little Miss No Tomorrow
Join date: 17 Sep 2004
Posts: 2,048
|
08-29-2005 09:21
I wrote a script to make a fish swim around in a tank using a random walk, but I had to resort to making the object (fish) physical in order to get good smooth turning and movement. At first I tried just using rotates and move-to, but the motions were too fast. I tried slowing them down by subdividing the motion into small steps, but that was jerky and used a lot of waits and calls to the move command, which I wasn't happy about.
Any ideas? I searched thru the Wiki site, but couldnt come up with anything that fit.
Zuzu
_____________________
From: Bud I don't want no commies in my car. No Christians either.
|
|
Angus Kuhr
Dwarf with a Hammer
Join date: 17 Jul 2005
Posts: 43
|
08-29-2005 21:55
I don't think you could do that with non-physical prims.
I do think, however, that particles could achieve that effect if you tinker with the right.
|
|
Zuzu Fassbinder
Little Miss No Tomorrow
Join date: 17 Sep 2004
Posts: 2,048
|
08-31-2005 09:25
hmm, i've done stuff like that with particles before, but I forsee two problems: -maximum life on the particle -my object is not just a texture My first attempt was very similar to the move and turn scripts in this post but I had trouble making the motion smooth. But hearing of the success with the vehicle script, I may take another stab at it. My real motivation is to produce as little lag as possible from my fishtank or koi pond
_____________________
From: Bud I don't want no commies in my car. No Christians either.
|
|
Dustin Widget
Script Monkey for hire
Join date: 15 Feb 2006
Posts: 101
|
03-09-2006 23:30
i really need a look into this as well
|
|
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
|
03-10-2006 03:33
I've seen people use llApplyImpulse or llApplyImpulseAndTorque for this too - making sure the numbers are small enough that the movement is realistically slow.
I think llMoveToTarget() with suitably large tau values (5s+) might also work, fast rotations work reasonably well with most fish I think?
Non-physical movement can, with llTargetOmega(), produce reasonably smooth rotations (and that can include rotations in planes other than xy, xz or yz) but translations in non-physical movement will always be jerky since they are, in essence, teleporting the object around.
|
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
03-10-2006 04:10
The smooth movement that I've had with small physical objects has been achieved using timers that set llSetForce with a drag parameter. You can set the drag coeefficient and the force to keep the object at a desired constant velocity. e.g. for an object that you want moving at a fixed target velocity - and this is just off the top of my head here so might have a bug or two but illustrates the point... vector gTargetVel = <1.0, 0.0, 0.0>; float gDragC = 0.0; float gAcceln = 1.0; float gMass = 0.0; vector gForce = ZERO_VECTOR;
default { state_entry() { gMass = llGetMass(); gDragC = 1 / llPow(llVecMag(gTargetVel), 2); gForce = (llVecNorm(gTargetVel) * gAcceln + <0.0, 0.0, 9.8>) * gMass; llSetTimerEvent(0.1); }
timer() { vector vel = llGetVel(); llSetForce(gForce - (llVecNorm(vel) * llPow(llVecMag(vel), 2) * gDragC), FALSE); } }
|
|
Plastic Spoonhammer
Registered User
Join date: 9 Feb 2006
Posts: 20
|
03-10-2006 09:46
Jesrad Seraph has recently posted a script which moves non-physical objects smoothly - it's meant for vehicles, but should be adaptable. Since llSetPos incurs a 1/5th second delay and makes for jerky movement, his solution is to use two 'mover' scripts running concurrently and offset by a tenth of a second to achieve 10 updates per second, which gives a reasonably convincing motion provided the sim isn't under heavy load.
There are various reasons for wanting to simulate movement with non-physical objects, but in your case it seems like enabling physics for your fish would be much simpler. Is there a reason you'd prefer they stay non-physical?
- P. Spoonhammer
|
|
Rickard Roentgen
Renaissance Punk
Join date: 4 Apr 2004
Posts: 1,869
|
03-10-2006 11:32
for smooth rotations you can use carefully timed TargetOmega and get a pretty good effect. I've done it for wagging avatar tails. Not sure how this will work with lLSetPos though. might reset the Omega.
|
|
Naryu Yue
Interrupted?
Join date: 23 Jul 2007
Posts: 15
|
08-28-2007 13:07
hehe i recently researched and achieved to overcome that problem \o/ in my case, i was moving a large boat, which could not be made physical, cuz it had 50+ prims. what i did was code a command queue, and timely flush the queue tyo produce the smooth movement. if you issue a new command,m it will be flushed and executed in the next Timer() event, meaning it gets delayed, but i asure that every command in the queue is executed. If you dont issue a new command, it just keeps doing the last executed one, meaning it keeps going in a certain direction, until you tell it to go another direction, or stop. The way i chose to issue commands was to send them in a channel (llSay()) by a another script, which I called autopilot. it works pretty much like any FIFO kind socket communication channel  //Smooth Movement Script by Naryu Yue //Do not Change any settings unless youre pretty sure what youre doing! //Feel free to use and distribute, making sure to keep the credits, thx!
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); } }
|