Object to Data v1.4

From Second Life Wiki
Revision as of 08:45, 27 April 2008 by Xaviar Czervik (talk | contribs) (Version 1.2 code added.)
Jump to navigation Jump to search

(http://www.gnu.org/copyleft/fdl.html) in the spirit of which this script is GPL'd. Copyright (C) 2008 Xaviar Czervik

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.


I'm not one for writing documentation, so I apologize in advance for the confusion of the following.

To convert an object into data...
1) Place down the object you want to convert to data.
2) Drop the Data Main script into the object.
3) When told to, drop the Object to Data script into the object.
4) After the object finishes gathering data,  Re-Rez the object and then go to 'Tools' -> 'Set Scripts to Running in Selection', and then Re-Rez the object again.
5) It will start to spew out data, copy this text in it's entirety and paste it into a note.

To convert data back to an object... 1) Place the desired note into the Data to Object object, and then touch it. 2) Stand back and wait for it to finish (this may take some time).

Now that you know how it works, start out by rezing a box and calling it "Data to Object", in it place an empty box called "HoloBox", as well as the following script.

Data to Object <lsl> key qid; integer line = 0; string name = "Data_Default"; string allData; integer prims; vector start;


setLink() {

   list l = llParseString2List(allData, ["-=-"], []);
   vector pos = (vector)llList2String(l, 0);
   pos += start;
   while (llVecDist(llGetPos(), pos) > .01) llSetPos(pos);
   list real;
   integer i = 1;
   while (i < llGetListLength(l)) {
       string this = llList2String(l, i);
       string thisPart = llGetSubString(this, 0, 1);
       if (thisPart == "#S") {
           real += (string)llGetSubString(this, 2, -1);
       } else if (thisPart == "#K") {
           real += (key)llGetSubString(this, 2, -1);
       } else if (thisPart == "#I") {
           real += (integer)llGetSubString(this, 2, -1);
       } else if (thisPart == "#F") {
           real += (float)llGetSubString(this, 2, -1);
       } else if (thisPart == "#V") {
           real += (vector)llGetSubString(this, 2, -1);
       } else if (thisPart == "#R") {
           real += (rotation)llGetSubString(this, 2, -1);
       }
       i++;
   }
   llSetLinkPrimitiveParams(LINK_ALL_OTHERS, real);

}

default {

   touch_start(integer i) {
       start = llGetPos();
       llOwnerSay("Start");
       llRequestPermissions(llGetOwner(), PERMISSION_CHANGE_LINKS);
   }
   run_time_permissions(integer p) {
       if (p & PERMISSION_CHANGE_LINKS) {
          line = 0;
          qid = llGetNotecardLine(name,line); 
       }
   }
   dataserver(key queryId, string data) {
       if (queryId == qid)  {
           if (data != EOF) {
               line += 1;
               data = llList2String(llParseString2List(data, ["-----: "], []), 1);
               if (data == "#START#") {
                   llRezObject("HoloBox", llGetPos() + <0,0,0>, <0,0,0>, <0,0,0,0>, 0);
               } else if (data == "#END#") {
                   setLink();
                   llBreakAllLinks();
                   allData = "";
               } else {
                   allData += data;
               }
               qid = llGetNotecardLine(name,line);
           } else {
               llSetTimerEvent(3);
           }
       }
   }
   timer() {
       llOwnerSay("Done");
       llSetTimerEvent(0);
   }
   object_rez(key k) {
       llCreateLink(k, 1);
   }

} </lsl>


Here are the two scripts required to turn an object into data:

Data Main <lsl> default {

   state_entry() {
       llRequestPermissions(llGetOwner(), PERMISSION_CHANGE_LINKS);
       if (llGetInventoryType("Object to Data") != -1) {
           state run;
       } else {
           llOwnerSay("Accept the permission to change links, and then place the 'Object to Data' script in me.");
       }
   }
   changed(integer num) {
       if (llGetInventoryType("Object to Data") != -1) {
           state run;
       }
   }

}

state run {

   state_entry() {
       llOwnerSay("Gathering data... Please wait. This may take some time.");
       llSetText("Loading...", <1,1,1>, 1);
       integer num = llGetNumberOfPrims();
       list lst;
       integer i = 1;
       while (i <= num) {
           lst += llGetLinkKey(i);
           i++;
       }
       llBreakAllLinks();
       i = 0;
       while (i < num) {
           llSetText((string)(((float)i*100.0)/((float)num)) + "% finished.", <1,1,1>, 1);
           llGiveInventory(llList2Key(lst, i), "Object to Data");
           llCreateLink(llList2Key(lst, i), 1);
           i++;
       }
       llSetText("", <1,1,1>, 1);
       llOwnerSay("Re-Rez this object and then go to 'Tools' -> 'Set Scripts to Running in Selection', and then Re-Rez this object again.");
       llRemoveInventory(llGetScriptName());
   }

} </lsl>


