• Bitte schaltet eure Ad Blocker aus. SLinfo kann nur betrieben werden, wenn es durch Werbung Einnahmen erzielt. Vielen Dank!!
  • Wir freuen uns, wenn du dich in unserem Forum anmeldest. Bitte beachte, dass die Freigabe per Hand durchgeführt wird (Schutz vor Spammer). Damit kann die Freigabe bis zu 24 Stunden dauern.
  • Wir verwenden Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten zu können und die Zugriffe auf unsere Website zu analysieren. Sie geben Einwilligung zu unseren Cookies, wenn Sie unsere Webseite weiterhin nutzen.

Dialog für Farbeinstellung per Hexcode möglich?

Maxi Farella

Aktiver Nutzer
Hallo

Ich baue gerne Dinge mit schwarzweißen Texturen, wo ich dann in SL im Baumenü unter Textur jede beliebige farbe hinzufügen kann.
Jetzt habe ich überlegt, für den verkauf solcher Dinge einen Dialog zu scripten, in dem die Käufer dann die Farbe nach ihrem Geschmack einstellen können.
Ich möchte die Sachen nämlich "no mod" machen, damit außer der Farbe nix verändert werden kann.

Gibt es vielleicht einen Weg, in einen Dialog ein Textfeld zu scripten, wo dann ein Hex-Code, wie auf einigen Internet-Seiten, eingegebenwerden kann, aus dem dann die Farbe für das Objekt ermittelt wird?

Beispiel für Hex-code:
ffff00 : grelles gelb
ffdf00 : warmes gelb
0000ff : blau
 
Zuletzt bearbeitet:
Warum unbedingt Hex-Code?
Vector Code ist doch viel einfacher.

Beispiel:
Code:
vector rot = <1.0, 0.0, 0.0>;
vector gruen = <0.0, 1.0, 0.0>;
vector blau = <0.0, 0.0, 1.0>;

Die einzelnen floats im code kannst du gezielt veraendern.

LG
Dae
 
Zuletzt bearbeitet:
Hallo

Ich baue gerne Dinge mit schwarzweißen Texturen, wo ich dann in SL im Baumenü unter Textur jede beliebige farbe hinzufügen kann.
Jetzt habe ich überlegt, für den verkauf solcher Dinge einen Dialog zu scripten, in dem die Käufer dann die Farbe nach ihrem Geschmack einstellen können.
Ich möchte die Sachen nämlich "no mod" machen, damit außer der Farbe nix verändert werden kann.

Gibt es vielleicht einen Weg, in einen Dialog ein Textfeld zu scripten, wo dann ein Hex-Code, wie auf einigen Internet-Seiten, eingegebenwerden kann, aus dem dann die Farbe für das Objekt ermittelt wird?

Beispiel für Hex-code:
ffff00 : grelles gelb
ffdf00 : warmes gelb
0000ff : blau

klar , Prinzipiell schon.
Der HTML Hex-Code besteht einfach aus 3 Hex-Zahlen (sechzehner-System) hintereinander, die für die RGB Werte stehen.

ffff00 ist so eben ff ff 00. Das sind jeweils 3 Zahlen von 0 (00) bis 255 (ff).
Also hast du das 3-Tupel ff,ff,00 im Hexadezimalsytem und 255, 255, 0 im Dezimalsystem.

Hexadezimalzahlen lassen sich in LSL durch voranstellen von "0x" als solche Kennzeichen.

Also hat man einfach den Vector <0xff,0xff,0x00> für grelles gelb.
Warmes gelb wäre dann <0xff,0xdf,0x00>. Und blau wäre <0x00,0x00,0xff>.


Den Parser um aus ffff00 eben mal <0xff,0xff,0x00> zu bauen hab ich mir hier mal gespart, das ist eigentlich eher trivial, da muss man nur bisschen was in den String "ffff00" mit einbauen.
 
Hallo

Ich baue gerne Dinge mit schwarzweißen Texturen, wo ich dann in SL im Baumenü unter Textur jede beliebige farbe hinzufügen kann.
Jetzt habe ich überlegt, für den verkauf solcher Dinge einen Dialog zu scripten, in dem die Käufer dann die Farbe nach ihrem Geschmack einstellen können.
Ich möchte die Sachen nämlich "no mod" machen, damit außer der Farbe nix verändert werden kann.

