Autonavigation?
|
|
Bradder Thereian
The Riverwalk
Join date: 4 Jun 2004
Posts: 69
|
12-26-2004 11:27
Posted in the General section regarding the problems with people building over protected areas. Someone thought I might get a better response here:
I have three parcels of property that are separated by short protected waterways. Though I know I *could* build illegal bridges between the properties unitl they were discovered, I would prefer a legal. less obtrusive solution and provide some sort of self-navigating, recreational "shuttle boat" that, upon boarding, would travel a fixed route ride from one dock to the next- sort of like a simpler version of the Tour Balloon I own, but as a water-level boat and on a much simpler scale for the destination coordinates.
Though I have read that such a task is actually quite easy for fixed-point destination coordinates for land/water vehicles, sadly I have absolutely no understanding of scripting and no programing abilities what-so-ever. So far I have had no luck in finding a script that will do this.
I do want to stay legal and keep the waterways clear of any obstructions - and I am sure the neighbors would appreciate not having boaters slamming into their property due to untired powerboating skills. Anyone know where such a script may be found?
|
|
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
|
12-26-2004 12:05
Can I second that plea please. I do script quite a bit, but physics and vehicles and I just don't get on in SL.
|
|
Shack Dougall
self become: Object new
Join date: 9 Aug 2004
Posts: 1,028
|
12-26-2004 23:09
One way to look at this problem is as an elevator that goes sideways or maybe if it was on a diagonal you could call it slideways. It always makes me think of the Wankavator from the chocalate factory movie. Anyway, for a scriptor, most of the code that you need can be found here. It's probably overkill and won't work for this ferry concept out of the box, but everything a scripter needs to solve this problem is there. All of the vector math and physics has been coded. It even has support for storing a non-linear path that would take a ferry around a bend in a river. If nobody beats me to it, I'll munge it into an all-purpose elevator script that will fit the ferry problem.
_____________________
Prim Composer for 3dsMax -- complete offline builder for prims and sculpties in 3ds Max http://liferain.com/downloads/primcomposer/
Hierarchical Prim Archive (HPA) -- HPA is is a fully-documented, platform-independent specification for storing and transferring builds between Second Life-compatible platforms and tools. https://liferain.com/projects/hpa
|
|
Bradder Thereian
The Riverwalk
Join date: 4 Jun 2004
Posts: 69
|
12-27-2004 08:13
Appreciate any help you can provide Shack- I think I have copied every script that I though might work for this- yours among them. Unfortunately my reaction was similar to looking at a Picasso "This is absolutely beautiful... what is it?" I did make it as far as "integer" in yours though 
|
|
Artillo Fredericks
Friendly Orange Demon
Join date: 1 Jun 2004
Posts: 1,327
|
12-27-2004 08:27
cool idea Wonkavator LOL I have a similar problem with Gov Linden land splitting my two lots... thanx for the info!
Arti
_____________________
"I, for one, am thouroughly entertained by the mass freakout." - Nephilaine Protagonist --== www.artillodesign.com ==--
|
|
Shack Dougall
self become: Object new
Join date: 9 Aug 2004
Posts: 1,028
|
Shack's Ferry Script 0.1
12-28-2004 12:50
Okay, as promised, here's a ferry script. It is essentially an omni-directional elevator script that overcomes all limitations on height and distance. It is a greatly simplified version of my PersonalPilot script. // Shack's Ferry Script // Version 0.1 // // Copyright 2004 Shack Dougall // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // DATE: 12-28-2004
// DESCRIPTION: The prim containing this script will move to position1 the // first time that it is touched. Thereafter, touching it will cause it to // ferry between position1 and position2.
// Position1 and Position2 can be anywhere in the same sim, but there must // be an unobstructed, straight-line path between them. However, there is // no limit to how high or how far apart the points are. This script is not // limited to up/down or left/right motion. Any two points will work.
// NOTE: Unattached objects disappear above z=4096. Also, the script uses // physics, so mass/energy limitations apply. That is, the prim containing // this script will not move if it does not have sufficient energy to move // both itself and anything standing on it. // It uses llMoveToTarget, so the prim should be at least as massive as // everything else it is moving. But if it is too massive, then it won't // have enough energy to move the mass.
// If you have problems, experiment with small unattached prims first.
// You could modify this to use llSetPos instead of llMoveToTarget if you // would prefer a different set of limitations :)
// ********************************************* // YOU MUST SET THE TWO POSITION VARIABLES!
vector position1 = ZERO_VECTOR; vector position2 = ZERO_VECTOR;
// for example, < X, Y, Z > // vector position1 = <10, 10, 50>; // vector position2 = <20, 20, 60>;
// *********************************************
// YOU MAY PLAY WITH THE VARIABLES BELOW
//Small TAU means faster movement. min: 0.032 good: > 0.2 //STEP_SIZE is the amount of distance that we will try to travel with one //call to llMoveToTarget. Necessary because llMoveToTarget //damps to the current position if this distance is > 64m. float TAU = 2.0; float STEP_SIZE = 63.0;
//STEP_TARGET_RANGE is how close to a move target we go before //we issue a new move target. The idea is that we don't want to slow down //too much, so we set a new target before we get to the first one. float STEP_TARGET_RANGE = 10.0;
// &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // DON'T TOUCH ANYTHING BELOW THIS UNLESS YOU KNOW WHAT YOU'RE DOING ;-) // danger Will Robinson
// where we are going vector destCoords;
integer NULL_TARGET = -1;
//targetID is the ID returned by the last call to llTarget if one is active. integer targetID = NULL_TARGET;
//Vector of length STEP_SIZE that points in the direction //we want to go. Add this to the current position to get the coords of //where we want to go next to get us closer to our goal. //Calculated at the start and cached for use during the trip. vector deltaVector;
init() { if (position1 == ZERO_VECTOR || position2 == ZERO_VECTOR) { llSay(0, "You must set the values of both: position1, position2."); return; } llStopMoveToTarget(); llSetStatus(STATUS_ROTATE_X|STATUS_ROTATE_Y|STATUS_ROTATE_Z,FALSE); llSetStatus(STATUS_PHYSICS, TRUE); llMoveToTarget(llGetPos(), TAU); llSay( 0, "Touch me to make me move."); }
//Removes the llTarget. Does nothing with movement. clearTarget() { if (targetID != NULL_TARGET) { llTargetRemove( targetID ); targetID = NULL_TARGET; } }
//Returns the displacement vector between two coordinates. //That is, returns the vector you need to add to the start location to get the //destination location. vector calcDeltaVector( vector destPos, vector startPos ) { vector coordsDelta = destPos - startPos; return coordsDelta; }
//Stores our destination and calculates the initial deltaVector that will //get us there. setDestination( vector newCoords ) { clearTarget(); // get current position info and store dest info vector currCoords = llGetPos(); destCoords = newCoords; // Calculate the total displacement vector // then, normalize it to get a unit vector (vector of length 1) // then, multiply it by the STEP_SIZE to get a displacement vector of // length STEP_SIZE deltaVector = calcDeltaVector(destCoords, currCoords); deltaVector = STEP_SIZE * llVecNorm(deltaVector); }
//Returns the distance to between two coordinates. float distance( vector startCoords, vector destCoords ) { vector curDelta = calcDeltaVector(destCoords, startCoords); return llVecMag(curDelta); }
// low-level workhorse of movement. // It calls llMoveToTarget to move us and llTarget to detect when we are there. // Each call to this function moves us a distance of STEP_SIZE toward our // eventual destination. Don't call this directly. moveToNextTarget() { vector nextTargetCoords; vector currCoords = llGetPos(); float distToDestination = distance( currCoords, destCoords ); if (distToDestination > STEP_SIZE) { nextTargetCoords = currCoords + deltaVector; } else { nextTargetCoords = destCoords; } targetID = llTarget( nextTargetCoords, STEP_TARGET_RANGE ); llMoveToTarget( nextTargetCoords, TAU ); }
toggleDestination() { vector newDest; if( destCoords == position1 ) newDest = position2; else newDest = position1; setDestination( newDest ); }
default { state_entry() { init(); } touch_start(integer total_number) { toggleDestination(); moveToNextTarget(); }
at_target( integer targetID, vector targetPos, vector ourPos ) { float distanceToDestination = distance( ourPos, destCoords ); integer nearDestination = distanceToDestination <= STEP_TARGET_RANGE; if (! nearDestination) { clearTarget(); moveToNextTarget(); } } }
_____________________
Prim Composer for 3dsMax -- complete offline builder for prims and sculpties in 3ds Max http://liferain.com/downloads/primcomposer/
Hierarchical Prim Archive (HPA) -- HPA is is a fully-documented, platform-independent specification for storing and transferring builds between Second Life-compatible platforms and tools. https://liferain.com/projects/hpa
|
|
Darby Bard
Registered User
Join date: 31 Jul 2004
Posts: 1
|
12-29-2004 11:07
Appreciate all of you work and your help with this script, Shack Right after my first typo sent the ferry flying into outerspace  , I got the hang of it. This script is perfect for my needs right now. Also, by looking at the Ferry Script and comparing it to your Pilot Script I have has learned a small bit about scripting. I am still tweaking some of the "safe" variables you included with some interesting results. Providing this script was very generous of you. If I can ever help you... er, nevermind... I have absolutely no SL talents which is why I so greatly appreciate your efforts. Though it feels very lame, all I can say is "Thank you!"
|
|
Shack Dougall
self become: Object new
Join date: 9 Aug 2004
Posts: 1,028
|
12-29-2004 11:47
From: Darby Bard Appreciate all of you work and your help with this script, Shack Right after my first typo sent the ferry flying into outerspace  , I got the hang of it. Not a problem. Glad it helps. Also, I've sent quite a few objects into space as well. And probably into neighboring sims. A good thing to have in your toolbelt is a Lost Die script. It's a script that automatically deletes the object if it gets too far away from you. Great for doing experiments with physical scripts. Here's an example: //Title: Lost Die Script //Date: 10-30-2003 06:53 AM //Scripter: ZHugh Becquerel
float LastTimeOwnerDetected; key owner;
TellOwner( string Message ) { // llWhisper( 0, "Trace: " + Message ); llInstantMessage(owner, (string)llGetPos() + " " + Message ); }
Init() { owner = llGetOwner(); LastTimeOwnerDetected = llGetTimeOfDay(); llSetTimerEvent(10.0); llSensorRepeat( "", "", AGENT, 50, PI, 10.0 ); } SelfDestructNow() { llSay(0, "Too far from owner. Self-destructing..."); TellOwner("Too far from owner. Self-destructing..."); llDie(); }
default { state_entry() { Init(); } on_rez(integer start_param) { Init(); } timer() { if( llGetTimeOfDay() - LastTimeOwnerDetected > 60 ) { //TellOwner( (string)llGetTimeOfDay() + " " + (string)LastTimeOwnerDetected ); SelfDestructNow(); } else if( llGetTimeOfDay() - LastTimeOwnerDetected > 30 ) { TellOwner( "Self destructing in 30 seconds..." ); } } sensor(integer num_detected) { integer i; integer near_owner; near_owner = FALSE; for( i=0;i<num_detected;i++) { //TellOwner("Sensed:" + llDetectedName(i)); if( llDetectedKey(i) == owner) { //TellOwner( "You're close"); near_owner = TRUE; } } if( near_owner == TRUE ) { LastTimeOwnerDetected = llGetTimeOfDay(); } } }
_____________________
Prim Composer for 3dsMax -- complete offline builder for prims and sculpties in 3ds Max http://liferain.com/downloads/primcomposer/
Hierarchical Prim Archive (HPA) -- HPA is is a fully-documented, platform-independent specification for storing and transferring builds between Second Life-compatible platforms and tools. https://liferain.com/projects/hpa
|
|
Adam Marker
new scripter
Join date: 2 Jan 2004
Posts: 104
|
Does the Ferry script keep damping forever?
01-02-2005 14:10
Thanks a lot for the Ferry script ... it has been very educational!
I added a whisper to the end of the at_target routine just to explore how the script works. I get a number of messages until I get to the destination, as expected. After the object stops at the destination though, at_target continues to be called. As far as I could tell, there were no obstructions .... although I was playing around a bit with tau a bit. I waited a couple of minutes during each test. I could see no movement of the object, but at_target kept executing until I reset the script.
I'm no expert at physical movement, but I really don't want to take up extra server resources for something that is essentially idle. Would it have stopped on its own? Is my object the wrong size? Is there some way to tell the Ferry that it is Close Enough, so relax and enjoy some down time?
|
|
Shack Dougall
self become: Object new
Join date: 9 Aug 2004
Posts: 1,028
|
01-02-2005 15:57
From: Adam Marker Thanks a lot for the Ferry script ... it has been very educational!
I added a whisper to the end of the at_target routine just to explore how the script works. I get a number of messages until I get to the destination, as expected. After the object stops at the destination though, at_target continues to be called.
Excellent!  Good observation. You are right. I don't have time to look at it in depth right now. A quick mod you can make in at_target() is to replace this: if (! nearDestination) { clearTarget(); moveToNextTarget(); }
with this: clearTarget(); if (! nearDestination) { moveToNextTarget(); }
I'll test this some more before I post a corrected version. When I re-read it a couple of days ago, I think I saw another bug that could pop up in some rare situations. Nothing that would cause disaster tho. 
_____________________
Prim Composer for 3dsMax -- complete offline builder for prims and sculpties in 3ds Max http://liferain.com/downloads/primcomposer/
Hierarchical Prim Archive (HPA) -- HPA is is a fully-documented, platform-independent specification for storing and transferring builds between Second Life-compatible platforms and tools. https://liferain.com/projects/hpa
|
|
Petteri Yiyuan
Registered User
Join date: 4 Mar 2007
Posts: 56
|
01-12-2008 05:21
Is there possbile to modify this script so that it accepts movement commands between two position (1&2) between certain group of people like lockacle doors? From: Shack Dougall Okay, as promised, here's a ferry script. It is essentially an omni-directional elevator script that overcomes all limitations on height and distance. It is a greatly simplified version of my PersonalPilot script. // Shack's Ferry Script // Version 0.1 // // Copyright 2004 Shack Dougall // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // DATE: 12-28-2004
// DESCRIPTION: The prim containing this script will move to position1 the // first time that it is touched. Thereafter, touching it will cause it to // ferry between position1 and position2.
// Position1 and Position2 can be anywhere in the same sim, but there must // be an unobstructed, straight-line path between them. However, there is // no limit to how high or how far apart the points are. This script is not // limited to up/down or left/right motion. Any two points will work.
// NOTE: Unattached objects disappear above z=4096. Also, the script uses // physics, so mass/energy limitations apply. That is, the prim containing // this script will not move if it does not have sufficient energy to move // both itself and anything standing on it. // It uses llMoveToTarget, so the prim should be at least as massive as // everything else it is moving. But if it is too massive, then it won't // have enough energy to move the mass.
// If you have problems, experiment with small unattached prims first.
// You could modify this to use llSetPos instead of llMoveToTarget if you // would prefer a different set of limitations :)
// ********************************************* // YOU MUST SET THE TWO POSITION VARIABLES!
vector position1 = ZERO_VECTOR; vector position2 = ZERO_VECTOR;
// for example, < X, Y, Z > // vector position1 = <10, 10, 50>; // vector position2 = <20, 20, 60>;
// *********************************************
// YOU MAY PLAY WITH THE VARIABLES BELOW
//Small TAU means faster movement. min: 0.032 good: > 0.2 //STEP_SIZE is the amount of distance that we will try to travel with one //call to llMoveToTarget. Necessary because llMoveToTarget //damps to the current position if this distance is > 64m. float TAU = 2.0; float STEP_SIZE = 63.0;
//STEP_TARGET_RANGE is how close to a move target we go before //we issue a new move target. The idea is that we don't want to slow down //too much, so we set a new target before we get to the first one. float STEP_TARGET_RANGE = 10.0;
// &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // DON'T TOUCH ANYTHING BELOW THIS UNLESS YOU KNOW WHAT YOU'RE DOING ;-) // danger Will Robinson
// where we are going vector destCoords;
integer NULL_TARGET = -1;
//targetID is the ID returned by the last call to llTarget if one is active. integer targetID = NULL_TARGET;
//Vector of length STEP_SIZE that points in the direction //we want to go. Add this to the current position to get the coords of //where we want to go next to get us closer to our goal. //Calculated at the start and cached for use during the trip. vector deltaVector;
init() { if (position1 == ZERO_VECTOR || position2 == ZERO_VECTOR) { llSay(0, "You must set the values of both: position1, position2."); return; } llStopMoveToTarget(); llSetStatus(STATUS_ROTATE_X|STATUS_ROTATE_Y|STATUS_ROTATE_Z,FALSE); llSetStatus(STATUS_PHYSICS, TRUE); llMoveToTarget(llGetPos(), TAU); llSay( 0, "Touch me to make me move."); }
//Removes the llTarget. Does nothing with movement. clearTarget() { if (targetID != NULL_TARGET) { llTargetRemove( targetID ); targetID = NULL_TARGET; } }
//Returns the displacement vector between two coordinates. //That is, returns the vector you need to add to the start location to get the //destination location. vector calcDeltaVector( vector destPos, vector startPos ) { vector coordsDelta = destPos - startPos; return coordsDelta; }
//Stores our destination and calculates the initial deltaVector that will //get us there. setDestination( vector newCoords ) { clearTarget(); // get current position info and store dest info vector currCoords = llGetPos(); destCoords = newCoords; // Calculate the total displacement vector // then, normalize it to get a unit vector (vector of length 1) // then, multiply it by the STEP_SIZE to get a displacement vector of // length STEP_SIZE deltaVector = calcDeltaVector(destCoords, currCoords); deltaVector = STEP_SIZE * llVecNorm(deltaVector); }
//Returns the distance to between two coordinates. float distance( vector startCoords, vector destCoords ) { vector curDelta = calcDeltaVector(destCoords, startCoords); return llVecMag(curDelta); }
// low-level workhorse of movement. // It calls llMoveToTarget to move us and llTarget to detect when we are there. // Each call to this function moves us a distance of STEP_SIZE toward our // eventual destination. Don't call this directly. moveToNextTarget() { vector nextTargetCoords; vector currCoords = llGetPos(); float distToDestination = distance( currCoords, destCoords ); if (distToDestination > STEP_SIZE) { nextTargetCoords = currCoords + deltaVector; } else { nextTargetCoords = destCoords; } targetID = llTarget( nextTargetCoords, STEP_TARGET_RANGE ); llMoveToTarget( nextTargetCoords, TAU ); }
toggleDestination() { vector newDest; if( destCoords == position1 ) newDest = position2; else newDest = position1; setDestination( newDest ); }
default { state_entry() { init(); } touch_start(integer total_number) { toggleDestination(); moveToNextTarget(); }
at_target( integer targetID, vector targetPos, vector ourPos ) { float distanceToDestination = distance( ourPos, destCoords ); integer nearDestination = distanceToDestination <= STEP_TARGET_RANGE; if (! nearDestination) { clearTarget(); moveToNextTarget(); } } }
|