ClickAndDrag

From Second Life Wiki
Jump to navigation Jump to search

Setup: Rez prim (A), apply script, Rez another prim (B) and put it slightly below it, link it up so B is a child and A is the root.

This is exactly the same code on my aRTS project that the landscape uses for handling interface touches, such as clicking on a point or dragging a rectangle which the HUD can in return use for sending out commands to units and/or unit selection.

This is quite a cool and unique script which can be used to draw rectangles dynamically dragged by a user on an interface. For example one could use this on a sculpted miniature simulator map and designate an area for some specific purpose. This gives dynamic feedback invaluable to such interfaces.

// ClickAndDrag made by Nexii Malthus
// Public Domain

// Protocol:
    //    Types   Data
    //      Click,  Player Key | Type | World Coords | Normal | Bi-Normal
    //      Drag,   Player Key | Type | WC-A | N-A | BN-A | WC-B | N-B | BN-B
// Type -  0 = Click, 1 = Drag

integer ch = 1; // Channel to send commands on

key kTextureClick = "5d431ade-24f3-2390-f1ba-ca404cad2864";
key kTextureDrag = "efc411bc-2005-10ff-da0c-3dda972f6e70";

list tData1;
list tData2;
vector ST1;

default{
    state_entry(){
        llMinEventDelay( 0.21 );
    }
    
    touch_start( integer d ){
        if( llDetectedTouchFace( 0 ) == -1 ) return;
        tData1 = [ llDetectedTouchPos(0), llDetectedTouchNormal(0), llDetectedTouchBinormal(0) ];
        ST1 = llDetectedTouchST( 0 );
    }
    
    touch( integer dn ){
        vector ST2 = llDetectedTouchST( 0 );
        
        if( ST1 == <-1,-1,0> || ST2 == <-1,-1,0> ) return;
        
        if( llVecDist( ST1, ST2 ) > 0.01 ){
            llSetColor( < 0.0, 0.0, 1.0 >, 0 ); llSetAlpha( 0.2, 0 );
            float relSize = 0.08;//0.084;
            vector selCentre = <1,1,0> - ((ST2+ST1)/2);
            vector selSize = (ST1-ST2); selSize = <llFabs(selSize.x),llFabs(selSize.y),0>;
            
            vector Scale = <relSize/selSize.x,relSize/selSize.y,0>;//selSize;//< selSize.x/relSize.x, selSize.y/relSize.y, 0>;
            vector Offset = (selCentre-<0.5,0.5,0>);Offset = <Offset.x*Scale.x,Offset.y*Scale.y,0>;
            llSetPrimitiveParams([ PRIM_TEXTURE, 0, kTextureDrag, Scale, Offset, 0 ]);
        }
    }
    
    touch_end( integer d ){
        key nKey = llDetectedKey( 0 );
        vector tPos = llDetectedTouchPos( 0 );
        tData2 = [ tPos, llDetectedTouchNormal( 0 ), llDetectedTouchBinormal( 0 ) ];
        vector ST2 = llDetectedTouchST( 0 );
        
        if( ST1 == <-1,-1,0> || ST2 == <-1,-1,0> ){
            if( llVecDist( ST1, ST2 ) > 0.01 )
                llSetAlpha( 0.0, 0 );
            return;
        }
        
        if( llVecDist( ST1, ST2 ) < 0.01 ){
            llSetColor( < 0.0, 1.0, 0.0 >, 0 ); llSetAlpha( 1.0, 0 );
            vector Scale = < 1.0, 1.0, 0>;
            vector Offset = < 1.0, 1.0, 0 > - ST1;
            llSetPrimitiveParams([ PRIM_TEXTURE, 0, kTextureClick, Scale, Offset, 0 ]);
            llSetAlpha( 0.0, 0 );
            llSay( ch, llDumpList2String( [nKey,0] + tData1, "|" ) );
        } else {
            llSetColor( < 0.0, 0.0, 1.0 >, 0 ); llSetAlpha( 0.2, 0 );
            float relSize = 0.08;
            vector selCentre = <1,1,0> - ((ST2+ST1)/2);
            vector selSize = (ST1-ST2); selSize = <llFabs(selSize.x),llFabs(selSize.y),0>;
            
            vector Scale = <relSize/selSize.x,relSize/selSize.y,0>;//selSize;//< selSize.x/relSize.x, selSize.y/relSize.y, 0>;
            vector Offset = (selCentre-<0.5,0.5,0>);Offset = <Offset.x*Scale.x,Offset.y*Scale.y,0>;
            llSetPrimitiveParams([ PRIM_TEXTURE, 0, kTextureDrag, Scale, Offset, 0 ]);
            llSay( ch, llDumpList2String( [nKey,1] + tData1 + tData2, "|" ) );
            llSetAlpha( 0.0, 0 );
        }
    }
}