Table of Contents

Shortnote

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.

Parameters

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.

Code

wanderer_gaussian.lsl
///////////////////////////////////////////////////////////////////////////
//  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.