Original Open Prim Animator

Expired

 

 

Original Author:  Todd Borst

Create Date: 

Category: Animation

Description: A great little script for animating prims

Download Script Here: 

Download Script

 

 

 

 
// Open Prim Animator - by Todd Borst
// Extensive Modifications by SignpostMarv Martin

// Note from Todd to other editors: Please document changes you have made to get proper credit.
// Note from Todd to users: People may have edited the script from since I've posted it originally.
// You can always view the original script by clicking the history tab.

// This is provided AS IS without support.  Please don't bug me demanding
// help or custom work for this free script.

// Summary: This is a simple prim animation script.  Just add this script
// to your object and a dialog will automatically pop up for you to use.

// Features:
// -Single script "Prim Puppeteer" like animation tool
// -Playback controllable through external scripts
// -Animation is scalable and resizeable
// -On-touch trigger built-in
// -Completely free and open sourced

// License:
// You are welcome to use this anyway you like, even bring to other grids
// outside of Second Life.  You are welcomed to sell it if you've made your
// own improvements to it.  This is effectively public domain.  Have fun.

integer COMMAND_CHANNEL = 32;

integer primCount;
integer commandListenerHandle = ERR_GENERIC;

list posList;
list rotList;
list scaleList;
integer currentSnapshot;
integer recordedSnapshots;

vector rootScale;
vector scaleChange = <1.0, 1.0, 1.0>;

integer maxMemory;
integer freeMemory;

//  The values for playAnimationStyle means
//      0 :=    no animation playing
//      1 :=    play animation once
//      2 :=    play animation looping

integer playAnimationStyle;

key op_import = "6b78fcc8-e147-4105-99a6-ff19b4bf559d";
key op_export = "7c2ca168-2b64-4836-8727-8e62b78dbd44";
key op_alter_rootScale = "f9d3389e-a78c-43f8-9e35-c11adec112a5";

//  _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//  _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

show_snapshot(integer snapNumber)
{
    if (!snapNumber || recordedSnapshots < snapNumber)
        return;

    vector rootPos = llGetPos();
    rotation rootRot = llGetRot();

    vector pos;
    rotation rot;
    vector scale;
    list params;

    integer i = 2;
    do
    {
        pos     = llList2Vector(posList, ((snapNumber - 1)*(primCount - 1)) + (i - 2));
        rot     = llList2Rot(rotList, ((snapNumber - 1)*(primCount - 1)) + (i - 2));
        scale   = llList2Vector(scaleList, ((snapNumber - 1)*(primCount - 1)) + (i - 2));

        if ( rootScale.x != 1.0 || rootScale.y != 1.0 || rootScale.z != 1.0 )
        {
            pos.x *= scaleChange.x;
            pos.y *= scaleChange.y;
            pos.z *= scaleChange.z;
            scale.x *= scaleChange.x;
            scale.y *= scaleChange.y;
            scale.z *= scaleChange.z;
        }
        params += [PRIM_LINK_TARGET, i,
                        PRIM_POSITION, pos,
                        PRIM_ROTATION, rot/rootRot,
                        PRIM_SIZE, scale
        ];

        if (64 < llGetListLength(params))
        {
            llSetLinkPrimitiveParamsFast(LINK_THIS, params);
            params = [];
        }
    }
    while (++i <= primCount);

    if (llGetListLength(params))
    {
        llSetLinkPrimitiveParamsFast(LINK_THIS, params);
        params = [];
    }
}

playAnimation(float delay, integer loop)
{
    if (delay < 0.1)
        delay = 1.0;

    if (loop == FALSE)
        playAnimationStyle = 1;
    else
        playAnimationStyle = 2;

    if (1 <= recordedSnapshots)
        llSetTimerEvent(delay);
}