Object to Data <lsl> string hexc="0123456789ABCDEF";//faster

string Float2Hex(float input) {// Copyright Strife Onizuka, 2006-2007, LGPL, http://www.gnu.org/copyleft/lesser.html

   if((integer)input != input)//LL screwed up hex integers support in rotation & vector string typecasting
   {//this also keeps zero from hanging the zero stripper.
       float unsigned = llFabs(input);//logs don't work on negatives.
       integer exponent = llFloor(llLog(unsigned) / 0.69314718055994530941723212145818);//floor(log2(b)) + rounding error
       integer mantissa = (integer)((unsigned / (float)("0x1p"+(string)(exponent -= (exponent == 128)))) * 0x1000000);//shift up into integer range
       integer index = (integer)(llLog(mantissa & -mantissa) / 0.69314718055994530941723212145818);//index of first 'on' bit
       string str = "p" + (string)((exponent += index) - 24);
       mantissa = mantissa >> index;
       do
           str = llGetSubString(hexc,15&mantissa,15&mantissa) + str;
       while(mantissa = mantissa >> 4);
       if(input < 0)
           return "-0x" + str;
       return "0x" + str;
   }//integers pack well so anything that qualifies as an integer we dump as such, supports netative zero
   return llDeleteSubString((string)input,-7,-1);//trim off the float portion, return an integer

}


string safeVector(vector v) {

   return "<"+safeFloat(v.x)+","+safeFloat(v.y)+","+safeFloat(v.z)+">";

}

string safeRotation(rotation v) {

   return "<"+safeFloat(v.x)+","+safeFloat(v.y)+","+safeFloat(v.z)+","+safeFloat(v.s)+">";

}

string safeFloat(float f) {

   return Float2Hex(f);

}

string list2string(list l) {

   string ret;
   integer len = llGetListLength(l);
   integer i;
   
   while (i < len) {
       integer type = llGetListEntryType(l, i);
       if (type == 1) {
           ret += "#I"+(string)llList2Integer(l, i);
       } else if (type == 2) {
           ret += "#F"+safeFloat(llList2Float(l, i));
       } else if (type == 3) {
           ret += "#S"+llList2String(l, i);
       } else if (type == 4) {
           ret += "#K"+(string)llList2Key(l, i);
       } else if (type == 5) {
           ret += "#V"+safeVector(llList2Vector(l, i));        
       } else if (type == 6) {
           ret += "#R"+safeRotation(llList2Rot(l, i));
       }
       ret += "-=-";
       i++;
   }
   return ret;

}

string getTexture() {

   string ret;
   
   integer sides = llGetNumberOfSides();
   
   integer same = 1;
   list texture;
   list repeat;
   list offset;
   list rot;
   
   integer i = 0;
   while (i < sides) {
       list side  = llGetPrimitiveParams([PRIM_TEXTURE, i]);
       texture += llList2String(side, 0);
       repeat  += llList2Vector(side, 1);
       offset  += llList2Vector(side, 2);
       rot     += llList2Float(side, 3);
       
       if (!(llList2String(texture, i) == llList2String(texture, i-1) && llList2Vector(repeat, i) == llList2Vector(repeat, i-1) &&
           llList2Vector(offset, i) == llList2Vector(offset, i-1) && llList2Float(rot, i) == llList2Float(rot, i-1))) {
               same = 0;
       }
       i++;
   }
   if (same) {
       ret += list2string([PRIM_TEXTURE, ALL_SIDES, llList2String(texture, 0), llList2Vector(repeat, 0), llList2Vector(offset, 0), llList2Float(rot, 0)]);
   } else {
       integer j = 0;
       while (j < llGetListLength(texture)) {
           ret += list2string([PRIM_TEXTURE, j, llList2String(texture, j), llList2Vector(repeat, j), llList2Vector(offset, j), llList2Float(rot, j)]);
           j++;
       }
   }        
   
   return ret;

}


