LSL Script : Star Init. Conditions Console

From Micasim

Jump to: navigation, search
// Star Initial Condition Panel for the 3-Body Simulator v1.3 by Rob Knop

// Copyright (C) 2009 Rob Knop
//
// 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 star = 1;
integer xyoffset = 0;
vector ctrpos = <0., 0., 0.>;
float posrange = 15.;
float minmass = 0.1;
float maxmass = 9.9;

float mass = 1.0;
float posx;
float posy;
float posz;
float velx;
float vely;
float velz;

integer starcomputerchan = 16384;
integer updateschan = 4096;

integer DISPLAY_STRING      = 204000; 

updatestarcomputer()
{
    vector pos = <posx, posy, posz>;
    vector vel = <velx, vely, velz>;
    
    llRegionSay(starcomputerchan, "starmass " + (string)star + " " + (string)mass);
    llSay(0, "starmass " + (string)star + " " + (string)mass);
    llRegionSay(starcomputerchan, "starpos " + (string)star + " " + (string)pos);
    llSay(0, "starpos " + (string)star + " " + (string)pos);
    llRegionSay(starcomputerchan, "starvel " + (string)star + " " + (string)vel);
    llSay(0, "starvel " + (string)star + " " + (string)vel);
}

updateposvel(integer axis, float amt, integer posvel)
{
    float val;
    float maxval;
    float minval;
    
    if (posvel) {
        maxval = 9.9;
        minval = -9.9;
        if (axis == 1) val = velx;
        else if (axis == 2) val = vely;
        else val = velz;
    } else {
        if (axis == 1) {
            val = posx;
            minval = ctrpos.x - posrange;
            maxval = ctrpos.x + posrange;
        }
        else if (axis == 2) {
            val = posy;
            minval = ctrpos.y - posrange;
            maxval = ctrpos.y + posrange;
        }
        else {
            val = posz;
            minval = ctrpos.z - posrange;
            maxval = ctrpos.z + posrange;
        }
    }
    
    val += amt;
    if (val < minval) val = minval;
    if (val > maxval) val = maxval;
    
    if (posvel) {
        if      (axis == 1) velx = val;
        else if (axis == 2) vely = val;
        else if (axis == 3) velz = val;
    }
    else {
        if      (axis == 1) posx = val;   // Wouldn't it be nice if LSL had arrays?
        else if (axis == 2) posy = val;
        else if (axis == 3) posz = val;
    }
    
    updatewidget(axis);
    updatestar();
}

updatestar() {
    vector pos = <posx, posy, posz>;
    vector vel = <velx, vely, velz>;
    
    llRegionSay(star, "POS " + (string)pos);
    llRegionSay(star, "VEL " + (string)vel);
}

updatewidget(integer axis)
{
    float pos;
    float vel;
    string posstr;
    string velstr;
    integer pointdex;
    
    if (axis == 1) {
        pos = posx;
        vel = velx;
    }
    else if (axis == 2) {
        pos = posy;
        vel = vely;
    }
    else if (axis == 3) {
        pos = posz;
        vel = velz;
    }
    
    posstr = "     " + (string)(llFloor(10.*pos + 0.5)/10.);
    pointdex = llSubStringIndex(posstr, ".");
    if (pointdex < 0) pointdex = -2;
    posstr = llGetSubString(posstr, pointdex-3, pointdex+1);

    if (vel < 0) velstr = "     -" + (string)(llFloor(100.*vel + 0.5)/100.);
    else         velstr = "     +" + (string)(llFloor(100.*vel + 0.5)/100.);
    pointdex = llSubStringIndex(velstr, ".");
    if (pointdex < 0) pointdex = -3;
    velstr = llGetSubString(velstr, pointdex-2, pointdex+2);     
    
    llMessageLinked(LINK_THIS, DISPLAY_STRING, posstr+velstr, (string)(axis+xyoffset));
}