showMenuDialog()
{
//  return;

    string temp = (string)((float)freeMemory/(float)maxMemory * 100.0);
    string menuText = "Free Memory: " + (string)freeMemory + " (" + llGetSubString(temp, 0, 4) +"%)"
        + "\nSnapshot " + (string)currentSnapshot +" of " + (string)recordedSnapshots
        + "\n\n[ Record ] - Record a snapshot of prim positions"
        + "\n[ Play ] - Play back all the recorded snapshots"
        + "\n[ Publish ] - Finish the recording process"
        + "\n[ Show Next ] - Show the next snapshot"
        + "\n[ Show Prev ] - Show the previous snapshot";

    llDialog(llGetOwner(), menuText,
        ["Record","Play","Publish","Show Prev","Show Next","Loop","Stop","Export"], COMMAND_CHANNEL);
}
string truncate_float(float foo)
{
    if (foo == 0.0)
        return "0";
    else if (foo == (float)((integer)foo))
        return (string)((integer)foo);

    string bar = (string)foo;

    while (llGetSubString(bar, -1, -1) == "0")
        bar = llGetSubString(bar, 0, -2);

    if (llGetSubString(bar, -1, -1) == ".")
        bar = llGetSubString(bar, 0, -2);

    return bar;
}

calc_scaleChange()
{
    if (rootScale != ZERO_VECTOR)
    {
        vector newScale = llGetScale();

        if ( (newScale.x / rootScale.x) != scaleChange.x
            || (newScale.y / rootScale.y) != scaleChange.y
            || (newScale.z / rootScale.z) != scaleChange.z)
        {
            scaleChange.x = newScale.x / rootScale.x;
            scaleChange.y = newScale.y / rootScale.y;
            scaleChange.z = newScale.z / rootScale.z;
        }
    }
}

