interpolation/Spline/Vectors

From Second Life Wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Summary

Function: vector pSpline( list v, float t, integer Loop );

B-Spline Interpolation between four vector points in a list of vectors that define a path.
Returns a vector

• list v
• float t Ranges between [0, 1]
• integer Loop Whether the list is a curved line or loops into a closed shape.

Specification

vector pSpline(list v, float t, integer Loop) {
    integer l = llGetListLength(v); t *= l-1;
    integer f = llFloor(t); t -= f;
    float t2 = t * t; float t3 = t2 * t;
    return (
      ( (-t3 + (3.*t2) - (3.*t) + 1.) * llList2Vector(v, pIndex(f-1,l,Loop)) )
    + ( ((3.*t3) - (6.*t2) + 4.) * llList2Vector(v, pIndex(f,l,Loop)) )
    + ( ((-3.*t3) + (3.*t2) + (3.*t) + 1.) * llList2Vector(v, pIndex(f+1,l,Loop)) )
    + ( t3 * llList2Vector(v, pIndex(f+2,l,Loop)) )
    ) / 6.0;
}
integer pIndex( integer Index, integer Length, integer Loop) {
    if(Loop) return Index % Length;
    if(Index < 0) return 0;
    if(Index > --Length) return Length;
    return Index;
}
// Released into public domain. By Nexii Malthus.

Examples

//Quick Dirty Example By To-mos Codewarrior (tomos.halsey)
integer LINK_cube;integer LINK_1;
integer LINK_2;   integer LINK_3;
integer LINK_4;   integer LINK_5;
integer LINK_6;   integer LINK_7;

vector pos_1;vector pos_2;
vector pos_3;vector pos_4;
vector pos_5;vector pos_6;
vector pos_7;

getlinks()
{
    integer total=llGetNumberOfPrims()+1;
    string name;
    while((total--)-1)
    {
        name=llGetLinkName(total);
        if(name == "Cube")LINK_cube = total;
        if(name == "1")   LINK_1 = total;
        if(name == "2")   LINK_2 = total;
        if(name == "3")   LINK_3 = total;
        if(name == "4")   LINK_4 = total;
        if(name == "5")   LINK_5 = total;
        if(name == "6")   LINK_6 = total;
        if(name == "7")   LINK_7 = total;
    }
}

getPositions()
{
    pos_1 = llList2Vector(llGetLinkPrimitiveParams(LINK_1, [PRIM_POS_LOCAL]), 0);
    pos_2 = llList2Vector(llGetLinkPrimitiveParams(LINK_2, [PRIM_POS_LOCAL]), 0);
    pos_3 = llList2Vector(llGetLinkPrimitiveParams(LINK_3, [PRIM_POS_LOCAL]), 0);
    pos_4 = llList2Vector(llGetLinkPrimitiveParams(LINK_4, [PRIM_POS_LOCAL]), 0);
    pos_5 = llList2Vector(llGetLinkPrimitiveParams(LINK_5, [PRIM_POS_LOCAL]), 0);
    pos_6 = llList2Vector(llGetLinkPrimitiveParams(LINK_6, [PRIM_POS_LOCAL]), 0);
    pos_7 = llList2Vector(llGetLinkPrimitiveParams(LINK_7, [PRIM_POS_LOCAL]), 0);
}

vector bSpline(list v, float t, integer Loop) {
    integer l = llGetListLength(v); t *= l-1;
    integer f = llFloor(t); t -= f;
    float t2 = t * t; float t3 = t2 * t;
    vector out=(
      ( (-t3 + (3.*t2) - (3.*t) + 1.) * llList2Vector(v, pIndex(f-1,l,Loop)) )
    + ( ((3.*t3) - (6.*t2) + 4.) * llList2Vector(v, pIndex(f,l,Loop)) )
    + ( ((-3.*t3) + (3.*t2) + (3.*t) + 1.) * llList2Vector(v, pIndex(f+1,l,Loop)) )
    + ( t3 * llList2Vector(v, pIndex(f+2,l,Loop)) )
    ) / 6.0;
    llSetText(
        "time: "+(string)t+"\n"+
        "vector pos: "+(string)out
    ,<1.0,1.0,1.0>,1.0);
    return out;
}
integer pIndex( integer Index, integer Length, integer Loop) {
    if(Loop) return Index % Length;
    if(Index < 0) return 0;
    if(Index > --Length) return Length;
    return Index;
}

interpolate()
{
    getPositions();
    
    float t;
    for(t = 0; t < 1; t += 0.001)
    {
        llSetLinkPrimitiveParamsFast(LINK_cube, [PRIM_POS_LOCAL,bSpline([pos_1,pos_2,pos_3,pos_4,pos_5,pos_6,pos_7,pos_7,pos_7],t,0)]);
    }
}

default
{
    state_entry()
    {getlinks();}
    
    touch_start(integer num)
    {interpolate();}
}