/////////////////////////////////////////////////////////////////////////// // 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. // /////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// // CONFIGURATION // ////////////////////////////////////////////////////////// // 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 = 4; // Maximum distance in meters from starting // coordinates that the primitive will be // allowed to reach. float MOVEMENT_RANGE = 20.0; // The minimum distance in meters when the // primitive will consider that it has reached // its next destination. float TARGET_AFFINITY = 0.8; //// Although these could be used to calculate //// the average velocity, they are provided //// separately because the "feeling" of watching //// an object go from point to point has to be //// tweaked in order to be fluent (ie: without //// big noticeable jumps between the points). //// Time between steps, measured in seconds. This //// differs between environments and can only be //// determined empirically at the level of a script. // Time between steps in seconds, Ideally as low // as possible float TIME = 0.1; // Step distance, measured in meters. Ideally as // low as possible. float STEP = 0.1; ////////////////////////////////////////////////////////// // INTERNALS // ////////////////////////////////////////////////////////// // 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 ; if(TYPE == 4) return ; if(TYPE == 8) return iPos + ; if(TYPE == 16) return iPos + ; if(TYPE == 32) return iPos + ; if(TYPE == 64) return iPos + ; if(TYPE == 128) return iPos + ; if(TYPE == 256) return iPos + ; return iPos; } // Vector that will be filled by the script with // the initial starting position in region coordinates. vector iPos = ZERO_VECTOR; // Storage for destination position. vector dPos = ZERO_VECTOR; // Begin script. default { state_entry() { // Avoid problems with other objects. llSetStatus(STATUS_PHANTOM, TRUE); iPos = llGetPos(); dPos = nextCoordinates(MOVEMENT_TYPE); llSetTimerEvent(TIME); } timer() { if(llVecDist(llGetPos(), dPos) < TARGET_AFFINITY) { dPos = nextCoordinates(MOVEMENT_TYPE); llLookAt(dPos, 0.1, 0.1); } vector cPos = llGetPos(); vector sPos = cPos + STEP * (dPos-cPos)/llVecDist(cPos,dPos); llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_POSITION, sPos]); llSetTimerEvent(TIME); } } // End script.