default
{
    state_entry()
    {
        maxMemory = llGetFreeMemory();
        freeMemory = llGetFreeMemory();

        primCount = llGetNumberOfPrims();
        commandListenerHandle = llListen(COMMAND_CHANNEL,"", llGetOwner(), "");
        showMenuDialog();

        rootScale = llGetScale();
        if (llGetInventoryType("OPA Notecard Import - 2011-11-03") == INVENTORY_SCRIPT){
            llResetOtherScript("OPA Notecard Import - 2011-11-03");
        }
    }

//  Feel free to remove this on-touch trigger if you are using your own script to control playback
//  touch_start(integer num_detected)
//  {
//      if (commandListenerHandle == ERR_GENERIC)
//      {
//          if (playAnimationStyle == 0)
//              playAnimation(1.0,TRUE);
//          else
//          {
//              playAnimationStyle = 0;
//              llSetTimerEvent((float)FALSE);
//          }
//      }
//  }

    changed(integer change)
    {
        if (change & CHANGED_SCALE)
            calc_scaleChange();

        if (change & CHANGED_LINK)
        {
            if ( primCount != llGetNumberOfPrims() )
            {
                llOwnerSay("Link change detected, reseting script.");
                llResetScript();
            }
        }
    }

    //The message link function is to allow other scripts to control the snapshot playback
    //This command will display snapshot #2:
    //      llMessageLinked(LINK_ROOT, 2, "XDshow", NULL_KEY);  llSleep(1.0);
    //
    //This command will play through all the recorded snapshots in ascending order.  The number "1.0" is the delay speed and can be changed.
    //      llMessageLinked(LINK_ROOT, 0, "XDplay", "1.0");
    //
    //This command will loop through all the recorded snapshots in ascending order.  The number "1.0" is the delay speed and can be changed.
    //      llMessageLinked(LINK_ROOT, 0, "XDplayLoop", "1.0");
    //
    //To stop any playing animation use
    //      llMessageLinked(LINK_ROOT, 0, "XDstop", NULL_KEY);

    link_message(integer sender_num, integer num, string str, key id)
    {
        if ("XDshow" == str && 1 <= num && num <= recordedSnapshots)
            show_snapshot(num);
        else if ("XDplay" == str)
        {
            currentSnapshot = 1;
            float delay = (float)((string)id);
            playAnimation(delay, FALSE);
        }
        else if ("XDplayLoop" == str)
        {
            float delay = (float)((string)id);
            playAnimation(delay, TRUE);
        }
        else if ("XDstop" == str)
        {
            playAnimationStyle = 0;
            llSetTimerEvent((float)FALSE);
        }
        else if ("XDexport" == str && !num)
        {
            list export = [];
            string foo;
            vector bar;
            rotation baa;
            string baz;

            integer i = 2;
            integer j = primCount;

            do
                export += [llGetLinkName(i)];
            while (++i <= j);

            llMessageLinked(sender_num, 1, llDumpList2String(export,"|")  , op_export);
            export = [];

            i = 0;
            j = llGetListLength(posList);

            do
            {
                bar = llList2Vector(posList,i);
                export += ["<" + truncate_float(bar.x) + ","
                          + truncate_float(bar.y) + "," + truncate_float(bar.z) + ">"];
            }
            while (++i < j);

            llMessageLinked(sender_num, 2, llDumpList2String(export,"|")  , op_export);
            export = [];

            i = 0;
            j = llGetListLength(rotList);

            do
            {
                baa = llList2Rot(rotList,i);
                export += ["<" + truncate_float(baa.x) + "," + truncate_float(baa.y)
                            + "," + truncate_float(baa.z) + "," + truncate_float(baa.s) + ">"];
            }
            while (++i < j);

            llMessageLinked(sender_num, 3, llDumpList2String(export,"|")  , op_export);
            export = [];

            i = 0;
            j = llGetListLength(scaleList);

            do
            {
                bar = llList2Vector(scaleList,i);
                export += ["<" + truncate_float(bar.x) + ","
                            + truncate_float(bar.y) + "," + truncate_float(bar.z) + ">"];
            }
            while (++i < j);

            llMessageLinked(sender_num, 4, llDumpList2String(export,"|")  , op_export);
        }
        else if ("XDmenu" == str)
        {
            showMenuDialog();
        }
        else if ("XDimportLength" == str && 0 < num)
        {
            list foo;
            list bar;

            integer i;
            do
            {
                foo += [ZERO_VECTOR];
                bar += [ZERO_ROTATION];
            }
            while (++i < num);

            posList = foo;
            scaleList = foo;
            rotList = bar;
            llMessageLinked(sender_num,-1,str,op_import);
            recordedSnapshots = num / (llGetNumberOfPrims() - 1);
            llMessageLinked(LINK_SET, recordedSnapshots, "XDrecordedSnapshots", NULL_KEY);
            currentSnapshot = 1;
        }
        else if ("XDrecordedSnapshots" == str && num == -1)
        {
            llMessageLinked(sender_num,recordedSnapshots,str,NULL_KEY);
        }
        else if (id == op_import && 0 <= num)
        {
            list params = llParseString2List(str, ["|"], []);
            vector impPos = (vector)llList2String(params, 0);
            rotation impRot = (rotation)llList2String(params, 1);
            vector impSize  = (vector)llList2String(params, 2);

            posList = llListReplaceList(posList, [impPos], num, num);
            rotList = llListReplaceList(rotList, [impRot], num, num);
            scaleList = llListReplaceList(scaleList, [impSize], num, num);
        }
        else if (id == op_alter_rootScale)
        {
            rootScale = (vector)str;
            calc_scaleChange();
        }
    }

    listen(integer channel, string name, key id, string message)
    {
        list parsedMessage = llParseString2List(message, [" "], []);
        string firstWord = llToLower(llList2String(parsedMessage, 0));
        string secondWord = llToLower(llList2String(parsedMessage, 1));

        if ("show" == firstWord && recordedSnapshots > 0)
        {
            llSetTimerEvent((float)FALSE);

            if (secondWord == "next")
            {
                ++currentSnapshot;

                if (recordedSnapshots < currentSnapshot)
                    currentSnapshot = 1;

                show_snapshot(currentSnapshot);
            }
            else if (secondWord == "prev")
            {
                --currentSnapshot;

                if (currentSnapshot < 1)
                    currentSnapshot = recordedSnapshots;

                show_snapshot(currentSnapshot);
            }
            else
            {
                currentSnapshot = (integer)secondWord;

                if (currentSnapshot && currentSnapshot <= recordedSnapshots)
                {
                    show_snapshot(currentSnapshot);
                    llOwnerSay("Showing snapshot: " + (string)currentSnapshot);
                }
                else
                {
                    llOwnerSay("Invalid snapshot number given: " + (string) currentSnapshot +
                                "\nA valid snapshot number is between 1 and " + (string) recordedSnapshots);

                    currentSnapshot = 1;
                }
            }
        }
        else if (firstWord == "record")
        {
            vector rootPos = llGetPos();

            integer i = 2;
            do
            {
                vector pos = llList2Vector(llGetLinkPrimitiveParams(i, [PRIM_POSITION]), 0);

                pos.x -= rootPos.x;
                pos.z -= rootPos.z;
                pos.y -= rootPos.y;
                pos = pos / llGetRot();
                posList += pos;

                rotation rot = llList2Rot(llGetLinkPrimitiveParams(i, [PRIM_ROTATION]), 0);

                rot = rot / llGetRot();
                rotList += rot;

                scaleList += llList2Vector(llGetLinkPrimitiveParams(i, [PRIM_SIZE]), 0);
            }
            while (++i <= primCount);

            ++recordedSnapshots;

            llOwnerSay("Total number of snapshots recorded: " + (string)recordedSnapshots);
            freeMemory = llGetFreeMemory();
        }
        else if (firstWord == "play")
        {
            float delay = (float)secondWord;
            currentSnapshot = 1;
            playAnimation(delay, FALSE);
        }
        else if ("publish" == firstWord)
        {
            llSetTimerEvent((float)FALSE);
            playAnimationStyle = 0;
            currentSnapshot = 1;

            llListenRemove(commandListenerHandle);
            commandListenerHandle = -1;

            llOwnerSay("Recording disabled. Publish complete.\nClick me to toggle animation on/off.");
        }
        else if ("loop" == firstWord)
        {
            llMessageLinked(LINK_THIS, 0, "XDplayLoop", NULL_KEY);
        }
        else if ("stop" == firstWord)
        {
            llMessageLinked(LINK_THIS, 0, "XDstop", NULL_KEY);
        }
        else if ("export" == firstWord)
        {
            llOwnerSay("Should be exporting");
            llMessageLinked(LINK_THIS, 0, "XDexport", NULL_KEY);
        }

        if (commandListenerHandle != ERR_GENERIC)
            showMenuDialog();
    }

    timer()
    {
        show_snapshot(currentSnapshot);

        if (currentSnapshot < recordedSnapshots)
            ++currentSnapshot;
        else
        {
            if (playAnimationStyle == 2)
                currentSnapshot = 1;
            else
            {
                llSetTimerEvent((float)FALSE);

                if (commandListenerHandle != ERR_GENERIC)
                    showMenuDialog();
            }
        }
    }
}

 