updatemasswidget()
{
    string str = "     " + (string)mass;
    integer pointdex = llSubStringIndex(str, ".");
    if (pointdex < 0) pointdex = -2;
    str = llGetSubString(str, pointdex-3, pointdex+1);
    llMessageLinked(LINK_THIS, DISPLAY_STRING, str, (string)xyoffset);
}


default
{
    state_entry()
    {
        llListen(updateschan, "3-Body Simulator", "", "");
        posx = ctrpos.x;
        posy = ctrpos.y;
        posz = ctrpos.z;
        velx = 0.;
        vely = 0.;
        velz = 0.;
        
        updatemasswidget();
        updatewidget(1);
        updatewidget(2);
        updatewidget(3);
    }
    
    touch_start(integer num)
    {        
        integer sign;
        float mag;
        string str;
        integer posvel;
        integer axis;
    
        vector touchpos = llDetectedTouchUV(0);
        float u = touchpos.x;
        float v = touchpos.y;
        
        if (u >= 0.69 && u <= 1.0 && v >= 0 && v <= 0.1)
        {
            updatestarcomputer();
            return;
        }
        
        if (v >= 0.68)      // Mass
        {
            if (v >= 0.68 && v <= 0.72) sign = -1;
            else if (v >= 0.84 && v <= 0.88) sign = 1;
            else return;
            
            if (u >= 0.35 && u <= 0.40) mag = 0.1;
            else if (u >= 0.42 && u <= 0.50) mag = 1.0;
            else return;
            
            mass += mag*sign;
            if (mass < minmass) mass = minmass;
            if (mass > maxmass) mass = maxmass;
            mass = llFloor(10.*mass + 0.5)/10.;
            updatemasswidget();
            llRegionSay(star, "MASS " + (string)mass);

            return;
        }
        
        if (u >= 0.035 && u <= 0.12) {
            posvel = 0;
            sign = 1;
        }
        else if (u >= 0.385 && u <= 0.46) {
            posvel = 0;
            sign = -1;
        }
        else if (u >= 0.52 && u <= 0.6) {
            posvel = 1;
            sign = 1;
        }
        else if (u >= 0.86 && u <= 0.93) {
            posvel = 1;
            sign = -1;
        }
        else return;
        
        if (v > 0.19 && v < 0.24) {
            axis = 3;
            mag = 0.1;
        }
        else if (v > 0.24 && v < 0.29) {
            axis = 3;
            mag = 1;
        }
        else if (v > 0.33 && v < 0.38) {
            axis = 2;
            mag = 0.1;
        }
        else if (v > 0.38 && v < 0.43) {
            axis = 2;
            mag = 1;
        }
        else if (v > 0.465 && v < 0.515) {
            axis = 1;
            mag = 0.1;
        }
        else if (v > 0.515 & v < 0.565) {
            axis = 1;
            mag = 1;
        }
        else return;
        
        if (posvel == 1 && mag < 0.5) mag/=2.;
        
        updateposvel(axis, mag*sign, posvel);
    }
    
    
    // **********************************************
    
    listen(integer chan, string name, key id, string msg)
    {
        list params = llParseString2List(msg, [" "], []);

        if (llList2Integer(params, 1) != star) return;
        
        string com = llList2String(params, 0);
        string val = llDumpList2String(llList2List(params,2,-1), " ");
        vector vec;
        
        if (com == "initmass") {
            mass = (float)val;
            updatemasswidget();
            llRegionSay(star, "MASS " + (string)mass);
        }
        else if (com == "initpos") {
            vec = (vector)val;
            posx = vec.x;
            posy = vec.y;
            posz = vec.z;
            updatewidget(1);
            updatewidget(2);
            updatewidget(3);
            updatestar();
        }
        else if (com == "initvel") {
            vec = (vector)val;
            velx = vec.x;
            vely = vec.y;
            velz = vec.z;
            updatewidget(1);
            updatewidget(2);
            updatewidget(3);
            updatestar();
        }     
    }
}