Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

[LIBRARY]: ColorControl and ColorChange

Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
05-02-2009 09:25
These two companion scripts were intended for use in a demo for SL newcomers, to illustrate how colors are expressed as RGB components of a vector. The ColorChange script, however, could be dropped into any prim on which a user wanted to be able to adjust color on touch (for example, on the wall of a house). The ColorControl script operates a one-prim panel, responding to llDetectedTouchUV, that communicates with ColorChange to do its work.

Here's the first script ...............

CODE

//ColorControl by Rolig Loon -- April 2009
//Controls the companion script, ColorChange, which is placed in a prim that you want to recolor.
//This script goes in a prim with one face textured as a 2 column x 4 row matrix (using texture f3fb210a-0fad-5e41-3be9-230a0ca68dce):
// ________________
// | | |
// | R- | R+ |
// |_______|_______|
// | | |
// | G- | G+ |
// |_______|_______|
// | | |
// | B- | B+ |
// |_______|_______|
// | | |
// | Darker | Lighter |
// |_______|_______|
//
//Clicking in column 1 (left) decreases values of R, G, B, or total intensity in the controlled prim.
//Clicking in column 2 (right) increases values of R, G, B, or total intensity in the controlled prim.
//Row 1 (top) controls R, Row 2 controls G, Row 3 controls B, and Row 4 (bottom) controls darkness/lightness.
//
//Type REDO in channel 12 to reset the color in the controlled prim to its initial state.
//Type DONE in channel 12 to end the color changing process and remove the script from the controlled prim.
//
integer CHANNEL = -1798;
default
{
state_entry()
{
llListen(12,"",NULL_KEY,"");
llSetTexture("f3fb210a-0fad-5e41-3be9-230a0ca68dce",2); //Puts grid texture on face 2 of your control prim
}
listen (integer channel, string name, key id, string message)
{
if (llToUpper(message) == "DONE")
{
llSay(CHANNEL,"Done!");
}
else if (llToUpper(message) == "REDO")
{
llSay(CHANNEL, "Ooops!");
}
}

touch(integer total_number)
{
vector UV = llDetectedTouchUV(0);
string signal;
if (UV.x <= 0.5 & UV.y <= 0.25)
{
signal = "D-";
}
else if (UV.x >0.5 & UV.y <= 0.25)
{
signal = "D+";
}
else if (UV.x <= 0.5 & UV.y > 0.25 & UV.y <= 0.5)
{
signal = "B-";
}
else if (UV.x > 0.5 & UV.y > 0.25 & UV.y <= 0.5)
{
signal = "B+";
}
else if (UV.x <= 0.5 & UV.y > 0.5 & UV.y <= 0.75)
{
signal = "G-";
}
else if (UV.x > 0.5 & UV.y > 0.5 & UV.y <= 0.75)
{
signal = "G+";
}
else if (UV.x <= 0.5 & UV.y > 0.75)
{
signal = "R-";
}
else if (UV.x > 0.5 & UV.y > 0.75)
{
signal = "R+";
}
llSay(CHANNEL, signal);
}
}


And here's the second one .........

CODE


//ColorChange by Rolig Loon -- April 2009
//Place this script in the prim that you want to modify.
//Click on a face to identify it as the one to be recolored.
// This script will remove itself if you type DONE in channel 12 when you have finished.
integer touchedFace;
vector color;
vector SaveColor;
integer channel = -1798;
default
{
state_entry()
{
llSay(0,"Initializing ....");
llListen(channel,"",NULL_KEY,"");
}
touch_start(integer total_number)
{
integer i;
for (i = 0; i < total_number; i++)
{
touchedFace = llDetectedTouchFace(i);

if (touchedFace == -1)
{
llWhisper(0, "Sorry, this routine will not work with your version of the SL viewer.");
}
color = llGetColor(touchedFace);
SaveColor = color;
llSay(0,"Ready. Use the control panel to adjust the color on face " + (string)touchedFace + ".");
}
}
listen(integer channel, string name, key id, string message)
{
if(message == "R+")
{color.x += 0.01;}
if (message == "R-")
{color.x -= 0.01;}
if (color.x <= 0.0)
{color.x = 0.0;}
if (color.x >= 1.0)
{color.x = 1.0;}
if(message == "G+")
{color.y += 0.01;}
if (message == "G-")
{color.y -= 0.01;}
if (color.y <= 0.0)
{color.y = 0.0;}
if (color.y >= 1.0)
{color.y = 1.0;}
if(message == "B+")
{color.z += 0.01;}
if (message == "B-")
{color.z -= 0.01;}
if (color.z <= 0.0)
{color.z = 0.0;}
if (color.z >= 1.0)
{color.z = 1.0;}
if (message == "D+")
{color = color * (1.01);}
if (message == "D-")
{color = color /1.01;}
if(message == "Ooops!")
{
llSetColor(SaveColor,touchedFace);
llSay(0,"Returning face " + (string)touchedFace + " to its initial color.");
llResetScript();
}
else if (message == "Done!")
{
llSay(0,"Task completed. Removing script....");
llRemoveInventory(llGetScriptName());
}
llSetColor(color, touchedFace);
llSetText((string)color,color,1.0); //Remove to get rid of floating text for non-demo use
}
}
_____________________
It's hard to tell gender from names around here but if you care, Rolig = she. And I exist only in SL, so don't ask.... ;)