Gibt es vielleicht einen Weg, in einen Dialog ein Textfeld zu scripten, wo dann ein Hex-Code, wie auf einigen Internet-Seiten, eingegebenwerden kann, aus dem dann die Farbe für das Objekt ermittelt wird?

Beispiel für Hex-code:
ffff00 : grelles gelb
ffdf00 : warmes gelb
0000ff : blau

Ich habe dir ein Beispiel dafür geschrieben und in meine Skriptsammlung hochgeladen: http://forumvirtuellewelten.de/default.aspx?g=posts&m=3117

Edit: Danke an Shirley für ihre Denkanstöße.
 
Zuletzt bearbeitet:
Wofür ist denn dieser Teil vom Script?
integer Ord(string chr)
{
if (chr == "")
return 0;
chr = llGetSubString(chr, 0, 0);
string hex = llEscapeURL(chr);
if (llGetSubString(hex, 0, 0) != "%")
{
// Regular character - we can't take advantage of llEscapeURL in this case,
// so we use llStringToBase64/llBase64ToInteger instead.
return llBase64ToInteger("AAAA" + llStringToBase64(chr));
}
integer b = (integer)("0x" + llGetSubString(hex, 1, 2));
if (b < 194 || b > 244)
return b;
if (b < 224)
return ((b & 0x1F) << 6) | (integer)("0x" + llGetSubString(hex, 4, 5)) & 0x3F;
integer cp;
if (b < 240)
{
cp = (b & 0x0F) << 12;
cp += ((integer)("0x" + llGetSubString(hex, 4, 5)) & 0x3F) << 6;
cp += (integer)("0x" + llGetSubString(hex, 7, 8)) & 0x3F;
return cp;
}
cp = (b & 0x07) << 18;
cp += ((integer)("0x" + llGetSubString(hex, 4, 5)) & 0x3F) << 12;
cp += ((integer)("0x" + llGetSubString(hex, 7, 8)) & 0x3F) << 6;
cp += (integer)("0x" + llGetSubString(hex, 10, 11)) & 0x3F;
return cp;
}
 
Aber warum der Umweg über die Ordinalzahl? Wen man eh weiß auf was man testen will, wieso tested man nicht direkt auf das entsprechende Zeichen?

In diesem Fall z.B. in der Form:
Code:
integer IsValidString(string input)
{
    string allowedChars = "0123456789abcdef";
    input = llStringTrim(llToLower(input), STRING_TRIM);
    integer length = llStringLength(input);
    if(length != 6)
        return 0;
    integer i;
    for( i = 0; i < length; i++ ) 
    {
        if(llSubStringIndex(allowedChars, llGetSubString(input, i, i)) == -1) 
            return 0;
    }
    return 1;
}
Man geht alle Zeichen durch und versucht den Index des zu testenden Zeichens in allowedChars zu ermitteln. Gelingt dies, handelt es sich um ein erlaubtes Zeichen. Andernfalls kehrt die Funktion direkt mit dem Wert 0 zurück. (StringTrim und ToLower dienen zum säubern der Eingabe. Kann man, bzw. sollte man, auch auslagern.)
 
Das geht natürlich auch. Ich fand es bequem, mit der bereits vorhandenen UD-Funktion Ord() nur noch den Zahlenbereich überprüfen zu müssen (Unicode-Zeichen zwischen 48-57 und 97-102 sind gültig).


Man kanns natürlich noch einfacher machen, z.B. so:
Code:
integer iIsHexChar(string s)
{
    if (llStringLength(s) != 1)
    {
        return FALSE;
    }
    if (s != "0" && (float)("0x"+s) == 0)
    {
        return FALSE;
    }
    return TRUE;
}

Mir ging es bei dem Beispiel nicht um eine perfekte Überprüfung ob ein String ein gültiger Hex-Code-Character ist.
 
Zuletzt bearbeitet:
Ich hab die Funktion gerade bei mir mal ausprobiert und da geht es (SL).

