Don't click here unless you want to be banned.

LSL Wiki : LibraryRopeConstraint

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawl338.us.archive.org

Rope Constraint


This script creates a pseudo-realistic rope constraint between two objects. Put this script in two nearby physics objects; they should detect one another and become joined by a particle-based representation of a rope. Making one of the objects non-physical and suspending it in mid-air high enough should cause the other, physical object to swing under it. (In fact, it's much less dangerous this way.) This does not require the llPushObject function to be allowed.

// Pseudo-Realistic Rope Constraint by Comrade Podolsky
// Free for non-commercial use.
// Free for commercial use, but if possible, please notify me of what use you found for it. (Besides tether-ball.) But you don't have to.
// And of course, anyone is free and encouraged to modify this script for more specific applications.
// If you need help adapting this script for anything, feel free to try to contact me in-game, but I am rarely online.

integer lockon = FALSE;
float rope_length = 5.0; // Obviously, the length of the simulated rope. (It will stretch slightly longer than this, though)
float dampening = 0.04; // This dampens a fraction of the object's velocity every 0.1 seconds, if the rope is stretched.
float bouncing = 0.4; // How much the object "bounces" back after stretching the rope to the limit of its length. This applies if the rope is stretched suddenly. 0.4 means it will bounce back with  40% of its original velocity. Setting this to below 0 will make the constraint act more stretchy than ropes normally do. Setting this to above 1 will make it unstable and dangerous.
float constant = 16.0; // The force constant of the rope. This applies when the rope is stretched slowly - in which case, it acts sort of like a spring.
key target;
vector ropecolor;
list rope_effect = [];

default
{
    state_entry()
    {
        llListen(12345,"","","TEST123");
        llSetTimerEvent(5.0);
    }

    timer() { if ( !lockon ){llWhisper(12345,"TEST123"); } } // Automatically locate "other" objects
    
    listen(integer chan, string name, key id, string msg)
    {
        if (!lockon)
        {
            lockon = TRUE;
            llWhisper(12345,"TEST123");
            llSetTimerEvent(0.0);
            target = id;
            llSensorRepeat("", target, SCRIPTED, 20.0, PI, 0.1); // This part may get rather resource-consuming. For slower-moving objects, and objects roped to something static, range may be decreased and delay may be increased.
            //Sensor range must be at least twice the length of the rope. Stretching the rope farther will cause it to act like it breaks, but it will restore itself if the objects are moved back together.
            
            rope_effect = // This is the particle effect representation of the rope. Change the colors, alphas, scales, and textures however you like. I can't say how it will affect the effect if you change anything else.
            [
                PSYS_PART_FLAGS,            PSYS_PART_FOLLOW_SRC_MASK | PSYS_PART_FOLLOW_VELOCITY_MASK | PSYS_PART_TARGET_LINEAR_MASK | PSYS_PART_TARGET_POS_MASK,
                
                PSYS_SRC_PATTERN,           PSYS_SRC_PATTERN_DROP,
                PSYS_SRC_TARGET_KEY,        target,
                
                PSYS_PART_START_COLOR,      ropecolor,
                PSYS_PART_END_COLOR,        ropecolor,
                PSYS_PART_START_ALPHA,      1.0,
                PSYS_PART_END_ALPHA,        1.0,
                PSYS_PART_START_SCALE,      <0.05,1.0,1.0>,
                PSYS_PART_END_SCALE,        <0.05,1.0,1.0>,
                PSYS_SRC_TEXTURE,           "",
                
                PSYS_PART_MAX_AGE,          0.5,
                PSYS_SRC_BURST_RATE,        0.001,
                PSYS_SRC_BURST_PART_COUNT,  1
            ];
            
            llParticleSystem(rope_effect);
        }
    }
    
    sensor(integer num_detected)
    {
        vector i_pos = llGetPos();
        vector u_pos = llDetectedPos(0);
        
        if (llVecMag(u_pos-i_pos)>rope_length)
        {
            llSetForce(constant*llGetMass()*llVecNorm(u_pos-i_pos)*(llVecMag(u_pos-i_pos) - rope_length),FALSE); // This is how an ideal spring would behave under these conditions. Without this statement, the rope would stretch slowly but indefinitely. Ropes do not work that way.
            llApplyImpulse( llGetMass() * llGetVel() * dampening * -1.0 , FALSE ); // This dampens the motion of the object, preventing buildup of excess kinetic energy through oscillation.
            vector wrongway = llVecNorm(i_pos - u_pos); // The direction in which the object should NOT be moving
            float wrongmag = ( llGetVel() - llDetectedVel(0) ) * wrongway; // The velocity with which the object is apparently moving, against the pull of the rope.
            if ( wrongmag > 0.0 ) { llApplyImpulse( llGetMass() * ( ( -1.0 - bouncing ) * ( wrongway * wrongmag ) ) , FALSE ); } // Stop the object from stretching too much farther than rope length.
        }
        else { llSetForce( ZERO_VECTOR, FALSE ); } // If the two objects are closer than rope length, the rope doesn't do anything.
    }
    
    no_sensor()
    {
        llSetForce( ZERO_VECTOR, FALSE );
    } // If the other object is nowhere to be seen, this object stops doing stuff.
}
There is one comment on this page. [Display comments/form]