Have Questions? Need help? Leave a note for Kitsune Lassiter in Second Life

 

 

Additional Notes & Instructions(If any):

Bending Fish

Expired

Original Author: 

Create Date: 10/29/2009

Category: Animation

Description: I found this on a website a long time ago and even though we have animesh, it was fun to use and I thought others might like it to play with. i left the copyright in place because Shine Renoir deserves the kudos for it.

Download Script Here: 

Download All Files

 

 

 

// bending fish
// 2007 Copyright by Shine Renoir (This email address is being protected from spambots. You need JavaScript enabled to view it.)
//

//First create a box A. Edit it, click Object->More and select the Physical checkbox. Then create a box B and select the Features->Flexible Path checkbox. Set 1 for wind for testing. Now first select box B, then ctrl-click box A to select both and click Link in Tools menu. This makes box A the root prim in the link set. Now the whole link set is physical, but box B is still flexible.

//Finally you can add the script below to the link set for a fish movement. Edit the objects by checking the "Edit linked parts" checkbox to make box A invisible, apply texture to box B and rotate it for the right bending effect, change the flexible parameters and move box A within the link set for more realistic movement (somewhere inside the fish).


// The center position is stored on rez.

// maximum swim radius from last center
float radius = 3.0;

// maximum swim distance for swimming up or down from last center
float height = 1.0;

// delay in seconds for next movement
float delay = 4.0;

// internal channel for communication
integer CHANNEL = -87;

// last center position
vector center;

float randBetween(float min, float max)
{
    return llFrand(max - min) + min;
}