Vieleicht irgendwo in deinem Code ein Semikolon vergessen (der Klassiker :D ) oder die Funktion an einer falschen Stelle eingefügt. (z.B. dürfen Funktionen nicht zwischen zwei States plaziert werden, etc.)

Wobei ich aber sagen würde, nimm die Funktion von Martin (oder pass sie dir an). Die ist kompakter, eleganter und vermutlich auch performanter als meine. ;)
 
Zuletzt bearbeitet:
Ich möchte das in einen Dialog mit 2 knöpfen einbetten.
einer soll die textbox für den hex-code öffnen und der andere einen sanften regenbogen-farbwechsel erzeugen.
jetzt kommt innerhalb von dem Listener die fehlermeldung "name not defined within scope" und der cursor steht dann an dem Wort "message", obwohl es doch direkt in der Zeile mit den definitionen von dem Listener für die Nachricht steht, mit der gearbeitet wird...

Code:
listen(integer channel, string name, key id, string message)
Hierdrin ist "Message" definiert.

Code:
else
        {
            if (isValidString(message) == 1)
            {
                llSetLinkColor(LINK_ALL_OTHERS, vColorFromHex(message), ALL_SIDES);
                llListenRemove(iListener);
            }
            else
            { //Invalid color-code.
                llOwnerSay(sMessageWrongColor);
                llListenRemove(iListener);
            }
        }
und hierdrin erkennt er das selbe wort nicht in der Zeile mit "isValidString", dabei befindet sich dieser Abschnitt innerhalb von dem Listener.
 
Ich möchte das in einen Dialog mit 2 knöpfen einbetten.
einer soll die textbox für den hex-code öffnen und der andere einen sanften regenbogen-farbwechsel erzeugen.
jetzt kommt innerhalb von dem Listener die fehlermeldung "name not defined within scope" und der cursor steht dann an dem Wort "message", obwohl es doch direkt in der Zeile mit den definitionen von dem Listener für die Nachricht steht, mit der gearbeitet wird...

Code:
listen(integer channel, string name, key id, string message)
Hierdrin ist "Message" definiert.

Code:
else
        {
            if ([COLOR="#FF0000"]is[/COLOR]ValidString(message) == 1)
            {
                llSetLinkColor(LINK_ALL_OTHERS, vColorFromHex(message), ALL_SIDES);
                llListenRemove(iListener);
            }
            else
            { //Invalid color-code.
                llOwnerSay(sMessageWrongColor);
                llListenRemove(iListener);
            }
        }
und hierdrin erkennt er das selbe wort nicht in der Zeile mit "isValidString", dabei befindet sich dieser Abschnitt innerhalb von dem Listener.

Dann schreib das 'Is' von 'IsValidString' doch einfach mal groß. :) (Bei Funktionsnamen verwende ich meistens kein lower CamelCase)
 
wieso steht der cursor dann hinter "message" und nicht hinter "IsValidString"?

Jetzt kommen zwar keine Fehlermeldungen mehr, aber es funktioniert noch nicht ganz richtig...

Code:
float red = 1;
float green = 0;
float blue = 0;

vector currentColour = <1,1,1>;

float COLOUR_INCREMENT = 0.01;

float TIMER_INT = 0.01;


changeColour()
{
    if (red == 1.0)
    {
        if (blue > 0.1)
        {
            blue = blue - COLOUR_INCREMENT;
        }
        else
        {
            green = green + COLOUR_INCREMENT;
        }
    }
    else if (green == 1.0)
    {
        if (red > 0)
        {
            red = red - COLOUR_INCREMENT;
        }
        else if (blue < 1.0)
        {
             blue = blue + COLOUR_INCREMENT;
        }
    }
    else if (blue == 1.0)
    {
        if (green > 0)
        {
            green = green - COLOUR_INCREMENT;
        }
        else if (red < 1.0)
        {
            red = red + COLOUR_INCREMENT;
        }
    }
    currentColour = <red, green, blue>;
    llSetLinkColor(LINK_ALL_OTHERS, currentColour, ALL_SIDES);
}