string getColor() {

   string ret;
   integer sides = llGetNumberOfSides();
   
   integer same = 1;
   list color;
   list alpha;
   
   integer i = 0;
   while (i < sides) {
       list side  = llGetPrimitiveParams([PRIM_COLOR, i]);
       alpha += llList2Float(side, 1);
       color  += llList2Vector(side, 0);
       
       if (!(llList2String(color, i) == llList2String(color, i-1) && llList2Vector(alpha, i) == llList2Vector(alpha, i-1))) {
               same = 0;
       }
       i++;
   }
   if (same) {
       ret += list2string([PRIM_COLOR, ALL_SIDES, llList2Vector(color, 0), llList2Float(alpha, 0)]);
   } else {
       integer j = 0;
       while (j < llGetListLength(color)) {
           ret += list2string([PRIM_COLOR, j, llList2Vector(color, j), llList2Float(alpha, j)]);
           j++;
       }
   }        
   
   return ret;

}

string getShiny() {

   string ret;
   integer sides = llGetNumberOfSides();
   
   integer same = 1;
   list shiny;
   list bump;
   
   integer i = 0;
   while (i < sides) {
       list side  = llGetPrimitiveParams([PRIM_BUMP_SHINY, i]);
       shiny += llList2Integer(side, 0);
       bump += llList2Integer(side, 1);
       
       if (!(llList2Integer(shiny, i) == llList2Integer(shiny, i-1) && llList2Integer(bump, i) == llList2Integer(bump, i-1))) {
               same = 0;
       }
       i++;
   }
   if (same) {
       ret += list2string([PRIM_BUMP_SHINY, ALL_SIDES, llList2Integer(shiny, 0), llList2Integer(bump, 0)]);
   } else {
       integer j = 0;
       while (j < llGetListLength(shiny)) {
           ret += list2string([PRIM_BUMP_SHINY, j, llList2Integer(shiny, j), llList2Integer(bump, j)]);
           j++;
       }
   }        
   
   return ret;

} string getBright() {

   string ret;
   integer sides = llGetNumberOfSides();
   
   integer same = 1;
   list fullbright;
   
   integer i = 0;
   while (i < sides) {
       list side  = llGetPrimitiveParams([PRIM_FULLBRIGHT, i]);
       fullbright += llList2Integer(side, 0);
       
       if (!(llList2Integer(fullbright, i) == llList2Integer(fullbright, i-1))) {
               same = 0;
       }
       i++;
   }
   if (same) {
       ret += list2string([PRIM_FULLBRIGHT, ALL_SIDES, llList2Integer(fullbright, 0)]);
   } else {
       integer j = 0;
       while (j < llGetListLength(fullbright)) {
           ret += list2string([PRIM_FULLBRIGHT, j, llList2Integer(fullbright, j)]);
           j++;
       }
   }        
   
   return ret;

}

vector getPos() {

   vector pos = llList2Vector(llGetPrimitiveParams([PRIM_POSITION]), 0);
   pos -= llList2Vector(llGetObjectDetails(llGetLinkKey(0), [OBJECT_POS]), 0);
   if (llGetLinkNumber() == 1) {
       pos = <0,0,0>;
   }
   return pos;

}

string getType() {

   list type = [PRIM_TYPE] + llGetPrimitiveParams([PRIM_TYPE]);
   type += [PRIM_PHYSICS] + llGetPrimitiveParams([PRIM_PHYSICS]);
   type += [PRIM_MATERIAL] + llGetPrimitiveParams([PRIM_MATERIAL]);
   type += [PRIM_TEMP_ON_REZ] + llGetPrimitiveParams([PRIM_TEMP_ON_REZ]);
   type += [PRIM_PHANTOM] + llGetPrimitiveParams([PRIM_PHANTOM]);
   type += [PRIM_ROTATION] + llGetPrimitiveParams([PRIM_ROTATION]);
   type += [PRIM_SIZE] + llGetPrimitiveParams([PRIM_SIZE]);
   type += [PRIM_FLEXIBLE] + llGetPrimitiveParams([PRIM_FLEXIBLE]);
   type += [PRIM_POINT_LIGHT] + llGetPrimitiveParams([PRIM_POINT_LIGHT]);
   type += [PRIM_CAST_SHADOWS] + llGetPrimitiveParams([PRIM_CAST_SHADOWS]);
   return list2string(type);

}


string getPrimitiveParams() {

   string ret;
   ret += getType();
   ret += getTexture();
   ret += getShiny();
   ret += getColor();
   ret += getBright();
   return ret;

}

default {

   on_rez(integer i) {
       if (llGetInventoryType("Replicate Main") == -1) {
           string s = getPrimitiveParams();
           s = safeVector(getPos()) + "-=-" + s;
           llSetObjectName("-----");
           llSleep(llGetLinkNumber());
           llOwnerSay("#START#");
           integer i = 0;
           while (i < llStringLength(s)) {
               llOwnerSay((string)llGetSubString(s, i, i+199));
               i += 200;
           }
           llOwnerSay("#END#");
       }
   }

} </lsl> </lsl>