Look for my work in XStreetSL at
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
05-02-2009 13:32
list gLstColors = [<1 / 255.0, 1 / 255.0, 1 / 255.0>, <1 / 255.0, 0.0, 0.0>, <0.0, 1 / 255.0, 0.0>, <0.0, 0.0, 1 / 255.0>];

llSay( CHANNEL, (string)(llList2Vector( gLstColors, (integer)(UV.y / .25) ) *
(1 - llRound( UV.x ) * 2) );

then cast the input in the second script to a vector, add it to llGetColor-face, and use the library function that I recently posted to clamp the range to [0, 1]. no more if branching
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
05-02-2009 13:57
Oh, now that's nice. :) It's less intuitive on first glance than my brute force approach, but much tighter and more elegant. Let me play with it a bit.
_____________________
It's hard to tell gender from names around here but if you care, Rolig = she. And I exist only in SL, so don't ask.... ;)

Look for my work in XStreetSL at
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
05-02-2009 14:10
WOOHOO! Glad to see the contribution Rolig!
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
05-02-2009 14:13
From: Jesse Barnett
WOOHOO! Glad to see the contribution Rolig!

;)
_____________________
It's hard to tell gender from names around here but if you care, Rolig = she. And I exist only in SL, so don't ask.... ;)

Look for my work in XStreetSL at
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
05-02-2009 18:18
From: Void Singer
list gLstColors = [<1 / 255.0, 1 / 255.0, 1 / 255.0>, <1 / 255.0, 0.0, 0.0>, <0.0, 1 / 255.0, 0.0>, <0.0, 0.0, 1 / 255.0>];

llSay( CHANNEL, (string)(llList2Vector( gLstColors, (integer)(UV.y / .25) ) *
(1 - llRound( UV.x ) * 2) );

then cast the input in the second script to a vector, add it to llGetColor-face, and use the library function that I recently posted to clamp the range to [0, 1]. no more if branching


Void, I can't see anything wrong with gLstColors as you have written it. It compiles fine in the LSL editor off line, but kicks up a syntax error in SL. Any ideas why?:confused:
_____________________
It's hard to tell gender from names around here but if you care, Rolig = she. And I exist only in SL, so don't ask.... ;)

Look for my work in XStreetSL at
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
05-02-2009 18:40
eh, the compiler doesn't like to do math in the globals area...

you can cheat and list them all as 1.0, then in llsay multiple them them by (1/255.0) so like....
(string)(llList2Vector( gLstColors, (integer)(UV.y / .25) ) * (1/255.0) * (1 - llRound( UV.x ) * 2)

(1 - llRound( UV.x ) * 2)
this part took me a minute to figure out... it's very hard to get -1|1 out of [0.0, 1.0] so I force it to true|false and subtract what needs be out of 1 to get negative 1... although looking at it I may have it backwards in which case it needs to be
(llRound( UV.x ) * 2 - 1)

there IS a Very Tiny chance (on the top? edge) that (integer)(UV.y / .25) might come up as 4 (UV.y = 1.0) which will make it default to the bottom (or all colors )
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
05-03-2009 10:24
This is kinda fun! :) I've used Void's suggestions to create an alternative pair of scripts that behaves the same way as my original ones, but uses different logic. I've only tweaked Void's formula a bit to get the touch event to respond to the proper parts of the control grid. Here are the scripts .....

CODE

//ColorControl by Rolig Loon -- April 2009
// Alternate version, suggested by Void Singer
//Controls the companion script, ColorChange, which is placed in a prim that you want to recolor.
//This script goes in a prim with one face textured as a 2 column x 4 row matrix (using texture
f3fb210a-0fad-5e41-3be9-230a0ca68dce):
// ________________
// | | |
// | R- | R+ |
// |_______|_______|
// | | |
// | G- | G+ |
// |_______|_______|
// | | |
// | B- | B+ |
// |_______|_______|
// | | |
// | Darker|Lighter|
// |_______|_______|
//
//Clicking in column 1 (left) decreases values of R, G, B, or total intensity in the controlled prim.
//Clicking in column 2 (right) increases values of R, G, B, or total intensity in the controlled prim.
//Row 1 (top) controls R, Row 2 controls G, Row 3 controls B, and Row 4 (bottom) controls darkness/lightness.
//
//Type REDO in channel 12 to reset the color in the controlled prim to its initial state.
//Type DONE in channel 12 to end the color changing process and remove the script from the controlled prim.
//
integer CHANNEL = -1798;
list gLstColors = [<1.0,1.0,1.0>,<0.0,0.0,1.0>,<0.0,1.0,0.0>,<1.0,0.0,0.0>];
default
{
state_entry()
{
llListen(12,"",NULL_KEY,"");
llSetTexture("f3fb210a-0fad-5e41-3be9-230a0ca68dce",2); //Puts grid texture on face 2 of your control prim
}
listen (integer channel, string name, key id, string message)
{
if (llToUpper(message) == "DONE")
{
llSay(CHANNEL,"Done!");
}
else if (llToUpper(message) == "REDO")
{
llSay(CHANNEL, "Ooops!");
}
}

touch(integer total_number)
{
vector UV = llDetectedTouchUV(0);
llSay( CHANNEL, (string)(llList2Vector( gLstColors, (integer)(UV.y / .25) ) * (1/255.0) *( 1- llRound( 1.0 - UV.x ) * 2)));
}
}