integer IsValidString(string input)
{
    string allowedChars = "0123456789abcdef";
    input = llStringTrim(llToLower(input), STRING_TRIM);
    integer length = llStringLength(input);
    if(length != 6)
        return 0;
    integer i;
    for( i = 0; i < length; i++ ) 
    {
        if(llSubStringIndex(allowedChars, llGetSubString(input, i, i)) == -1) 
            return 0;
    }
    return 1;
}

integer iComponentLength = 2;
string sHexPrefix = "0x";
float fColorMax = 255.0;
vector vColorFromHex(string sColor)
{ //Convert hex-string (e.g. "aaff00") to vector color.
        string sX; string sY; string sZ; integer iHelper; vector vColor;
        iHelper = 0;
        sX = llGetSubString(sColor, iHelper, iHelper + iComponentLength - 1);
        iHelper = iHelper + iComponentLength;
        sY = llGetSubString(sColor, iHelper, iHelper + iComponentLength - 1);
        iHelper = iHelper + iComponentLength;
        sZ = llGetSubString(sColor, iHelper, iHelper + iComponentLength - 1);
        
        vColor = <((integer)(sHexPrefix + sX)) / fColorMax, ((integer)(sHexPrefix + sY)) / fColorMax, ((integer)(sHexPrefix + sZ)) / fColorMax>;
        return vColor;
}

integer iListener;
integer iChannel = -938475;
//float fTimer = 30.0; //Seconds.
string sMessageDialog = "wich color settings would you use? \nhex-color : type in a hex-code fpr your own color \nPsychedelic : smooth rainbow color-change";
string sMessageTextBox = "Please enter the hex-code to re-color this prim-face, e.g. ff7f00";
string sMessageWrongColor = "Invalid color-code.";
//integer iTOUCHFACE;
//integer iTOUCHPRIM;
default
{
    touch_start(integer num_detected)
    {
        if (llDetectedKey(0) != llGetOwner())
        { //Only listen to owner.
            return;
        }
        //iTOUCHFACE = llDetectedTouchFace(0); //Store face and prim.
        //iTOUCHPRIM = llDetectedLinkNumber(0);
        iListener = llListen(iChannel, "", llDetectedKey(0), "");
        //llSetTimerEvent(fTimer);
        llDialog(llDetectedKey(0), sMessageDialog, ["hex-color", "Psychedelic"], iChannel);
    }
    listen(integer channel, string name, key id, string message)
    {
        if (message == "hex-color")
        {
            llSetTimerEvent(0);
            llTextBox(llDetectedKey(0), sMessageTextBox, iChannel);
        }
        else if (message == "Psychedelic")
        {
            llListenRemove(iListener);
            llSetTimerEvent(TIMER_INT);
        }
        //llSetTimerEvent(0);
        //llListenRemove(iListener);
        //Delete timer and listener.
        else
        {
            if (IsValidString(message) == 1)
            {
                llSetLinkColor(LINK_ALL_OTHERS, vColorFromHex(message), ALL_SIDES);
                llListenRemove(iListener);
            }
            else
            { //Invalid color-code.
                llOwnerSay(sMessageWrongColor);
                llListenRemove(iListener);
            }
        }
    }
    timer()
    {
        changeColour();
    }   
}
Der sanfte farbwechsel wandert nur von rot zu gelb und endet dann...
Wenn ich auf den knopf drücke, der die Texteingabe für den hexcode öffnen soll, geht nur der Dialog aus, aber keine TextBox an...
Woran liegt das?
 
wieso steht der cursor dann hinter "message" und nicht hinter "IsValidString"?
Das musst du die Entwickler von LindenLabs fragen. Ist aber nichts ungewöhnliches, dass die Fehleranzeige eines Compilers manchmal verwirrende Fehlerpositionen ausgibt. ;) Liegt oft an der Art und Weise wie der Parser aufgebaut ist.

Der sanfte farbwechsel wandert nur von rot zu gelb und endet dann...

Wegen diesem if
Code:
if (red == 1.0)
    {
        if (blue > 0)
        {
            blue -= COLOUR_INCREMENT;
        }
        else if (green < 1.0)
        {
            green += COLOUR_INCREMENT;
        }
    }

