User:Xen Lisle/Texture Slide

From Second Life Wiki
Jump to: navigation, search

Texture Slide

General information:

This is a proof of concept to show how to slide a texture across a prim face with mouse movement.

The script will display a grid texture of 25 squares. Clicking on a grid square will return that squares value.
Clicking and holding while moving the mouse, the texture will slide in the direction of the mouse movement.

Script

//  Touch and drag a texture across a prim face
//  Useful for interfaces and such
//  Example script gives you 25 buttons to click on
//  By Xen Lisle
//  Free to use
 
//  prim face you want the script to work on
integer gFace = 0;
 
//  the UV repeats of the texture. values smaller than one will show only part of the texture
vector UV_TEXTURE_REPEATS = <1.0, 1.0, 0.0>;
 
//  your menu texture
string MENU_TEXTURE = "69737f61-1fdd-6033-7ea3-a52e61a40137";
 
//  strided list to define button labels and values
//    - vector one is top left button corner
//    - vector two is bottom right button corner
//    - next two elements hold data for the buttons
//  elements in this example: LABEL, DATA
//  assigning a label helps to filter different button actions
//  not very helpful in our example but included anyway
list BUTTONS_STRIDED_LIST = [
    <0.0, 1.0, 0.0>,    <0.2, 0.8, 0.0>,    "Button",   "A-0",
    <0.2, 1.0, 0.0>,    <0.4, 0.8, 0.0>,    "Button",   "A-1",
    <0.4, 1.0, 0.0>,    <0.6, 0.8, 0.0>,    "Button",   "A-2",
    <0.6, 1.0, 0.0>,    <0.8, 0.8, 0.0>,    "Button",   "A-3",
    <0.8, 1.0, 0.0>,    <1.0, 0.8, 0.0>,    "Button",   "A-4",
 
    <0.0, 0.8, 0.0>,    <0.2, 0.6, 0.0>,    "Button",   "B-0",
    <0.2, 0.8, 0.0>,    <0.4, 0.6, 0.0>,    "Button",   "B-1",
    <0.4, 0.8, 0.0>,    <0.6, 0.6, 0.0>,    "Button",   "B-2",
    <0.6, 0.8, 0.0>,    <0.8, 0.6, 0.0>,    "Button",   "B-3",
    <0.8, 0.8, 0.0>,    <1.0, 0.6, 0.0>,    "Button",   "B-4",
 
    <0.0, 0.6, 0.0>,    <0.2, 0.4, 0.0>,    "Button",   "C-0",
    <0.2, 0.6, 0.0>,    <0.4, 0.4, 0.0>,    "Button",   "C-1",
    <0.4, 0.6, 0.0>,    <0.6, 0.4, 0.0>,    "Button",   "C-2",
    <0.6, 0.6, 0.0>,    <0.8, 0.4, 0.0>,    "Button",   "C-3",
    <0.8, 0.6, 0.0>,    <1.0, 0.4, 0.0>,    "Button",   "C-4",
 
    <0.0, 0.4, 0.0>,    <0.2, 0.2, 0.0>,    "Button",   "D-0",
    <0.2, 0.4, 0.0>,    <0.4, 0.2, 0.0>,    "Button",   "D-1",
    <0.4, 0.4, 0.0>,    <0.6, 0.2, 0.0>,    "Button",   "D-2",
    <0.6, 0.4, 0.0>,    <0.8, 0.2, 0.0>,    "Button",   "D-3",
    <0.8, 0.4, 0.0>,    <1.0, 0.2, 0.0>,    "Button",   "D-4",
 
    <0.0, 0.2, 0.0>,    <0.2, 0.0, 0.0>,    "Button",   "E-0",
    <0.2, 0.2, 0.0>,    <0.4, 0.0, 0.0>,    "Button",   "E-1",
    <0.4, 0.2, 0.0>,    <0.6, 0.0, 0.0>,    "Button",   "E-2",
    <0.6, 0.2, 0.0>,    <0.8, 0.0, 0.0>,    "Button",   "E-3",
    <0.8, 0.2, 0.0>,    <1.0, 0.0, 0.0>,    "Button",   "E-4"];
 
vector gStartST;
vector gEndST;
vector gOffsetUV;
 
list FindUV(vector v, list lst)
{
    vector cordA;
    vector cordB;
    integer lines = llGetListLength(lst) / 4;
 
    //  roll values between 0 and 1
    v -= <llFloor(v.x), llFloor(v.y), 0.0>;
 
    integer i;
    for (i = 0; i < lines; i++)
    {
        cordA = llList2Vector(lst,i * 4);
        cordB = llList2Vector(lst, i * 4 + 1);
 
        if (v.x > cordA.x && v.x < cordB.x &&
            v.y < cordA.y && v.y > cordB.y)
        {
            return llList2List(lst, i*4 + 2, i*4 + 3);
        }
    }
 
    return [];
}
 
default
{
    state_entry()
    {
        if (MENU_TEXTURE == "")
        {
            MENU_TEXTURE = "69737f61-1fdd-6033-7ea3-a52e61a40137";
        }
 
        llSetLinkPrimitiveParamsFast(0, [
            PRIM_TEXTURE, gFace, MENU_TEXTURE, UV_TEXTURE_REPEATS, ZERO_VECTOR, 0.0]);
    }
 
    touch_start(integer num_detected)
    {
        integer face = llDetectedTouchFace(0);
 
        if (face == gFace)
        {
            gOffsetUV = llGetTextureOffset(gFace);
            gStartST = llDetectedTouchST(0);
 
            //  scale the touch vector to match our texture scale
            gStartST = <gStartST.x*UV_TEXTURE_REPEATS.x, gStartST.y*UV_TEXTURE_REPEATS.y, 0.0>;
        }
    }
 
    touch(integer num_detected)
    {
        integer face = llDetectedTouchFace(0);
 
        if (face == gFace)
        {
            gEndST = llDetectedTouchST(0);
 
            //  scale the touch vector to match our texture scale
            gEndST = <gEndST.x*UV_TEXTURE_REPEATS.x, gEndST.y*UV_TEXTURE_REPEATS.y, 0.0>;
 
            if (llVecDist(gStartST,gEndST) > 0.0)
            {
                 vector newUV = gOffsetUV + (gStartST - gEndST);
 
                 //  roll values between 0 and 1
                 newUV -= <llFloor(newUV.x), llFloor(newUV.y), 0.0>;
 
                //  apply new texture offset
                 llSetLinkPrimitiveParamsFast(0, [
                    PRIM_TEXTURE, gFace, MENU_TEXTURE, UV_TEXTURE_REPEATS, newUV, 0.0]);
            }
        }
    }
 
    touch_end(integer num_detected)
    {
        integer face = llDetectedTouchFace(0);
 
        if (face == gFace)
        {
            if (llVecDist(gStartST, gEndST) > 0.0)
            {
                //  compare mouse movement to see if texture was moved. maybe useful to do something here
            }
            else//  did not slide the texture. was a button press
            {
                list list_data = FindUV(llDetectedTouchUV(0), BUTTONS_STRIDED_LIST);
 
                //This next line is where we compare button labels
                if (llList2String(list_data, 0) == "Button")
                {
                    llSay(PUBLIC_CHANNEL, llList2String(list_data, 1));
                }
            }
        }
    }
}