From Micasim
// N-body visualization star v1.3 by Rob Knop (Prospero Frobozz)
// Copyright (C) 2009 Prospero Frobozz
//
// This script is free software, available under the GNU GPL version 2.
// You are free to use it, modify it, or distribute it. If you distribute
// this script or any modified versions, they must also be under the GNU GPL.
// This means that the script itself must be mod/copy/transfer. Objects that
// use the script, or other components of such objects, do not themselves need
// to be mod/copy/transfer. However, if you distribute those objects, the
// script, or any other scripts derived from it, must, and all derived scripts
// must be made available under the GNU GPL.
integer numpositioners = 10;
integer positioner = 0;
integer numvecpositioners = 10;
integer vecpositioner = 0;
integer firstrotator = 10;
integer lastrotator = 19;
integer rotator = 10;
integer firstscaler = 20;
integer lastscaler = 29;
integer scaler = 20;
integer num;
float mass;
vector ctrpos = <0., 0., 0.>;
float posrange = 10.;
float minx;
float maxx;
float miny;
float maxy;
float minz;
float maxz;
float shaftwid = 0.1;
float minvecsize = 0.05;
float maxvecsize = 10.;
float dispscale = 1.0;
integer velshown;
setmass(float inmass)
{
vector color;
vector size;
mass = inmass;
if (mass < 0.5) {
size = dispscale * <0.5, 0.5, 0.5>;
color = <1., 0., 0.>;
}
else if (mass < 0.7) {
size = dispscale * <0.75, 0.75, 0.75>;
color = <1., 0.5, 0.>;
}
else if (mass < 0.9) {
size = dispscale * <0.8, 0.8, 0.8>;
color = <1., 0.75, 0.>;
}
else if (mass < 1.2) {
size = dispscale * <1.0, 1.0, 1.0>;
color = <1., 1., 0.>;
}
else if (mass < 2) {
size = dispscale * <1.15, 1.15, 1.15>;
color = <1., 1., 0.5>;
}
else if (mass < 3) {
size = dispscale * <1.3, 1.3, 1.3>;
color = <1., 1., 1.>;
}
else if (mass < 4) {
size = dispscale * <1.5, 1.5, 1.5>;
color = <0.5, 0.7, 1.0>;
}
else if (mass < 5) {
size = dispscale * <1.7, 1.7, 1.7>;
color = <0.4, 0.5, 1.0>;
}
else {
size = dispscale * <1.9, 1.9, 1.9>;
color = <0.2, 0.2, 1.0>;
}
llSetColor(color, ALL_SIDES);
llSetScale(size);
}
setminmax()
{
minx = ctrpos.x - posrange * dispscale;
maxx = ctrpos.x + posrange * dispscale;
miny = ctrpos.y - posrange * dispscale;
maxy = ctrpos.y + posrange * dispscale;
minz = ctrpos.z - posrange * dispscale;
maxz = ctrpos.z + posrange * dispscale;
}
setpos(vector pos)
{
pos *= dispscale;
pos += ctrpos;
if (pos.x < minx) pos.x = minx;
if (pos.x > maxx) pos.x = maxx;
if (pos.y < miny) pos.y = miny;
if (pos.y > maxy) pos.y = maxy;
if (pos.z < minz) pos.z = minz;
if (pos.z > maxz) pos.z = maxz;
llMessageLinked(LINK_THIS, positioner, (string)pos, NULL_KEY);
if (++positioner >= numpositioners) {
positioner = 0;
}
}
setvel(vector invel)
{
invel *= dispscale;
float shaftlen = llVecMag(invel);
vector shaftnorm = llVecNorm(invel);
float coslat = llSqrt(shaftnorm.x*shaftnorm.x + shaftnorm.y*shaftnorm.y);
float cosphi;
if (coslat == 0.) cosphi = 0.; else cosphi = shaftnorm.x/coslat;
float coslat2 = llSqrt( (1 + coslat) / 2.);
float sinlat2 = llSqrt( (1 - coslat) / 2.);
if (shaftnorm.z < 0) sinlat2 *= -1.;
float cosphi2 = llSqrt( (1 + cosphi) / 2.);
if (shaftnorm.y < 0) cosphi2 *= -1;
float sinphi2 = llSqrt( (1 - cosphi) / 2.);
if (shaftlen < minvecsize) shaftlen = minvecsize;
if (shaftlen > maxvecsize) shaftlen = maxvecsize;
vector shaftpos = <shaftlen/2., 0., 0.>;
vector headpos = <shaftlen, 0., 0.>;
vector shaftscale = <dispscale*0.1, dispscale*0.1, shaftlen>;
rotation rot = <0., -sinlat2, 0., coslat2> * <0., 0., sinphi2, cosphi2>;
// rotation rot = llEuler2Rot(<0., llAsin(-shaftnorm.z), 0.>) *
// llEuler2Rot(<0., 0., llAtan2(shaftnorm.y, shaftnorm.x)>);
llMessageLinked(LINK_THIS, rotator, (string)rot, NULL_KEY);
if (++rotator > lastrotator) {
rotator = firstrotator;
}
llMessageLinked(2, vecpositioner, (string)shaftpos, NULL_KEY);
llMessageLinked(3, vecpositioner, (string)headpos, NULL_KEY);
if (++vecpositioner >= numvecpositioners) {
vecpositioner = 0;
}
llMessageLinked(2, scaler, (string)shaftscale, NULL_KEY);
if (++scaler > lastscaler) {
scaler = firstscaler;
}
}
figurenumber()
{
string name = llGetObjectName();
list nameparse;
nameparse = llParseString2List(name, [" "], []);
num = llList2Integer(nameparse, 1);
llSay(0, "I am star "+(string)num);
}
default
{
state_entry()
{
figurenumber();
// Start with velocity arrow hidden
llSetLinkAlpha(2, 0.0, ALL_SIDES);
llSetLinkAlpha(3, 0.0, ALL_SIDES);
velshown = 0;
// Commands from the computer come on the channel
// that's the same as our number
llListen(num, "3-Body Simulator", "", "");
llListen(num, "Star Controls", "", "");
llListen(num, "", llGetOwner(), "");
}
listen(integer chan, string name, key id, string message)
{
integer firstspace;
string com;
string params;
// llSay(0, "Got command : '"+message+"'");
if (message == "reset" || message == "initialize") {
figurenumber();
return;
}
firstspace = llSubStringIndex(message, " ");
if (firstspace < 0) {
com = message;
params = "";
}
else {
com = llGetSubString(message, 0, firstspace-1);
params = llGetSubString(message, firstspace+1, -1);
}
// llSay(0, "Executing command : '" + com + "'");
// llSay(0, "Params : '" + params + "'");
if (com == "VEL") {
setvel((vector)params);
}
else if (com == "POS") {
setpos((vector)params);
}
else if (com == "MASS") {
setmass((float)params);
}
else if (com == "CTRPOS") {
ctrpos = (vector)params;
setminmax();
}
else if (com == "POSRANGE") {
posrange = (float)params;
setminmax();
}
else if (com == "DISPSCALE") {
dispscale = (float)params;
setminmax();
}
else if (com == "SHOWVEL") {
llSetLinkAlpha(2, 1.0, ALL_SIDES);
llSetLinkAlpha(3, 1.0, ALL_SIDES);
velshown = 1;
}
else if (com == "HIDEVEL") {
llSetLinkAlpha(2, 0.0, ALL_SIDES);
llSetLinkAlpha(3, 0.0, ALL_SIDES);
velshown = 0;
}
else if (com == "DUMP") {
llSay(0, "position : " + (string)llGetPos());
llSay(0, "rotation : " + (string)llGetRot());
}
else if (com == "RESET") {
llResetScript();
}
}
}