init()
{
    llOwnerSay("start swimming");
    llListen(CHANNEL, "", llGetOwner(), "");
    llSetTimerEvent(0.0);
    llSetStatus(STATUS_ROTATE_X, FALSE);
    llSetStatus(STATUS_ROTATE_Y, FALSE);
    float t = llSqrt(2.0) / 2.0;
    llSetRot(<0, 0, 0, 0>);
    center = llGetPos();
    llSetBuoyancy(1.0);
    llSetTimerEvent(delay);
}

default
{
    touch_start(integer num)
    {
        llDialog(llGetOwner(), "Click 'stop', then move the fish to a new center and then click 'start'. Change parameters with the other buttons", ["radius", "height", "delay", "stop", "start"], -33);
    }

    state_entry()
    {
        init();
    }

    on_rez(integer start_num)
    {
        init();
    }

    timer()
    {
        // get current position
        vector pos = llGetPos();
        
        // calculate random next position
        vector dest = pos;
        dest.x += randBetween(-radius, radius);
        dest.y += randBetween(-radius, radius);
        dest.z += randBetween(-radius, height);
        
        // move to center, if outside radius
        integer i;
        for (i = 0; i < 3; i++) {
            if (llVecMag(dest - center) > radius) {
                dest = (dest - pos) / 2.0 + pos;
            }
        } 
        if (dest.z < center.z - height) {
            dest.z += 0.5;
        }
        if (dest.z > center.z + height) {
            dest.z -= 0.5;
        }
        
        // fallback: if other objects pushes the fish, move back to center
        if (llVecMag(dest - center) > radius) {
            dest = center;
        }

        // calculate new rotation and move to target
        vector delta = pos - dest;
        float angle = llAtan2(delta.y, delta.x) + PI / 2.0;
        rotation rot = llEuler2Rot(<0, 0, angle>);
        llRotLookAt(rot, 1.0, 1.0);
        llMoveToTarget(dest, 2);
    }

    listen(integer channel, string name, key id, string message)
    {
        if (message == "stop") {
            llOwnerSay("stop swimming");
            llSetTimerEvent(0.0);
            llStopMoveToTarget();
        } else if (message == "start") {
            init();
        } else if (message == "radius") {
            llDialog(llGetOwner(), "Change radius in meters from center of the fish. Current radius: " + (string) radius, ["radius +1", "radius -1", "radius +5", "radius -5"], -33);
        } else if (message == "radius +1") {
            radius += 1.0;
            llOwnerSay("new radius: " + (string) radius);
        } else if (message == "radius -1") {
            radius -= 1.0;
            if (radius < 1.0) {
                radius = 1.0;
            }
            llOwnerSay("new radius: " + (string) radius);
        } else if (message == "radius +5") {
            radius += 5.0;
            llOwnerSay("new radius: " + (string) radius);
        } else if (message == "radius -5") {
            radius -= 5.0;
            if (radius < 1.0) {
                radius = 1.0;
            }
            llOwnerSay("new radius: " + (string) radius);
        } else if (message == "height") {
            llDialog(llGetOwner(), "Change moving height in meters. Current height: " + (string) height, ["height +1", "height -1", "height +5", "height -5"], -33);
        } else if (message == "height +1") {
            height += 1.0;
            llOwnerSay("new height: " + (string) height);
        } else if (message == "height -1") {
            height -= 1.0;
            if (height < 1.0) {
                height = 1.0;
            }
            llOwnerSay("new height: " + (string) height);
        } else if (message == "height +5") {
            height += 5.0;
            llOwnerSay("new height: " + (string) height);
        } else if (message == "radius -5") {
            height -= 5.0;
            if (height < 1.0) {
                height = 1.0;
            }
            llOwnerSay("new height: " + (string) height);
        } else if (message == "delay") {
            llDialog(llGetOwner(), "Change max delay in seconds. Current delay: " + (string) delay, ["delay +1", "delay -1"], -33);
        } else if (message == "delay +1") {
            delay += 1.0;
            llOwnerSay("new delay: " + (string) delay);
        } else if (message == "delay -1") {
            delay -= 1.0;
            if (delay < 1.0) {
                delay = 1.0;
            }
            llOwnerSay("new delay: " + (string) delay);
        }
    }
}

 