And ....

CODE

//ColorChange by Rolig Loon -- April 2009
//Place this script in the prim that you want to modify.
//Click on a face to identify it as the one to be recolored.
// This script will remove itself if you type DONE in channel 12 when you have finished.
//
//The function fVecRangeXY was written by Void Singer (see http://forums.secondlife.com/showthread.php?t=317223)
integer face;
vector color;
vector SaveColor;
integer channel = -1798;
vector fVecRangeXY( vector vVecRaw, float vFltMin, float vFltMax ){
return <(vFltMin < vVecRaw.x && vVecRaw.x <= vFltMax) * vVecRaw.x,
(vFltMin < vVecRaw.y && vVecRaw.y <= vFltMax) * vVecRaw.y,
(vFltMin < vVecRaw.z && vVecRaw.z <= vFltMax) * vVecRaw.z>
+ <(vVecRaw.x < vFltMin),
(vVecRaw.y < vFltMin),
(vVecRaw.z < vFltMin)> * vFltMin
+ <(vVecRaw.x > vFltMax),
(vVecRaw.y > vFltMax),
(vVecRaw.z > vFltMax)> * vFltMax;
}

default
{
state_entry()
{
llSay(0,"Initializing ....");
llListen(channel,"",NULL_KEY,"");
color = llGetColor(0); // Defaults to face zero on startup
}
touch_start(integer total_number)
{
face = llDetectedTouchFace(0); //Triggers change on selected face
color = llGetColor(face);
llSetText((string)color,color,1.0); //Remove to get rid of floating text
SaveColor = color;
llSay(0,"Ready. Use the control panel to adjust the color on face " + (string)face + ".");
}
listen(integer channel, string name, key id, string message)
{
if(message == "Ooops!")
{
llSetColor(SaveColor,face);
llSetText((string)SaveColor,SaveColor,1.0); //Remove to get rid of floating text
llSay(0,"Returning face " + (string)face + " to its initial color.");
llResetScript();
}
else if (message == "Done!")
{
llSay(0,"Task completed. Removing script....");
llRemoveInventory(llGetScriptName());
}
else
{
vector ModColor = (vector)message;
color = color + ModColor;
color = fVecRangeXY(color,0.0,1.0);
llSetColor(color, face);
llSetText((string)color,color,1.0); //Remove to get rid of floating text
}
}
}
_____________________
It's hard to tell gender from names around here but if you care, Rolig = she. And I exist only in SL, so don't ask.... ;)

Look for my work in XStreetSL at
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
05-03-2009 13:14
( 1- llRound( 1.0 - UV.x ) * 2)
Uv.x = 0.0 (edge case)
result 1 (reversal)

(2 * llRound( UV.x ) - 1)
removes edge cases

";(integer)(4 * UV.y - .001)" instead of "llRound( UV.y / .25)"
should also eliminate the edge case in my other calculation with only a (0.25)% overall shift to the left in the border positions. (sorry about that).
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
05-03-2009 13:42
From: Void Singer
( 1- llRound( 1.0 - UV.x ) * 2)
Uv.x = 0.0 (edge case)
result 1 (reversal)

(2 * llRound( UV.x ) - 1)
removes edge cases

";(integer)(4 * UV.y - .001)" instead of "llRound( UV.y / .25)"
should also eliminate the edge case in my other calculation with only a (0.25)% overall shift to the left in the border positions. (sorry about that).


Yeah, I played with that formula a bit because the way you had it written reversed left for right on the control grid, so that clicks on the right column decreased RGB values and those on the left increased them. I worried only briefly about the edge cases because the probability that a user might click exactly on one of them is vanishingly small. Still, for completeness you are right.

Incidentally, I also rearranged the gLstColors vector because clicks on the control panel were being read in the order BRG instead of RGB.

All in all, I'm VERY pleased that you tossed out this suggestion. I learned some fun things by trying it out, and now we have two functioning scripts. Thanks, Void! :D
_____________________
It's hard to tell gender from names around here but if you care, Rolig = she. And I exist only in SL, so don't ask.... ;)

Look for my work in XStreetSL at