Table of Contents

and FailedNoob Resident based on wanderer.

Shortnote

Based on the calculations on wanderer, we can derive an orbiter script that takes as input the owner's position and rotates around them as well as turning its positive z-face towards them. Please note that for practical applications such as sculpts, you will have to either create a prim or design an object so that the face of the root primitive that should point towards you should be along the positive z-axis.

wanderer generates coordinates within a geometrical shape or body by randomly varying the angles and the distance from the origin point. Orbiter simplifies that by incrementing the angle values instead of picking them randomly and also keeps the distance from the origin point constant. That way, Orbiter manages to travel on the circumference geodesic on the shape of the body. If the sphere calculation would be replaced instead of the circular movement, the Orbiter would move on the surface of a sphere.

Applications

The orbiter currently revolves around the owner on a circular trajectory. However, we can expand that to orbit around other objects and with different trajectories. Possibly, it could be used as a tool for simulating a planetary system.

Setup

In order to use this script:

Code

orbiter.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.        //
///////////////////////////////////////////////////////////////////////////
 
//////////////////////////////////////////////////////////
//                  CONFIGURATION                       //
//////////////////////////////////////////////////////////
// How precise corners are?
float DEFINITION = .1;
// What range from the owner in 
// meters?
float RADIUS = 2; // meters
// How precise should the drift 
// towards the target be?
float TARGET_AFFINITY = .8; // meters
// When will the object consider 
// it has reached the target?
float TARGET_DAMPENING = 3;
//////////////////////////////////////////////////////////
//                      INTERNALS                       //
//////////////////////////////////////////////////////////
vector dPos = ZERO_VECTOR;
float a = PI;
float b = PI;
 
vector nextPos(vector iPos) {
    // Circle Rotation
    if(a >= TWO_PI) a=0; if(b >= TWO_PI) b=0;
    return iPos + <RADIUS *  llCos(a+=DEFINITION), RADIUS * llSin(b+=DEFINITION), 0>;
}
 
moveTo(vector position) {
    llTargetRemove(_targetID);
    _targetID = llTarget(position, TARGET_AFFINITY);
    llLookAt(position, .6, .6);
    llMoveToTarget(position, TARGET_DAMPENING);    
}
 
key _owner = NULL_KEY;
integer _targetID = 0;
 
default
{
    state_entry() {
        llSetStatus(STATUS_PHYSICS, FALSE);
        _owner = llGetOwner();
        llSensorRepeat("", _owner, AGENT, 64, TWO_PI, (1.2-llGetRegionTimeDilation()));
        _targetID = 0;
    }
 
    sensor(integer num) {
        dPos = llDetectedPos(0);
    }
    no_sensor() {
        llSetStatus(STATUS_PHYSICS, FALSE);
    }
 
    touch_start(integer total_number)
    {
        llSetStatus(STATUS_PHYSICS, TRUE);
        llSetForce(<0,0,9.81> * llGetMass(), 0);
        dPos = llDetectedPos(0);
        moveTo(nextPos(dPos));
    }
    at_target(integer tnum, vector targetpos, vector ourpos) {
        if(tnum != _targetID) return;
        moveTo(nextPos(dPos));
    }
    on_rez(integer param) {
        llSetStatus(STATUS_PHYSICS, FALSE);
        _owner = llGetOwner();
    }
    changed(integer change) {
        if(change & CHANGED_OWNER)
            _owner = llGetOwner();
    }
}

TODO