Have Questions? Need help? Leave a note for Kitsune Lassiter in Second Life

 

 

Additional Notes & Instructions(If any):

Basic Wear Animate

Expired

Original Author:  Solo Mornington

Create Date: 

Category: Animate

Description:  The whole script repository can be found here: https://github.com/SoloMornington/Solos-Script-Repository

 

 

// BASIC WEAR/ANIMATE SCRIPT 1.0
// by Solo Mornington

// THIS NOTICE MUST REMAIN INTACT:
// Copyright 2010, Solo Mornington
// License: Use freely in any way you want. Modified versions
// may be used in any way. No credit or acknowledgement required.
// Definitive source and updates available here:
// http://github.com/SoloMornington/Solos-Script-Repository
// ** end notice

// A very basic framework script for others to modify
// hopefully illustrating some best-practices
//
// inspired by Catherine Omega's basic animation script on lslwiki.net

// WHAT THIS SCRIPT DOES:
// it plays an animation when the avatar wears the prim containing the script.
// it illustrates how to use the permissions system

// HOW TO USE IT:
// put this script in an object. this script should be in the root prim of the object
// change the next line to reflect the name of the animation you want to play

list gAnimations = [
    "[solo] karakasa spine lock",
    "[solo] shoulders up"
    ]; // what animation to play?

// NOTE: I use a naming convention of putting g at the start of any
// global variable. This makes it easier to see which variables have
// which scope.

default
{
    state_entry()
    {
        // when we come to state_entry, it can be from a number of different circumstances:
        // 1) the script has been reset
        // 2) the script has been edited
        // 3) the prim has been shift-drag copied
        // note that none of these have anything to do with being worn or removed.
        // but because we're probably going to be editing this script, and since the
        // user might reset it while wearing it, let's figure out if we're attached....
        if (llGetAttached())
        {
            // yes, we're attached, so we ask for permission to play animations.
            // which starts the whole cascade of permissions being given and
            // animation-playing. we also request the ability to take over the
            // controls, so that this script will stand a better chance of running
            // in no-script areas.
            llRequestPermissions(llGetOwner(),
                PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);
        }
    }

    run_time_permissions(integer perm)
    {
        // handle the permissions change, in case the user resets the script
        // or the scripter is changing the script and doesn't want to detach/reattach
        // as part of the development cycle
        // or the object goes across a sim border
        // or the avatar teleports
        //
        // all other code leads here.
        // when the user does anything with this scripted object, it will
        // ask for permission to trigger animations.
        // this event will always fire when we ask permissions, even if
        // we already have those permissions.
        // therefore we only ever start animations here.
        if (perm & PERMISSION_TRIGGER_ANIMATION)
        {
            // yay we got permission, so let's start animating:
            integer i;
            integer count = llGetListLength(gAnimations);
            for(i=0; i<count; ++i)
            {
                llStartAnimation(llList2String(gAnimations, i));
            }
        }
        if (perm & PERMISSION_TAKE_CONTROLS)
        {
            // we only want to take control so the script keeps working
            // in no-script areas. so we don't accept anything and pass
            // on everything
            llTakeControls(CONTROL_ML_LBUTTON, FALSE, TRUE);
        }
    }

    attach(key id)
    {
        // this event is fired when the prim is either attached or detached.
        // this means the object could be worn, dropped, or pulled back into inventory
        // so let's figure out which:
        if (id != NULL_KEY) // if id isn't null then we're attached.
        {
            // ..so we ask permission to do animations, which will cause
            // run_time_permissions to fire.
            llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
        }
        else // if the object hasn't been attached, it's either dropped or in inventory
        {
            // this is our last chance to clean up after ourselves by
            // stopping the animation
            if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION)
            {
                integer i;
                integer count = llGetListLength(gAnimations);
                for(i=0; i<count; ++i)
                {
                    llStopAnimation(llList2String(gAnimations, i));
                }
            }
        }
    }
    
    changed(integer what)
    {
        // if we're being worn, and the avatar crosses a sim border, the new sim
        // will have no idea what animations should be playing. so we have to tell it.
        //
        // we're interested in the CHANGED_REGION flag, because we only need to tell
        // the new simulator what animation to play.
        // note that CHANGED_REGION will only happen in the *root* prim of a multi-prim
        // object. this places a few restrictions on how we script attachments.
        if (what & CHANGED_REGION)
        {
            // ok, we're in a new sim, so start up the animations again....
            llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
        }
    }
}