red wird nie verändert, also wird jedesmal dieser Codeblock ausgeführt. Irgendwann (nach 100 durchläufen) hatt green seinen Endwert erreicht (1.0) und es passiert nichts mehr. llSetLinkColor wird zwar noch periodisch aufgerufen aber immer mit den selben Werten.
Der Code in den darauffolgenden Blöcken wird nicht ausgeführt wegen dem else if. Tausch das mal gegen nur ein if:
Code:
[...]
if (red == 1.0)
    {
        if (blue > 0)
        {
            blue -= COLOUR_INCREMENT;
        }
        else if (green < 1.0)
        {
            green += COLOUR_INCREMENT;
        }
    }
    if (green == 1.0)
    {
        if (red > 0)
        {
            red -= COLOUR_INCREMENT;
        }
        else if (blue < 1.0)
        {
            blue += COLOUR_INCREMENT;
        }
    }
    if (blue == 1.0)
    {
        if (green > 0)
        {
            green -= COLOUR_INCREMENT;
        }
        else if (red < 1.0)
        {
            red += COLOUR_INCREMENT;
        }
    }
[...]
Vielleicht die anderen else auch noch weg. Ich denke ich verstehe schon was in dem Codeblock passieren soll, aber so ganz ohne Doku/Kommentare ist das doch etwas *meh* :sad:

[...] Wenn ich auf den knopf drücke, der die Texteingabe für den hexcode öffnen soll, geht nur der Dialog aus, aber keine TextBox an...
Woran liegt das?

Code:
llTextBox([COLOR="#FF0000"]llDetectedKey(0)[/COLOR], sMessageTextBox, iChannel);
Weil llDetectedKey(0) im Kontext des listen Events irgendwas zurückgibt. (Vermutlich NULL_KEY oder "") llDetectedKey(0) funktioniert nur für "Detected" Events. Da du ja anscheinend nur dem Besitzer zugriff auf das Menü geben willst, tausche es gegen llGetOwner() aus.
 
ich habe jetzt dieses id, womit im listener der benutzer bezeichnet ist bei der Text-Box eingefügt.
das geht jetzt.
nur mit dem farbwechsel-verlauf-effekt weiß ich immernochnicht weiter

ich habe das aus einem anderen script, da steht es so hier:
Code:
 if(red >= 1.0)
        {
            if (blue > 0.1)
            {blue = blue - 0.1;}
            else
            {green = green + 0.1;}
        }
        
        if(green >= 1.0)
        {
            if (red > 0.1)
            {red = red - 0.1;}
            else
            {blue = blue + 0.1;}
        }
        
       if(blue >= 1.0)
        {
            if (green > 0.1)
            {green = green - 0.1;}
            else
            {red = red + 0.1;}
        }
ich habe ein paar unterschiede twischen den beiden versionen angeglichen.
jetzt klappt´s plötzlich mit dem ganzen regenbogen.
keine ahnung, wie da was verhindert war...
 
Zuletzt bearbeitet:
Schönes Beispiel warum man Fliesskommazahlen nicht auf Gleichheit testet...

Tausch mal changeColour() gegen das hier aus:
Code:
changeColour()
{
    if (red >= 1.0)
    {
        if (blue > 0.1)
            blue = blue - COLOUR_INCREMENT;
        else if(green < 1.0)
            green = green + COLOUR_INCREMENT;
    }
    if (green >= 1.0)
    {
        if (red > 0)
            red = red - COLOUR_INCREMENT;
        else if (blue < 1.0)
             blue = blue + COLOUR_INCREMENT;
    }
    if (blue >= 1.0)
    {
        if (green > 0)
            green = green - COLOUR_INCREMENT;
        else if (red < 1.0)
            red = red + COLOUR_INCREMENT;
    }
    currentColour = <red, green, blue>;
//    llOwnerSay(":: " + (string)currentColour);
    llSetLinkColor(LINK_ALL_OTHERS, currentColour, ALL_SIDES);
}
Habs grad mal mit den von dier geposteten Code getestet. Sollte gehen.
> keine ahnung, wie da was verhindert war...
^^ ...Die typischen Probleme von Copy&Paste Programmierung.
 
Zuletzt bearbeitet:

Users who are viewing this thread

Zurück
Oben Unten