The following script can be configured to make an object move inside the following geometric shapes:
// 2 for a square. // 4 for a circle. // 8 for a sphere. // 16 for an upper hemisphere. // 32 for a lower hemisphere. // 64 for an elipsoid. // 128 for an upper hemi-elipsoid. // 256 for a lower hemi-elipsoid.
using a gaussian distribution with an accumulation of points in the vicinity of the origin point.
Configure the script by setting the parameters described in the header:
integer MOVEMENT_TYPE = 4; float MOVEMENT_RANGE = 5; float TARGET_AFFINITY = .8; float TARGET_DAMPENING = 3;
they are all documented in the script. After that, save the script and drop it in a primitive you wish to wander about.
/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2011 - License: GNU GPLv3 // // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // // rights of fair usage, the disclaimer and warranty conditions. // /////////////////////////////////////////////////////////////////////////// // This defines the movement type that the // primitive will have. The primitive will // generate coordinates within the following // types of geometric areas. // // Replace the MOVEMENT_TYPE below with one // of the following numbers representing: // 2 for a square. // 4 for a circle. // 8 for a sphere. // 16 for an upper hemisphere. // 32 for a lower hemisphere. // 64 for an elipsoid. // 128 for an upper hemi-elipsoid. // 256 for a lower hemi-elipsoid. integer MOVEMENT_TYPE = 32; // Maximum distance in meters from starting // coordinates that the primitive will be // allowed to reach. float MOVEMENT_RANGE = 5; // The minimum distance in meters when the // primitive will consider that it has reached // its next destination. float TARGET_AFFINITY = .8; // How fast will the primitive try to reach // the next coordinate. float TARGET_DAMPENING = 3; // Returns the next random coordinates // depending on the type of shape selected. // // IN: integer representing shape. // OUT: vector containing the coordinates // relative to the initial starting position. vector nextCoordinates(integer TYPE) { float driftRange = llFrand(MOVEMENT_RANGE); float a = llFrand(TWO_PI); float b = llFrand(TWO_PI); float c = llFrand(PI); if(TYPE == 2) return <iPos.x + driftRange, iPos.y + llFrand(MOVEMENT_RANGE), iPos.z>; if(TYPE == 4) return <iPos.x + driftRange * llCos(a), iPos.y + driftRange * llSin(b), iPos.z>; if(TYPE == 8) return iPos + <driftRange * llCos(a) * llCos(b), driftRange * llCos(a) * llSin(b), driftRange * llSin(a)>; if(TYPE == 16) return iPos + <driftRange * llCos(a) * llCos(b), driftRange * llCos(a) * llSin(b), driftRange * llSin(c)>; if(TYPE == 32) return iPos + <driftRange * llCos(a) * llCos(b), driftRange * llCos(a) * llSin(b), -driftRange * llSin(c)>; if(TYPE == 64) return iPos + <driftRange * llCos(a) * llCos(b), llFrand(MOVEMENT_RANGE) * llCos(a) * llSin(b), driftRange * llSin(a)>; if(TYPE == 128) return iPos + <driftRange * llCos(a) * llCos(b), llFrand(MOVEMENT_RANGE) * llCos(a) * llSin(b), driftRange * llSin(c)>; if(TYPE == 256) return iPos + <driftRange * llCos(a) * llCos(b), llFrand(MOVEMENT_RANGE) * llCos(a) * llSin(b), -driftRange * llSin(c)>; return iPos; } //vector nextCoordinates(integer MOVEMENT_TYPE) { // float driftRange = llFrand(10); // float a = llFrand(TWO_PI); // float b = llFrand(TWO_PI); // return iPos + <driftRange * llCos(a) * llCos(b), driftRange * llCos(a) * llSin(b), driftRange * llSin(a)>; //} // Orientates the primitive's positive z axis // towards a position and moves the primitive // towards that position. // // IN: vector representing a position in region // coordinates. // OUT: nothing. moveTo(vector position) { llTargetRemove(targetID); targetID = llTarget(position, TARGET_AFFINITY); llLookAt(position, .6, .6); llMoveToTarget(position, TARGET_DAMPENING); } // Vector that will be filled by the script with // the initial starting position in region coordinates. vector iPos; // Integer that the script will use to detect // the next target position it will reach. integer targetID; // Begin script. default { state_entry() { iPos = llGetPos(); llSetStatus(STATUS_PHYSICS, TRUE); llSetForce(<0,0,9.81> * llGetMass(), 0); moveTo(nextCoordinates(MOVEMENT_TYPE)); } at_target(integer tnum, vector targetpos, vector ourpos) { if(tnum != targetID) return; moveTo(nextCoordinates(MOVEMENT_TYPE)); } } // End script.