,

Magic Sit Kit– 1.2

Expired

 

 

Original Author:  Whidou Bienstock

Create Date: 08-01-2008

Category: Animation

Description: 

Magic Sit System is the new easy way to configure sit targets on your chairs, beds, cars, rocks, walls, ...

No need for maths or calculation scripts. This is the free and lag-less alternative to the charmless pose balls.

 

 

Download Script Here: 

Download Script

 

 Magic Sti Script

 

 
// This script is licensed under GPL license version 2
//
// In short: feel free to redistribute and modify it, as long as
// any copies of it can be redistributed and modified as well.
//
// The official text of the licence is available at
// http://www.gnu.org/licences/gpl.html
//
// (c) The owner of Avatar Whidou Bienstock, 2008
integer CHANNEL = 48; // Channel of communication with the object
string NAME = "Magic Sit Cube - 1.2"; // Name of the Magic Sit Cube
integer listen_num;
// Start the first animation stored in the object, if any
startAnimation()
{
 if (llGetInventoryNumber(INVENTORY_ANIMATION)) // If there is at least one animation in the inventory
 {
 integer perm = llGetPermissions();
 
 if (perm & PERMISSION_TRIGGER_ANIMATION) // and if we can animate the avatar
 {
 string name = llGetInventoryName(INVENTORY_ANIMATION, 0);
llStopAnimation("sit"); // stop the default animation
 llStartAnimation(name); // and start the new one
 }
 else // else ask the permission
 llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
 }
}
// Stop the first animation stored in the object, if any
stopAnimation()
{
 if (llGetInventoryNumber(INVENTORY_ANIMATION)) // If there is at least one animation in the inventory
 {
 integer perm = llGetPermissions();
 
 if (perm & PERMISSION_TRIGGER_ANIMATION) // and if we can animate the avatar
 {
 string name = llGetInventoryName(INVENTORY_ANIMATION, 0);
llStopAnimation(name); // stop the animation
 }
 }
}
// Set the sit target
sitPose(string message)
{
 list msg = llParseString2List(message, [ "|" ], []); // Split the data
 vector avPos = (vector) llList2String(msg, 0); // Avatar's position
 rotation avRot = (rotation) llList2String(msg, 1); // Avatar's rotation
rotation rot = avRot / llGetRot(); // Difference between the 2 rotations
 vector pos = // Sit target offset
 (avPos - llGetPos()) / llGetRot() - <0, 0, 0.4>;
llSitTarget(pos, rot); // Sitpose the objet (the purpose of the whole thing)
 llOwnerSay("Object sitposed. I used the following instruction:
 llSitTarget(" + (string) pos + ", " + (string) rot + ");");
 llSetClickAction(CLICK_ACTION_SIT); // Make it easy to sit for new residents
 llOwnerSay("Sit target set. Your object is ready."); // Warn the owner
}
default
{
 state_entry()
 {
 listen_num = llListen(CHANNEL, NAME, NULL_KEY, ""); // Listen to the cube
 llOwnerSay("Magic Sit Script ready"); // Inform the owner
 }
listen(integer channel, string name, key id, string message)
 {
 if (llGetOwnerKey(id) == llGetOwner()) // Check that the cube has the same owner as the object
 {
 if (message == "*") // If the owner sits on the cube
 {
 startAnimation(); // then possibly animate his/her avatar
 }
 else // else if the owner unsits from the cube
 {
 llListenRemove(listen_num); // then remove the listen
 sitPose(message); // calculate the sit target
 stopAnimation(); // possibly stop the animation
 llRemoveInventory(llGetScriptName()); // and destroy this script
 }
 }
 }
run_time_permissions(integer perm)
 {
 if (perm & PERMISSION_TRIGGER_ANIMATION) // If the permission is granted
 {
 string name = llGetInventoryName(INVENTORY_ANIMATION, 0);
llStopAnimation("sit"); // stop the default animation
 llStartAnimation(name); // and start the new one
 }
 }
}

 

Magic Anim Acript

 
// This script is licensed under GPL license version 2
//
// In short: feel free to redistribute and modify it, as long as
// any copies of it can be redistributed and modified as well.
//
// The official text of the licence is available at
// http://www.gnu.org/licences/gpl.html
//
// (c) The owner of Avatar Whidou Bienstock, 2008
startAnimation()
{
 string name = llGetInventoryName(INVENTORY_ANIMATION, 0);
llStopAnimation("sit"); // Stop the default animation
 llStartAnimation(name); // and start the new one
}
stopAnimation()
{
 string name = llGetInventoryName(INVENTORY_ANIMATION, 0);
llStopAnimation(name); // Stop the animation
}
default
{
 
 changed(integer change)
 {
 if (change & CHANGED_LINK)
 {
 if (llGetInventoryNumber(INVENTORY_ANIMATION)) // If there is at least one animation in the inventory
 {
 key who = llAvatarOnSitTarget();
 integer perm = llGetPermissions();
if (who) // If someone sits down, animate the avatar
 {
 if ( (perm & PERMISSION_TRIGGER_ANIMATION) &&
 (who == llGetPermissionsKey())
 ) startAnimation();
 else
 llRequestPermissions(who, PERMISSION_TRIGGER_ANIMATION);
 }
 else // If the person stands up and was playing the animation, stop the animation
 {
 if (perm & PERMISSION_TRIGGER_ANIMATION)
 stopAnimation();
 }
 }
 }
 }
 
 run_time_permissions(integer perm)
 {
 if (perm & PERMISSION_TRIGGER_ANIMATION) // If the permission is granted, start the animation
 startAnimation();
 }
}

 

Have Questions? Need help? Leave a note for Kitsune Lassiter in Second Life

 

 

Additional Notes & Instructions(If any):

 

###############################################################
# #
# Magic Sit System v1.1 #
# #
# Open Source Sit Target Editor #
# GPL v2.0 License #
# Keep it full perms #
# #
###############################################################

I. Presentation

Magic Sit System is the new easy way to configure sit targets on your chairs, beds, cars, rocks, walls, ...

No need for maths or calculation scripts. This is the free and lag-less alternative to the charmless pose balls.

II. Why you should not use pose balls

If you just want to allow residents to sit on your object, each new pose ball adds an
unnecessary script to the simulator and therefore generates lag.

Each pose ball adds a new prim to your object, diminishing your allowed
prims count and generating lag.

Poseballs are not natural to use, they are a convention.

Poseballs are not aesthetical.

III. How to use the Magic Kit

1) Put the script named "Magic Sit Script" into the object you want to configure
2) Rez the "Magic Sit Cube"
3) Sit on the cube (left click is enough)
4) Right-click on the cube and select "Edit" in the pizza menu that appears
5) Move and rotate the cube until your avatar is in the desired position
6) Un-sit

To test the result, just sit on your object (left click should be enough).

At the end, the script named "Magic Sit Script" is automatically removed
from your object. You can remove the cube as well, or use it to set the
sit target of another object.

IV. Support for multiple sit targets

If you want several sit positions on your object (bank, couch...), repeat the above
sequence for the same number of prims in the object, using the "Edit linked parts"
checkbox.

V. Support for custom animations

Just drop your animation into the object before you start the above sequence.

When you have finished setting the sit target, you can leave the animation
in the object and add a script to play that animation when someone sits on your
object, for example, the "Magic Anim Script" included in this kit.

There's no support for multiple animations at this time.

VI. Legal Mentions

This sit posing kit is licensed under GPL license version 2

In short: feel free to redistribute and modify it, as long as any copies of it
can be redistributed and modified as well.

The official text of the license is available at
http://www.gnu.org/licences/gpl.html

(c) The owner of Avatar Whidou Bienstock, 2008