Danny DeGroot
Sub-legendary
Join date: 7 Jul 2004
Posts: 191
|
04-27-2005 11:14
Hi,
I feel vaguely guilty about posting this question before going in-game and actually testing it, but I'm not going to be able to do that until later today, and I'm very curious. Plus, I'm avoiding an unpleasant RW task by posting here instead.
Say I wanted to rez a banana creme pi...um, a small physical homing device, and have it travel across a few sims in search of Dodger Alexa..um, a hypothetical fellow avie. If I give it a straight-line force vector...say, <500.0, 0.0, 0.0> is a good course...then will applying <-500.0, 0.0, 0.0> inside the target sim immediately cancel the forward motion? Or is there a momentum to contend with?
Thanks in advance for any insights into this purely theoretical question.
== danny d.
Edit: PS This would be using force as opposed to impulse.
|
Jeffrey Gomez
Cubed™
Join date: 11 Jun 2004
Posts: 3,522
|
04-27-2005 12:18
Hell, if that's all you want to do, why not just do an llMoveToTarget loop? vector target = <0,0,0>; // Hypothetical target float speed = 10; // Speed of motion float time_between = 0.3; // Speed of the timer float threshhold = 10; // Threshhold value before moving directly to target
default { state_entry() { llMoveToTarget(llGetPos(), 0.3); llSetStatus(STATUS_PHYSICS,TRUE); llSetTimerEvent(time_between); } timer() { if(llAbs((integer)target.x) <= 256 && llAbs((integer)target.y) <= 256) // If this is small, we must be in local position { llMoveToTarget(llGetPos() + (llVecNorm(target - llGetPos()) * speed),0.3); if(llVecMag(target - llGetPos()) < threshhold) { llMoveToTarget(target,0.3); llSay(0,"Splat!"); } } else // ... we're in global units. { llMoveToTarget(llGetPos() + (llVecNorm(target - llGetPos() + llGetRegionCorner()) * speed),0.3); if(llVecMag(target - llGetPos() + llGetRegionCorner()) < threshhold) { llMoveToTarget(target,0.3); llSay(0,"Splat!"); } } } } Caution: Written out-of-world. Of course, this is optimized to work in-sim unless you like globals. An even simpler way, if you don't care about accuracy*, would be to just shut off physics when the object hits the target. AKA: llSetStatus(STATUS_PHYSICS,FALSE); Edit: Changed code to work with globals.
_____________________
---
|
Danny DeGroot
Sub-legendary
Join date: 7 Jul 2004
Posts: 191
|
04-27-2005 13:33
Jeffrey, That's a total eye-opener...I had no idea you could feed global coordinates directly into llMoveToTarget(). (That is what you're doing, right? I need to spend some time with your example when I wake up. I'm on vacation, so the "wake up" task is running at a lower-than-normal priority  ) The reason I was originally after predicting the llSetForce() behavior was that I wanted to plot a fairly lengthy route across the grid (for a single object, not a swarm  ), and I thought I was going to have to change directions a couple of times to bypass the void sims...and maybe sneak up from behind  So, I wanted to pre-define the N,S,E,and W force vectors, and to be able to process a chatted route like "NNNNEEEENN" to launch the thing, having it grab the next character in the string and apply the matching vector each time it crossed a sim border. But if applying the South vector to a Northward-travelling object doesn't halt it immediately when it gets to a sim where it needs to change direction, then as I understand it, it may have travelled two or three additional sims before the East vector takes hold. I hope that makes sense. I've had a little more caffeine, but still not nearly enough. == danny d.
|
Jeffrey Gomez
Cubed™
Join date: 11 Jun 2004
Posts: 3,522
|
04-27-2005 13:39
Totally understand. Here. Have a pathfinder. // Edit these variables here:
// Target Sim: string region = "Urdu";
// Location in Sim vector loc = <100,100,50>;
// Advanced Variables:
integer max_tries = 100; // Max number of traceback routines float fly_height= 400; // Height to fly in world units integer speed = 20; // Speed for physical movement integer same_sim_tries = 5; // Failsafe count before use back is triggered
// Standard Flags:
integer use_back = TRUE; // Depending, this might help the pathfinder WORK! integer use_phys = TRUE; // Use physics integer ignore_init = TRUE; // Ignores initialization movement
// Physics Flags: integer drunk_driver = FALSE; // One wild ride! integer use_exact = TRUE; // Use exact coords; countered by drunk_driver // Set drunk_driver and use_exact to FALSE and use_phys to TRUE to initiate // my best attempt at a vehicle-less autopilot. Enjoy!
list path = []; // Lists path already taken. Good for statistical data or, // here, knowing if we came from a sim already. key sim_stuffs = ""; // For Data Request
pathTo(vector location) { integer same_sim = 0; // Same sim count. Failsafe. integer try = 0; // Initialize our first try variable integer traceback = FALSE; // Traceback variable if we dead-end vector init = llGetPos(); // Initialize our position init.z = fly_height; if(use_phys) { llMoveToTarget(llGetPos(),0.3); llSetStatus(STATUS_PHYSICS,TRUE); } if(!ignore_init) { if(!use_phys) { while(llGetPos() != init) llSetPos(init); } else { while(llVecMag(llGetPos() - init) > speed) llMoveToTarget(llGetPos() + llVecNorm(init - llGetPos()) * speed,0.3); } } while(try < max_tries) // Start up the meat of our function { vector global = llGetPos() + llGetRegionCorner(); vector diff = location + <0,128,0> - global; vector target = <0,0,0>; integer is_next = FALSE; if(llListFindList(path,(list)llGetRegionCorner()) == -1) path += llGetRegionCorner(); else same_sim++; if(llGetRegionName() == region) { thisSim(); return; } if(llAbs((integer)diff.x) > llAbs((integer)diff.y)) { if(diff.x < 0) { if(!llEdgeOfWorld(<128,128,0>, <-256,0,0>) && llListFindList(path,[llGetRegionCorner() + <-256,0,0>]) == -1) target = llGetRegionCorner() + <-128,128,0>; else { if(diff.y < 0) { if(!llEdgeOfWorld(<128,128,0>, <0,-256,0>) && llListFindList(path,[llGetRegionCorner() + <0,-256,0>]) == -1) target = llGetRegionCorner() + <128,-128,0>; } if(target == <0,0,0>) { if(!llEdgeOfWorld(<128,128,0>, <0,256,0>) && llListFindList(path,[llGetRegionCorner() + <0,256,0>]) == -1) target = llGetRegionCorner() + <128,384,0>; } if(target == <0,0,0>) traceback = TRUE; } } else { if(!llEdgeOfWorld(<128,128,0>, <256,0,0>) && llListFindList(path,[llGetRegionCorner() + <256,0,0>]) == -1) target = llGetRegionCorner() + <384,128,0>; else { if(diff.y < 0) { if(!llEdgeOfWorld(<128,128,0>, <0,-256,0>) && llListFindList(path,[llGetRegionCorner() + <0,-256,0>]) == -1) target = llGetRegionCorner() + <128,-128,0>; } if(target == <0,0,0>) { if(!llEdgeOfWorld(<128,128,0>, <0,256,0>) && llListFindList(path,[llGetRegionCorner() + <0,256,0>]) == -1) target = llGetRegionCorner() + <128,384,0>; } if(target == <0,0,0>) traceback = TRUE; } } } else { if(diff.y < 0) { if(!llEdgeOfWorld(<128,128,0>, <0,-256,0>) && llListFindList(path,[llGetRegionCorner() + <0,-256,0>]) == -1) target = llGetRegionCorner() + <128,-128,0>; else { if(diff.x < 0) { if(!llEdgeOfWorld(<128,128,0>, <-256,0,0>) && llListFindList(path,[llGetRegionCorner() + <-256,0,0>]) == -1) target = llGetRegionCorner() + <-128,128,0>; } if(target == <0,0,0>) { if(!llEdgeOfWorld(<128,128,0>, <256,0,0>) && llListFindList(path,[llGetRegionCorner() + <256,0,0>]) == -1) target = llGetRegionCorner() + <384,128,0>; } if(target == <0,0,0>) traceback = TRUE; } } else { if(!llEdgeOfWorld(<128,128,0>, <0,256,0>) && llListFindList(path,[llGetRegionCorner() + <0,256,0>]) == -1) target = llGetRegionCorner() + <128,384,0>; else { if(diff.x < 0) { if(!llEdgeOfWorld(<128,128,0>, <-256,0,0>) && llListFindList(path,[llGetRegionCorner() + <-256,0,0>]) == -1) target = llGetRegionCorner() + <-128,128,0>; } if(target == <0,0,0>) { if(!llEdgeOfWorld(<128,128,0>, <256,0,0>) && llListFindList(path,[llGetRegionCorner() + <256,0,0>]) == -1) target = llGetRegionCorner() + <384,128,0>; } if(target == <0,0,0>) traceback = TRUE; } } } if(traceback) { try++; integer path_back = llListFindList(path,[llGetRegionCorner()]); if(llListFindList(path,[llGetRegionCorner()]) == -1) path_back = llGetListLength(path) - 1; // See if any sim is open nearby if use_back is set if(use_back || llGetRegionCorner() == llList2Vector(path,0) || same_sim > same_sim_tries) { if(!llEdgeOfWorld(<128,128,0>, <-256,0,0>) && llListFindList(path,[llGetRegionCorner() + <-256,0,0>]) == -1) target = llGetRegionCorner() + <-128,128,0>; else if(!llEdgeOfWorld(<128,128,0>, <256,0,0>) && llListFindList(path,[llGetRegionCorner() + <256,0,0>]) == -1) target = llGetRegionCorner() + <384,128,0>; else if(!llEdgeOfWorld(<128,128,0>, <0,-256,0>) && llListFindList(path,[llGetRegionCorner() + <0,-256,0>]) == -1) target = llGetRegionCorner() + <128,-128,0>; else if(!llEdgeOfWorld(<128,128,0>, <0,256,0>) && llListFindList(path,[llGetRegionCorner() + <0,256,0>]) == -1) target = llGetRegionCorner() + <128,384,0>; same_sim = 0; } // If all else fails, go back along the path we took if(target == <0,0,0>) target = llList2Vector(path,path_back - 1) + <128,128,0>; traceback = FALSE; } if(ignore_init && llVecMag(<location.x,location.y,0> + <128,128,0> - <target.x,target.y,0>) < 10) { is_next = TRUE; target = (location + loc) - (1 / 5 * (loc + location - llGetPos() - llGetRegionCorner())); } if(llGetStatus(STATUS_PHYSICS)) { while(llVecMag(<target.x,target.y,0> - <global.x,global.y,0>) > speed * 5) { global = llGetPos() + llGetRegionCorner(); vector place = llGetPos() + target - global; if(!is_next) place.z = fly_height; if(use_exact) { llMoveToTarget(llGetPos() + (llVecNorm(place - llGetPos()) * speed),0.3); llLookAt(llGetPos() + llVecNorm(place - llGetPos()) * speed,0.3,0.3); } else { vector between; between = llRot2Euler(llRotBetween(llRot2Up(llGetRot()),llVecNorm(place - llGetPos()))); if(!drunk_driver) { vector between2 = llRot2Euler(llRotBetween(llVecNorm(place - llGetPos()),llRot2Up(llGetRot()))); if(llVecMag(llVecNorm(between) + llRot2Up(llGetRot())) < 1.1 && llVecMag(llRot2Up(llGetRot()) + llVecNorm(place - llGetPos())) > 1) between = between2; } rotation two = llGetRot() * llEuler2Rot(0.1 * between); llLookAt(llGetPos() + (<0,0,1> * two),0.3,0.3); llMoveToTarget(llGetPos() + llRot2Up(llGetRot()) * speed,0.3); } llSleep(0.2); } } else { while(target.x != global.x || target.y != global.y) { global = llGetPos() + llGetRegionCorner(); vector place = llGetPos() + target - global; place.z = fly_height; llSetPos(place); llSleep(0.1); } } } }
thisSim() { float ground = llGround(loc - llGetPos()); if(llScriptDanger(loc) && loc.z < ground + 20) loc.z = ground; else if(loc.z < ground) loc.z = ground; if(llGetStatus(STATUS_PHYSICS)) { while(llVecMag(llGetPos() - loc) > speed) { llMoveToTarget(llGetPos() + llVecNorm(loc - llGetPos()) * speed,0.3); llLookAt(llGetPos() + llVecNorm(loc - llGetPos()) * speed,0.3,0.3); } } else { while(llGetPos() != loc) llSetPos(loc); } llSetStatus(STATUS_PHYSICS,FALSE); llStopLookAt(); llStopMoveToTarget(); vector rot = llRot2Euler(llGetRot()); llSetRot(llEuler2Rot(<PI + PI_BY_TWO,rot.y,PI_BY_TWO>)); }
default { touch_start(integer total_number) { sim_stuffs = llRequestSimulatorData(region,DATA_SIM_POS); } dataserver(key query, string data) { if(query == sim_stuffs) pathTo((vector)data); } }
_____________________
---
|
Elle Pollack
Takes internets seriously
Join date: 12 Oct 2004
Posts: 796
|
04-27-2005 13:53
From: Danny DeGroot Say I wanted to rez a banana creme pi...um, a small physical homing device, and have it travel across a few sims in search of Dodger Alexa..um, a hypothetical fellow avie. . *cracks up*. I promise not to warn the Artfull Dodger if you leave L${undisclosed sum} for me at {Location DELETED FOR SECURITY REASONS}. 
_____________________
*********************************************** "Ya'll are so cute with your pitchforks and torches ..." ~Brent Linden SL streams a world, can you also stream a mind?
|