Clusterrezzer.lsl

This is the rezzer script described on Using NewtonPhysics that will rez out two stars orbiting in a circle. Read the instructions on Using NewtonPhysics to make it work. It rezzes a bunch of stars with a 1/r distribution (out to some cutoff), and then gives them random velocities with a v_rms that is roughly what you'd expect virially.

// Listens on channel 1 for instructions //  "rez" -- rez the stars //  "go"  -- tell stars to apply initial velocity and go //   "stop" -- turns stars unphysical //  "start" -- turns stars physical //  "die" -- tells stars to die

integer chan = 3117;

// exponential scale length of the cluster // or, maybe maximum radius of the cluster float r = 25.0;

// mass of each star float m = 0.5;

// Number of stars integer n = 64;

// *************** // internal variables

list starpos; list starvel;

// ****************************************************

float exprand(float sigma) {   float x = 0.0; while (x == 0.0) x = llFrand(1.0); return -llLog(x)*sigma; }

// returns r distributed according to p(r) = 1/r, //  with a cutoff at maxr

float invrand(float maxr) {   float maxx = llLog(maxr); float x = llFrand(maxx); return(llPow(2.71828182845905, x)); }

float gaussrand(float sigma) {   float x1; float x2; float y1; float y2; float ftmp; float R2 = 2.; while (R2 > 1. || R2 ==0) {       x1 = 2.0*llFrand(1.0) - 1.0; x2 = 2.0*llFrand(1.0) - 1.0; R2 = x1*x1 + x2*x2; }   ftmp = llSqrt(-2. * llLog(R2) / R2); y1 = x1 * ftmp; y2 = x2 * ftmp;   // Extra!

return y1 * sigma; }

vector randsphere(float r) { float costheta = llFrand(2.0) - 1.0; float sintheta = llSqrt(1.0 - costheta*costheta); float phi = llFrand(TWO_PI);

return  * r; }

rezstars {   integer i;    integer j;    float starrad; vector thisstarpos; vector thisstarvel; float pe = 0.; // I wish we had doubles float rmsvel = 0; float dist;

llSay(0, "Rezzing " + (string)n + " stars..."); starpos = ["junk"]; starvel = ["junk"];

for (i = 1 ; i <= n ; ++i) {       // starrad = exprand(r); starrad = invrand(r); thisstarpos = llGetPos + randsphere(starrad); starpos += [thisstarpos]; // llSay(0, "Star " + (string)i + " pos: " + (string)thisstarpos); llRezObject("Star", llGetPos, ZERO_VECTOR,                   ZERO_ROTATION, i); for (j = 1 ; j < i ; ++j) {           dist = llVecMag(llList2Vector(starpos, j) - thisstarpos); pe -= m * m / dist;  // no divide-by-0 protection... }   }    llSay(0, "PE = " + (string)pe); rmsvel = llSqrt( -pe / (3.0 * m * n) ); llSay(0, "rmsvel = " + (string)rmsvel);

for (i = 1 ; i <= n ; ++i) {       thisstarvel = ; starvel += [thisstarvel]; // llSay(0, "Star " + (string)i + " vel: " + (string)thisstarvel); }

llSay(0, "...done rezzing stars.");

}

default {   state_entry {       llListen(chan, "", "", ""); llListen(1, "", "", ""); }

touch_start(integer num) {   }    listen(integer chan, string name, key id, string msg) {       list params = llParseString2List(msg, [" "], []); string command = llList2String(params, 0); integer num = 0; if (llGetListLength(params) > 1) num = llList2Integer(params, 1); if (command == "Hello" && num > 0 && num <= n)       { // llSay(0, "Got Hello from star " + (string)num); llSay(chan, "pos " + (string)num + " " + llList2String(starpos, num)); llSay(chan, "initvel " + (string)num + " " + llList2String(starvel, num)); }       else if (command == "rez") {           rezstars; }       else if (command == "go") {           llRegionSay(3117, "go"); }       else if (command == "stop") {           llRegionSay(3117, "stop"); }       else if (command == "start") {           llRegionSay(3117, "start"); }       else if (command == "die") {           llRegionSay(3117, "die"); }   }       }