Bird Flight Script 8f1 // // Bird Flight Script // // Move the bird high enough that it won't hit anything right away and then click on it. // It will fly around the location vector set at the top of "timer". It will stay on about a quarter sim. // The z omponent of this vector is the maximum height. // (If it won't let you change the script, find a copy with full permissions.) // It attempts to resume flying after various problems, but if it stops or gets stuck, // move it where there is space to fly and click again once or twice. If that fails, reset the script. // (It may fail to climb if you launch it more than about 50 m below the set hight.) // // // There are no "if" statements controling the normal flight! The whole thing is done by simulating aerodynamics. // That is, by coupled differectial equations (approximated by difference equations), simulating a free flight model airplane. // It uses the SL physical vehicle type, and much additional dynamics and tuning is done by the script. // The bird (or airplane) is not forced to stay on the sim, it is steared, as a bird would stay above a food area. // Vertically, it stays off the ground by simulating a stable free flight model, // such as a Guillows rise off ground rubber powered model from a toy store or Langley's pioneering steam powered models. // To make long flights more interesting, the parametres are gradually varried with hight, // so that a stall is assured by the time it reaches the hight set in the top of "timer", below. // Mathematically the motion is deterministic at low altitude, in the strong sense of // the coupled differential equations being uniformly integrable. But the motion is chaotic at high altitude. // That is, the recovery from a stall can be arbitrarily sensetive to the exact motion at the point of stall. // The numerical solution captures some of the chaotic nature of a real world stalling airplane. // // // Based on: // Li'l Stinker Flight Script, by Fritz t. Cat (Fritz Kakapo) // // Since the version I started with was public domain, with free software intentions expressed, // I, Fritz t. Cat, hereby publish my modified version, below, under the GNU General Public License, // on 2009 July 14 and subsequent versions as available. This means that it is a copyright violation to set // no-copy, no-modify, no-transfer or turn off "allow anyone to copy" on this script, // the Li'l Stinker Airplane for which it was written, or anything derived from either of them. // And also that a GNU Licence statement and credits, according to the current version of the license, // must accompany anything derived from this script or airplane. I have reproduced the public domain script, // in a note card, for use in proprietary products. // The aerodynamics and algorithms used are not copyrightable and may be used as a guide to other scripts. // Please refer to some source, such as Wikipedia, for the exact license terms. // // I have kept some of the earlier comments here: //""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" // Simple airplane script example // THIS SCRIPT IS PUBLIC DOMAIN! Do not delete the credits at the top of this script! // Nov 25, 2003 - created by Andrew Linden and posted in the Second Life scripting forum // Jan 05, 2004 - Cubey Terra - minor changes: customized controls, added enable/disable physics events // Feel free to copy, modify, and use this script. // Always give credit to Andrew Linden and all people who modify it in a read me or in the object description. //"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" // // The script assumes that the root primitive is oriented such that its: // local x-axis points toward the nose of the plane, and its // local z-axis points toward the top. // // This bird script is tuned for a flight weight of 0.194306 virtual kilegrams, as of 2009.12.19. // //============================================================================================================= // // Particle System This is not bird-like but can be used to see the flight path more clearly. // //float rate = 0.1; // Adujusted in timer. // StartSteam() { // MASK FLAGS: set to "TRUE" to enable integer glow = TRUE; // Makes the particles glow integer bounce = FALSE; // Make particles bounce on Z plane of objects integer interpColor = TRUE; // Color - from start value to end value integer interpSize = TRUE; // Size - from start value to end value integer wind = FALSE; // Particles effected by wind integer followSource = FALSE; // Particles follow the source integer followVel = TRUE; // Particles turn to velocity direction // Choose a pattern from the following: // PSYS_SRC_PATTERN_EXPLODE // PSYS_SRC_PATTERN_DROP // PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY // PSYS_SRC_PATTERN_ANGLE_CONE // PSYS_SRC_PATTERN_ANGLE integer pattern = PSYS_SRC_PATTERN_EXPLODE; // Select a target for particles to go towards // "" for no target, "owner" will follow object owner // and "self" will target this object // or put the key of an object for particles to go to // Particle paramaters float age = 255.; // Life of each particle float maxSpeed = 0.03; // Max speed each particle is spit out at float minSpeed = 0.0; // Min speed each particle is spit out at string texture = "cloud for smoke"; // Texture used for particles, default used if blank float startAlpha = .8; // Start alpha (transparency) value float endAlpha = 0.05; // End alpha (transparency) value vector startColor = < 0.99, 0.99, 0.99 >; // Start color of particlesvector endColor = < 0.2, 0.7, 0.2 >; // End color of particles (if interpColor == TRUE) vector startSize = < 0.2, 0.2, 0>; // Start size of particles vector endSize = < 2., 2., 0 >; // End size of particles (if interpSize == TRUE) vector push = < 0., 0., 0. >; // Force pushed on particles // System paramaters float rate = 0.15; // How fast (rate) to emit particles float radius = 0.1; // Radius to emit particles for BURST pattern integer count = 1; // How many particles to emit per BURST float outerAngle = 0.; // Outer angle for all ANGLE patterns float innerAngle = 0.; // Inner angle for all ANGLE patterns vector omega = <0,0,0>; // Rotation of ANGLE patterns around the source float life = 0; // Life in seconds for the system to make particles // Script variables integer flags; flags = 0; if (glow) flags = flags | PSYS_PART_EMISSIVE_MASK; if (bounce) flags = flags | PSYS_PART_BOUNCE_MASK; if (interpColor) flags = flags | PSYS_PART_INTERP_COLOR_MASK; if (interpSize) flags = flags | PSYS_PART_INTERP_SCALE_MASK; if (wind) flags = flags | PSYS_PART_WIND_MASK; if (followSource) flags = flags | PSYS_PART_FOLLOW_SRC_MASK; if (followVel) flags = flags | PSYS_PART_FOLLOW_VELOCITY_MASK; llParticleSystem(); } // StopSteam() { llParticleSystem( ); } // //===================================================================================================== // // The thrust is saved and restored as it decays, to continue cruising. vector gLinearMotor = <0, 0, 0>; // // Used to handle exceptions: float last_time; // previously stored time of day vector last_pos_1a = <-7,-7,-7>; vector last_pos_1b = <-7,-7,-7>; vector last_pos_2a = <-7,-7,-7>; vector last_pos_2b = <-7,-7,-7>; integer kownt_1 = 0; integer kownt_2 = 0; float leap = 10.; integer flying = FALSE; // Keeps track of whether flying or pearched. integer pause = 1; // // Base values of dynamically varied parameters: float ANGULAR_DEFLECTION_TIMESCALE_0 = 8.; // Can be used to decrease stability with altitude. // float LINEAR_DEFLECTION_TIMESCALE_0 = 27.; // fuselage lift // float ANGULAR_MOTOR_TIMESCALE_0 = 1.0; // This is shortened in timer, to increase control effectiveness with speed. // vector ANGULAR_FRICTION_TIMESCALE_0 = < 0.10, 0.08, 0.58 >; // Along with angular motor time scale, // // vector steady_torque = < 0, 0, 0. >; // Aerodynamic torque, to add trim and dynamics. // integer new_collision = 5; // Decremented in timer. vector global_pos; // position relative to launch point, counting 246 m for each sim vector Center_0; // //-------------------------------------------------------------------------------------------------------- init() { llSetStatus( STATUS_PHYSICS, FALSE ); // Stop if already flying. // // // Set initial values of vehicle parameters. // llSetVehicleType( VEHICLE_TYPE_AIRPLANE ); // Sets default airplane-like parameters. // // action of the fin and stabilizer: Points toward velocity. // The front turns toward the current velocity. llSetVehicleFloatParam( VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 1. ); // "behave much like the deflection time scales" llSetVehicleFloatParam( VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, ANGULAR_DEFLECTION_TIMESCALE_0 / 2. ); // // fuselage lift. // Wing lift is handled with VEHICLE_LINEAR_FRICTION_TIMESCALE below. // The velocity turns toward the front. (Exact formula unknown.) llSetVehicleFloatParam( VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 1. ); // "behave much like the deflection time scales" llSetVehicleFloatParam( VEHICLE_LINEAR_DEFLECTION_TIMESCALE, LINEAR_DEFLECTION_TIMESCALE_0 ); // // propeller thrust strength // Shorter time scale makes it more stable. Longer makes a wider speed range. llSetVehicleFloatParam( VEHICLE_LINEAR_MOTOR_TIMESCALE, 2.0 ); // 1/strength // "it cannot be set longer than 120 seconds" llSetVehicleFloatParam( VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 15.); // Throttle gradually closes with time, but defeated: Refreshed below in timer. // // This controls the strength of the torques set in timer. llSetVehicleFloatParam( VEHICLE_ANGULAR_MOTOR_TIMESCALE, ANGULAR_MOTOR_TIMESCALE_0 ); // 1/strength // llSetVehicleFloatParam( VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 1.5 ); // Control returns to neutral when released. But it is reset in timer, so this ony matters when there is lag. // //--------------------- linear friction ------------------------------------------------ // The x component is parasite drag (along with VEHICLE_LINEAR_MOTOR_TIMESCALE). // The y component contributes to fuselage transverse lift and to drag due to yaw. // The effect of dyhedral depends on side slip. // The z component might seem to be just a vertical damping, but when pitch changes by a small amount, // most of the motion in the direction that was previously forward, becomes motion in the new forward direction, // with initially only a small transverse (up or down) component. With a short decay time scale // in the z direction, that component is lost quickly, so the motion continues to follow the pitch angle, with little loss. // The larger the z time constant is, the more "induced drag" there is. That is VEHICLE_LINEAR_FRICTION_TIMESCALE.z // greater than zero causes a drag that increases with lift, similarly to induced drag of a physical airplane. // // The z component gives the wing lift. Decreasing it allows the airplane to fly more slowly, // without loss of speed or altitude. But it seems to be near the limit, to fly slower one may need buoyancy. llSetVehicleVectorParam( VEHICLE_LINEAR_FRICTION_TIMESCALE, < 14., 2.0, 0.008 > ); // // This is damping of rotation. Physically it would increase with the length and wing span. // The z component is neccesary for the dihedral and sweepback to be effective. llSetVehicleVectorParam( VEHICLE_ANGULAR_FRICTION_TIMESCALE, ANGULAR_FRICTION_TIMESCALE_0 ); // Along with angular motor time scale, this damps the rotational motion. // llSetVehicleFloatParam( VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 1000 ); // CG below center of lift, pendulum period. llSetVehicleFloatParam( VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0 ); // damping, 0–1: 1. is fully damped. // This needs to be weak for a stunt airplane, that should fly nearly the same upside down as right side up. // It is desirable especially in free flight models, such as paper gliders. See the dynamic coupling in timer. // // This drives yaw in the direction of roll, imitating use of rudder by the pilot. llSetVehicleFloatParam( VEHICLE_BANKING_EFFICIENCY, 0 ); // Is there a difference between time scale llSetVehicleFloatParam( VEHICLE_BANKING_TIMESCALE, 1000 ); // and efficiency? llSetVehicleFloatParam( VEHICLE_BANKING_MIX, 0 ); // more yaw control when moving, 0 = none at rest. // Since this imitates a manual control, any convenient value set is physical (assuming a rotating tail wheel). // The Wright brothers found that mechanical coupling of the rudder and ailerons was not sufficient, // because of the delays involved. // It is not used here, because it was not intended for attitudes far from right side up. // // "hover can be better than sliding along the ground during takeoff and landing // but it only works over the terrain (not objects)" //llSetVehicleFloatParam(VEHICLE_HOVER_HEIGHT, 3.0); //llSetVehicleFloatParam(VEHICLE_HOVER_EFFICIENCY, 0.5); //llSetVehicleFloatParam(VEHICLE_HOVER_TIMESCALE, 2.0); //llSetVehicleFlags(VEHICLE_FLAG_HOVER_UP_ONLY); // // "non-zero buoyancy helps the airplane stay up // set to zero if you don't want this crutch" // This was useful in the initial stages of tuning. I think it simply reduces the gravitational // contribution to downward acceleration. It, here, is supposed to allow a longer timer setting. llSetVehicleFloatParam( VEHICLE_BUOYANCY, 0. ); // // Start with only vehicle torques. This is set in timer. llSetVehicleVectorParam( VEHICLE_ANGULAR_MOTOR_DIRECTION, <0,0,0> ); // //------------------------------------------------------------------------------------------------------- flying = FALSE; // Keep track of not flying. llSetTimerEvent( 0. ); // Stop timer. //StopSteam(); // Stop particles. llStopSound(); //llSetSoundQueueing( TRUE ); // This is supposed to make sounds wait for eachother, but it doesn't work. // So llSleep is used below to force wait. // //llSay(0, (string)llGetMass()+" virtual kilograms." ); llSay(0, "Cogito ergo sum."); // (quote from 1952 Galaxy science fiction story) llSay(0, "Touch to set center and start."); // // } // End init(). // //------------------------------------------------------------------------------------------------------------------- default { state_entry() { init(); } // on_rez(integer start_param) { init(); } // //---------------------------------------------------------------------------------------------------------------- touch_start(integer total_number) { if ( llDetectedOwner( 0 ) != llGetOwner() ) { // only the owner can use this vehicle llSay(0, "Please take a copy of this airplane or bird and fly your own copy. (If it is not set \"Free to copy\" or \"For sale l$ 0\", contact the owner or the creator.) You aren't the owner -- only the owner can fly this plane."); } else { // if ( ! flying ) { Center_0 = llGetPos(); global_pos = Center_0; // location relative to launch point llPlaySound( "parrot2", 1.0 ); // //StartSteam(); // Start paricle tracer smoke trail. // gLinearMotor = < 11., 0, 0. >; // Set thrust. llSetVehicleVectorParam( VEHICLE_LINEAR_MOTOR_DIRECTION, gLinearMotor ); // llSetStatus( STATUS_PHYSICS, TRUE ); // Enable physics. // llApplyImpulse( < 0.3, 0, 0.05 >, TRUE ); // Except for humbingbirds, birds run or push off with their feet. // flying = TRUE; llSay(0, "Started."); last_time = llGetTimeOfDay(); // to test for lag llSetTimerEvent( 0.5 ); // seconds Timer controls flight. // llSleep( 2. ); llLoopSound( "parrot1", 0.25 ); // } else { llSetStatus( STATUS_PHYSICS, FALSE ); llSay(0, "Stopped manually."); llSetTimerEvent( 0. ); // Stop timer. flying = FALSE; llStopSound(); //StopSteam(); // } // } // End owner. } // //====================================================================================================== timer() { //----------------------------------- Set parcel center. ------------------------------------------- // // This vector should be changed to match the location available for flight. <--------------------<<<< // //vector Center = < 128., 128., 30.+20.+llFabs(llGround(<0,0,0>)-20.) >; // Use constant east, north. //vector Center = Center_0 + < 0., 0., 30. >; // Use starting hight as flat ground level. Center_0.z = 0.; vector Center = Center_0 + < 0., 0., 30.+20.+llFabs(llGround(<0,0,0>)-20.) >; // higher over water //vector Center = Center_0 + < 0., 0., 30.+10.+llGround(<0,0,0>) >; // lower over water // // This is the locaiton that it flies around. The z component is about the top of the flight pattern // and should be high enough to keep it off the ground most of the time. // The bird will stear to stay near the horizontal part and below the vertical value. // //---------------------------- Update position + 256 * sim count. ------------------------------------ // vector pos = llGetPos(); // vector delta_pos = pos-global_pos; // if ( delta_pos.x < -128. ) delta_pos.x = delta_pos.x + 256.; else if ( delta_pos.x > 128. ) delta_pos.x = delta_pos.x - 256.; // if ( delta_pos.y < -128. ) delta_pos.y = delta_pos.y + 256.; else if ( delta_pos.y > 128. ) delta_pos.y = delta_pos.y - 256.; // global_pos += delta_pos; // //----------------------------- Get some flight data used below. ------------------------------------ rotation rot = llGetRot(); vector glob_dorsal = <0,0,1> * rot; // dorsal direction in global coordinates float horizontal = glob_dorsal * <0,0,1>; // vector v = llGetVel(); // float speed = llSqrt( v * v ); // //llShout( 0, (string) speed ); // debug and tuning // //-------------------------------- Refresh motor settings. ----------------------------------------- // llSetVehicleVectorParam( VEHICLE_LINEAR_MOTOR_DIRECTION, gLinearMotor ); // This is to defeat VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE. // //---------------- Include speed increase of contol surface effectiveness. ---------------------------------- // llSetVehicleFloatParam( VEHICLE_LINEAR_DEFLECTION_TIMESCALE, LINEAR_DEFLECTION_TIMESCALE_0 / ( 0.5 + 0.5 * speed / 8. ) ); // fuselage lift // llSetVehicleFloatParam( VEHICLE_ANGULAR_MOTOR_TIMESCALE, ANGULAR_MOTOR_TIMESCALE_0 / ( 0.15 + 0.85 * llSqrt( speed*speed ) / 8. ) ); // 1/strength of controls // // //--------------------------------------------- Dynamics ------------------------------------------------------ // // steady_torque = < 0., 0, 0. >; // // >>>>>>-------------------------> Stear toward parcel center. <--------------------------------------<<<<<< // (It can be allowed to wander by removing this section.) // vector toCenter = Center - global_pos; // global vector to center of parcel // if ( toCenter.z < 0. ) { jump skip_dynamics; } // None of this dynamics makes any sense if we are above ceiling! // // Roll and yaw to the port of center, moving inward and to starboard when moving away from center. // This moves it toward center, when circling right. vector h_toCenter = toCenter; h_toCenter.z = 0; // No vertical here. vector loc_h_toCenter = h_toCenter / rot; // global to local coordinate transformation; vector left = -loc_h_toCenter; left.y = 0; left.z = -2. * left.x; // Roll component goes to roll and yaw. steady_torque += left * 0.0016 * speed; // Roll to left of center, to right away. // // Turn toward center. This tends to move it to center when not circeling. vector turn_toCenter = < 1, 0, 0 > % loc_h_toCenter; // Forward x redius = torque toward center. steady_torque += turn_toCenter * 0.0030 * speed; // Adjust strength. Add to torque. // // // This replaces the code above, to move cross country: //steady_torque += < -1, 1, 0 > / llSqrt(2.) * 1.2 / llGetRot(); // Turn to east. // This line directs the average direction approximatly East. Rotate for other directions. // That is, the version tested goes around 135 degrees to the right of the above constant vector. // // //-------------------------------------- Reduce stability at high altitude. -------------------------------- float stability = toCenter.z / 30.; stability = llFabs( stability ) + 0.001; // There have been run time math errors. float sqr_stab = llSqrt( stability ); float fourR_stab = llSqrt( sqr_stab ) ; float eightR_stab = llSqrt( fourR_stab ) ; // llSetVehicleFloatParam( VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, ANGULAR_DEFLECTION_TIMESCALE_0 / ( 0.6 + 0.4*speed/8. ) * ( 0.1 + 0.9*stability ) ); // fin and stabalizer // Too much fin and stabalizer reduces dynamic stability, at maximum height. // llSetVehicleVectorParam( VEHICLE_ANGULAR_FRICTION_TIMESCALE, ANGULAR_FRICTION_TIMESCALE_0 / ( sqr_stab ) ); // Along with angular motor time scale, // Less angular friction reduces static (angle only) stability damping. // // //--------------------------- Dynamic Coupling and Trim Tuneing ----------------------------------------------- // vector local_vel = v / rot; // global to local coordines // // Spiral right to help stay in sim (and stabalize phugoid). float right = 0.; right += 0.04 * local_vel.x * fourR_stab; right += 0.024 * local_vel.x * local_vel.x * fourR_stab; right += 0.002 * local_vel.x * local_vel.x * local_vel.x; steady_torque.x += right; steady_torque.z -= 1.5 * right; // // Dihedral: Wing tip on the downward side lifts when moving sideways. // If VEHICLE_ANGULAR_FRICTION_TIMESCALE.z holds the nose back from the turn // and VEHICLE_LINEAR_FRICTION_TIMESCALE.y lets it slip slip sideways, // then the dihedral lifts the inside wing in a turn. // steady_torque.x += 4. * local_vel.y; // steady_torque.x += 0.5 * local_vel.y * speed * fourR_stab; // steady_torque.x += 0.06 * local_vel.y * speed * speed * fourR_stab; // // // Wing sweep-back --- similar to dyhedral but only works when lifting // The wing that is yawed forward and the body is sideslipping toward has more lift. steady_torque.x -= 0.5 *( local_vel.y * local_vel.z * local_vel.x ); steady_torque.x -= 0.5 *( local_vel.y * local_vel.z * local_vel.x * local_vel.x ); // // Turn upward: This is the trim incidence of the stabalizer. steady_torque.y -= 0.10 * speed; // Low powers of speed control the climb angle. steady_torque.y -= 0.30 * local_vel.x * speed * speed; // The high powers of speed make it recover quickly from steep dives. steady_torque.y -= 0.03 * speed * speed * speed * speed / fourR_stab; // // Turn downward: Like the paper clip on the nose of a paper airplane. steady_torque.y += 1.; // A steep slope of this torque with speed steady_torque.y += 1.3 * horizontal // makes the phugoid unstable. * sqr_stab; // Fades out to make it stall. // llSetVehicleVectorParam( VEHICLE_ANGULAR_MOTOR_DIRECTION, steady_torque ); // Apply the torque. // @skip_dynamics; //----------------------------------- Handle Exceptions -------------------------------------------- // // Lag float time = llGetTimeOfDay(); // if ( time > last_time + 5. ) // Usually when crossing sim boundaries. { llSetStatus( STATUS_PHYSICS, FALSE ); // Turn off physics. llSay( 0, "Flight suspended, for timer timeout." ); pause = -20; } last_time = time; // // Recovers from trying to enter restricted space. if ( !llGetStatus(STATUS_PHYSICS) && flying && pause>0 ) { llSetRot( llGetRot() * llAxisAngle2Rot( <0,0,1>, PI*2./3. ) ); pause = -10; } // // Low "energy" float e = llGetEnergy(); // if ( e < 0.95 ) { llSay( 0, (string) e ); // if ( e < 0.5 ) { llSetStatus( STATUS_PHYSICS, FALSE ); // Pause physics. llSay( 0, "Flight suspended, to catch his breath." ); pause = -30; } } // // Continue after timed pause. pause += 1; if ( pause == 0 && flying ) { llPlaySound( "parrot2", 1.0 ); llSetStatus( STATUS_PHYSICS, TRUE ); llSleep( 2. ); llLoopSound( "parrot1", 0.25 ); } // //------------------------------------------------------------------------------------------------------------- // // Break away if stuck. if ( llGetStatus( STATUS_PHYSICS ) ) { if ( kownt_1 == 40 ) { vector diff_a = pos - last_pos_1a; vector diff_b = pos - last_pos_1b; if ( diff_a*diff_a + diff_b*diff_b < 2. ) { llPlaySound( "parrot2", 1.0 ); llSay( 0, "Stuck!" ); llSetStatus(STATUS_PHYSICS, FALSE); pos.z += leap; // Attempt to jump over obsticle. if ( pos.z > Center.z ) { pos.z = Center.z; } // But not above set ceiling. llSetPos( pos ); llSetStatus(STATUS_PHYSICS, TRUE); leap += 10.; llSleep( 2. ); llLoopSound( "parrot1", 0.25 ); } last_pos_1b = last_pos_1a; last_pos_1a = pos; kownt_1 = 0; } // if ( kownt_2 == 400 ) { vector diff_a = pos - last_pos_2a; vector diff_b = pos - last_pos_2b; if ( diff_a*diff_a + diff_b*diff_b < 6. ) { llPlaySound( "parrot2", 1.0 ); llSay( 0, "Stuck!" ); llSetStatus(STATUS_PHYSICS, FALSE); pos.z += leap; // Attempt to jump over obsticle. if ( pos.z > Center.z ) { pos.z = Center.z; } // But not above set ceiling. llSetPos( pos ); llSetStatus(STATUS_PHYSICS, TRUE); leap += 10.; llSleep( 2. ); llLoopSound( "parrot1", 0.25 ); } last_pos_2b = last_pos_2a; last_pos_2a = pos; kownt_2 = 0; } kownt_1 += 1; kownt_2 += 1; } // End STATUS_PHYSICS. // new_collision -= 1; // // } // End timer. ------------------------------------------------------------------------------------------- // land_collision( vector pos ) // It tends to get stuck on its back like a turtle. { if ( flying ) { if ( new_collision <= 0 ) { llStopSound(); // ? llPlaySound( "parrot2", 1.0 ); // llSetStatus( STATUS_PHYSICS, FALSE ); // Must be non-physical to set pos and rot. // llSetPos( llGetPos() + < 0, 0, 7. > ); // rotation rot = llGetRot(); vector forward = llRot2Fwd( rot ); forward.z = 0.; // Keep only the rotation around the vertical axis. rot = llAxes2Rot( forward, <0,0,1.>%forward, <0,0,1.> ); rot = llAxisAngle2Rot( <0, -1. ,0>, 30.*PI/180. ) * rot; rot = llAxisAngle2Rot( <0,0, -1. >, 45.*PI/180. ) * rot; rot = llAxisAngle2Rot( < 1., 0,0>, 10.*PI/180. ) * rot; llSetRot( rot ); // llSetStatus( STATUS_PHYSICS, TRUE ); // //llSay(0, "Ouch!" ); // llApplyImpulse( < 0.05, 0, 0.002 >, TRUE ); // Except for humbingbirds, birds run or push off with there feet. // last_time = llGetTimeOfDay(); // Don't time out for the time it took to do this. //llSleep( 2. ); This was for the sound, but I think the script engine is not multi-threaded. llStopSound(); // ? Otherwise it loops the wrong sound !? llLoopSound( "parrot1", 0.25 ); new_collision = 10; } } else { llSetStatus( STATUS_PHYSICS, FALSE ); } } // End land_collision. // collision( integer n ) // It tends to get stuck on its back like a turtle. { if ( flying ) { if ( new_collision <= 0 ) { llStopSound(); // ? llPlaySound( "parrot2", 0.1 ); // llSetStatus( STATUS_PHYSICS, FALSE ); // Must be non-physical to set pos and rot. // rotation rot = llGetRot(); vector forward = llRot2Fwd( rot ); forward.z = 0.; // Keep only the rotation around the vertical axis. rot = llAxes2Rot( forward, <0,0,1.>%forward, <0,0,1.> ); rot = llAxisAngle2Rot( <0, -1. ,0>, 30.*PI/180. ) * rot; rot = llAxisAngle2Rot( <0,0, -1. >, 45.*PI/180. ) * rot; rot = llAxisAngle2Rot( < 1., 0,0>, 10.*PI/180. ) * rot; llSetRot( rot ); // llSetPos( llGetPos() + < 0, 0, 2. > ); llSetStatus( STATUS_PHYSICS, TRUE ); // //llSay(0, "Ouch!" ); // llApplyImpulse( < 0.1, 0, 0.07 >, TRUE ); // Except for humbingbirds, birds run or push off with there feet. // last_time = llGetTimeOfDay(); // Don't time out for the time it took to do this. //llSleep( 2. ); This was for the sound, but I think the script engine is not multi-threaded. llStopSound(); // ? Otherwise it loops the wrong sound !? llLoopSound( "parrot1", 0.05 ); new_collision = 10; } } else { llSetStatus( STATUS_PHYSICS, FALSE ); } } // End collision. } // End default. // //============================================================================================================================= // //============================================================================================================================= //