Join us in Outworldz at www.outworldz.com:9000 or follow us:

Search dozens of selected web sites for OpenSim and LSL script

New! Script Meta-Search will search thousands of scripts here and at other sites for LSL or Opensim scripts.
Loading

Want to add a script or a project? Upload it and a half million people will see it and your name here this year.

Home   Show All
Category: Contributor: Creator
Animal Free_flight_bird_script  

Free_flight_bird_script

I am posting this script with the warnim...

Category: Animal
By : Fritz Kakapo
Created: 2010-09-02 Edited: 2010-09-02
Worlds: Second Life

the Zip file

Download all files for Free_flight_bird_script
Contents are in zip format, with .LSL (text) source code and LSLEdit (text + Solution) formats.
Get file # 1. Free_flight_bird_script_1.lsl
1 //
2
3 // Bird Flight Script
4
5 //
6
7 // Move the bird high enough that it won't hit anything right away and then click on it.
8
9 // It will fly around the location vector set at the top of "timer". It will stay on about a quarter sim.
10
11 // The z omponent of this vector is the maximum height.
12
13 // (If it won't let you change the script, find a copy with full permissions.)
14
15 // It attempts to resume flying after various problems, but if it stops or gets stuck,
16
17 // move it where there is space to fly and click again once or twice. If that fails, reset the script.
18
19 // (It may fail to climb if you launch it more than about 50 m below the set hight.)
20
21 //
22
23 //
24
25 // There are no "if" statements controling the normal flight! The whole thing is done by simulating aerodynamics.
26
27 // That is, by coupled differectial equations (approximated by difference equations), simulating a free flight model airplane.
28
29 // It uses the SL physical vehicle type, and much additional dynamics and tuning is done by the script.
30
31 // The bird (or airplane) is not forced to stay on the sim, it is steared, as a bird would stay above a food area.
32
33 // Vertically, it stays off the ground by simulating a stable free flight model,
34
35 // such as a Guillows rise off ground rubber powered model from a toy store or Langley's pioneering steam powered models.
36
37 // To make long flights more interesting, the parametres are gradually varried with hight,
38
39 // so that a stall is assured by the time it reaches the hight set in the top of "timer", below.
40
41 // Mathematically the motion is deterministic at low altitude, in the strong sense of
42
43 // the coupled differential equations being uniformly integrable. But the motion is chaotic at high altitude.
44
45 // That is, the recovery from a stall can be arbitrarily sensetive to the exact motion at the point of stall.
46
47 // The numerical solution captures some of the chaotic nature of a real world stalling airplane.
48
49 //
50
51 //
52
53 // Based on:
54
55 // Li'l Stinker Flight Script, by Fritz t. Cat (Fritz Kakapo)
56
57 //
58
59 // Since the version I started with was public domain, with free software intentions expressed,
60
61 // I, Fritz t. Cat, hereby publish my modified version, below, under the GNU General Public License,
62
63 // on 2009 July 14 and subsequent versions as available. This means that it is a copyright violation to set
64
65 // no-copy, no-modify, no-transfer or turn off "allow anyone to copy" on this script,
66
67 // the Li'l Stinker Airplane for which it was written, or anything derived from either of them.
68
69 // And also that a GNU Licence statement and credits, according to the current version of the license,
70
71 // must accompany anything derived from this script or airplane. I have reproduced the public domain script,
72
73 // in a note card, for use in proprietary products.
74
75 // The aerodynamics and algorithms used are not copyrightable and may be used as a guide to other scripts.
76
77 // Please refer to some source, such as Wikipedia, for the exact license terms.
78
79 //
80
81 // I have kept some of the earlier comments here:
82
83 //"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
84
85 // Simple airplane script example
86
87 // THIS SCRIPT IS PUBLIC DOMAIN! Do not delete the credits at the top of this script!
88
89 // Nov 25, 2003 - created by Andrew Linden and posted in the Second Life scripting forum
90
91 // Jan 05, 2004 - Cubey Terra - minor changes: customized controls, added enable/disable physics events
92
93 // Feel free to copy, modify, and use this script.
94
95 // Always give credit to Andrew Linden and all people who modify it in a read me or in the object description.
96
97 //""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
98
99 //
100
101 // The script assumes that the root primitive is oriented such that its:
102
103 // local x-axis points toward the nose of the plane, and its
104
105 // local z-axis points toward the top.
106
107 //
108
109 // This bird script is tuned for a flight weight of 0.194306 virtual kilegrams, as of 2009.12.19.
110
111 //
112
113 //=============================================================================================================
114
115 //
116
117 // Particle System This is not bird-like but can be used to see the flight path more clearly.
118
119 //
120
121 //float rate = 0.1; // Adujusted in timer.
122
123 //
124
125 StartSteam()
126
127 {
128
129 // MASK FLAGS: set to "TRUE" to enable
130
131 integer glow = TRUE; // Makes the particles glow
132
133 integer bounce = FALSE; // Make particles bounce on Z plane of objects
134
135 integer interpColor = TRUE; // Color - from start value to end value
136
137 integer interpSize = TRUE; // Size - from start value to end value
138
139 integer wind = FALSE; // Particles effected by wind
140
141 integer followSource = FALSE; // Particles follow the source
142
143 integer followVel = TRUE; // Particles turn to velocity direction
144
145
146
147
148
149
150
151
152
153
154
155 // Choose a pattern from the following:
156
157 // PSYS_SRC_PATTERN_EXPLODE
158
159 // PSYS_SRC_PATTERN_DROP
160
161 // PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY
162
163 // PSYS_SRC_PATTERN_ANGLE_CONE
164
165 // PSYS_SRC_PATTERN_ANGLE
166
167
168
169 integer pattern = PSYS_SRC_PATTERN_EXPLODE;
170
171
172
173
174
175
176
177 // Select a target for particles to go towards
178
179 // "" for no target, "owner" will follow object owner
180
181 // and "self" will target this object
182
183 // or put the key of an object for particles to go to
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199 // Particle paramaters
200
201
202
203 float age = 255.; // Life of each particle
204
205 float maxSpeed = 0.03; // Max speed each particle is spit out at
206
207 float minSpeed = 0.0; // Min speed each particle is spit out at
208
209 string texture = "cloud for smoke"; // Texture used for particles, default used if blank
210
211 float startAlpha = .8; // Start alpha (transparency) value
212
213 float endAlpha = 0.05; // End alpha (transparency) value
214
215 vector startColor = < 0.99, 0.99, 0.99 >; // Start color of particles <R,G,B>
216
217 vector endColor = < 0.2, 0.7, 0.2 >; // End color of particles <R,G,B> (if interpColor == TRUE)
218
219 vector startSize = < 0.2, 0.2, 0>; // Start size of particles
220
221 vector endSize = < 2., 2., 0 >; // End size of particles (if interpSize == TRUE)
222
223 vector push = < 0., 0., 0. >; // Force pushed on particles
224
225
226
227
228
229
230
231 // System paramaters
232
233
234
235 float rate = 0.15; // How fast (rate) to emit particles
236
237 float radius = 0.1; // Radius to emit particles for BURST pattern
238
239 integer count = 1; // How many particles to emit per BURST
240
241 float outerAngle = 0.; // Outer angle for all ANGLE patterns
242
243 float innerAngle = 0.; // Inner angle for all ANGLE patterns
244
245 vector omega = <0,0,0>; // Rotation of ANGLE patterns around the source
246
247 float life = 0; // Life in seconds for the system to make particles
248
249
250
251
252
253
254
255 // Script variables
256
257
258
259 integer flags;
260
261
262
263
264
265
266
267
268
269 flags = 0;
270
271
272
273
274
275
276
277 if(glow) flags = flags | PSYS_PART_EMISSIVE_MASK;
278
279 if(bounce) flags = flags | PSYS_PART_BOUNCE_MASK;
280
281 if(interpColor) flags = flags | PSYS_PART_INTERP_COLOR_MASK;
282
283 if(interpSize) flags = flags | PSYS_PART_INTERP_SCALE_MASK;
284
285 if(wind) flags = flags | PSYS_PART_WIND_MASK;
286
287 if(followSource) flags = flags | PSYS_PART_FOLLOW_SRC_MASK;
288
289 if(followVel) flags = flags | PSYS_PART_FOLLOW_VELOCITY_MASK;
290
291
292
293
294
295
296
297
298
300
301 PSYS_PART_FLAGS,flags,
302
303 PSYS_PART_START_COLOR, startColor,
304
305 PSYS_PART_END_COLOR, endColor,
306
307 PSYS_PART_START_SCALE,startSize,
308
309 PSYS_PART_END_SCALE,endSize,
310
311 PSYS_SRC_PATTERN, pattern,
312
314
315 PSYS_SRC_ACCEL, push,
316
318
320
322
324
325 PSYS_SRC_INNERANGLE,innerAngle,
326
327 PSYS_SRC_OUTERANGLE,outerAngle,
328
329 PSYS_SRC_OMEGA, omega,
330
331 PSYS_SRC_MAX_AGE, life,
332
333 PSYS_SRC_TEXTURE, texture,
334
335 PSYS_PART_START_ALPHA, startAlpha,
336
337 PSYS_PART_END_ALPHA, endAlpha
338
339 ]);
340
341
342
343 }
344
345 //
346
347 StopSteam()
348
349 {
350
352
353 }
354
355 //
356
357 //=====================================================================================================
358
359 //
360
361 // The thrust is saved and restored as it decays, to continue cruising.
362
363 vector gLinearMotor = <0, 0, 0>;
364
365 //
366
367 // Used to handle exceptions:
368
369 float last_time; // previously stored time of day
370
371 vector last_pos_1a = <-7,-7,-7>;
372
373 vector last_pos_1b = <-7,-7,-7>;
374
375 vector last_pos_2a = <-7,-7,-7>;
376
377 vector last_pos_2b = <-7,-7,-7>;
378
379 integer kownt_1 = 0;
380
381 integer kownt_2 = 0;
382
383 float leap = 10.;
384
385 integer flying = FALSE; // Keeps track of whether flying or pearched.
386
387 integer pause = 1;
388
389 //
390
391 // Base values of dynamically varied parameters:
392
393 float ANGULAR_DEFLECTION_TIMESCALE_0 = 8.; // Can be used to decrease stability with altitude.
394
395 //
396
397 float LINEAR_DEFLECTION_TIMESCALE_0 = 27.; // fuselage lift
398
399 //
400
401 float ANGULAR_MOTOR_TIMESCALE_0 = 1.0; // This is shortened in timer, to increase control effectiveness with speed.
402
403 //
404
405 vector ANGULAR_FRICTION_TIMESCALE_0 = < 0.10, 0.08, 0.58 >; // Along with angular motor time scale,
406
407 //
408
409 //
410
411 vector steady_torque = < 0, 0, 0. >; // Aerodynamic torque, to add trim and dynamics.
412
413 //
414
415 integer new_collision = 5; // Decremented in timer.
416
417 vector global_pos; // position relative to launch point, counting 246 m for each sim
418
419 vector Center_0;
420
421 //
422
423 //--------------------------------------------------------------------------------------------------------
424
425 init()
426
427 {
428
429 llSetStatus( STATUS_PHYSICS, FALSE ); // Stop if already flying.
430
431 //
432
433 //
434
435 // Set initial values of vehicle parameters.
436
437 //
438
439 llSetVehicleType( VEHICLE_TYPE_AIRPLANE ); // Sets default airplane-like parameters.
440
441 //
442
443 // action of the fin and stabilizer: Points toward velocity.
444
445 // The front turns toward the current velocity.
446
448
449 // "behave much like the deflection time scales"
450
451 llSetVehicleFloatParam( VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, ANGULAR_DEFLECTION_TIMESCALE_0 / 2. );
452
453 //
454
455 // fuselage lift.
456
457 // Wing lift is handled with VEHICLE_LINEAR_FRICTION_TIMESCALE below.
458
459 // The velocity turns toward the front. (Exact formula unknown.)
460
462
463 // "behave much like the deflection time scales"
464
465 llSetVehicleFloatParam( VEHICLE_LINEAR_DEFLECTION_TIMESCALE, LINEAR_DEFLECTION_TIMESCALE_0 );
466
467 //
468
469 // propeller thrust strength
470
471 // Shorter time scale makes it more stable. Longer makes a wider speed range.
472
473 llSetVehicleFloatParam( VEHICLE_LINEAR_MOTOR_TIMESCALE, 2.0 ); // 1/strength
474
475 // "it cannot be set longer than 120 seconds"
476
478
479 // Throttle gradually closes with time, but defeated: Refreshed below in timer.
480
481 //
482
483 // This controls the strength of the torques set in timer.
484
485 llSetVehicleFloatParam( VEHICLE_ANGULAR_MOTOR_TIMESCALE, ANGULAR_MOTOR_TIMESCALE_0 ); // 1/strength
486
487 //
488
489 llSetVehicleFloatParam( VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 1.5 );
490
491 // Control returns to neutral when released. But it is reset in timer, so this ony matters when there is lag.
492
493 //
494
495 //--------------------- linear friction ------------------------------------------------
496
497 // The x component is parasite drag (along with VEHICLE_LINEAR_MOTOR_TIMESCALE).
498
499 // The y component contributes to fuselage transverse lift and to drag due to yaw.
500
501 // The effect of dyhedral depends on side slip.
502
503 // The z component might seem to be just a vertical damping, but when pitch changes by a small amount,
504
505 // most of the motion in the direction that was previously forward, becomes motion in the new forward direction,
506
507 // with initially only a small transverse (up or down) component. With a short decay time scale
508
509 // in the z direction, that component is lost quickly, so the motion continues to follow the pitch angle, with little loss.
510
511 // The larger the z time constant is, the more "induced drag" there is. That is VEHICLE_LINEAR_FRICTION_TIMESCALE.z
512
513 // greater than zero causes a drag that increases with lift, similarly to induced drag of a physical airplane.
514
515 //
516
517 // The z component gives the wing lift. Decreasing it allows the airplane to fly more slowly,
518
519 // without loss of speed or altitude. But it seems to be near the limit, to fly slower one may need buoyancy.
520
522
523 //
524
525 // This is damping of rotation. Physically it would increase with the length and wing span.
526
527 // The z component is neccesary for the dihedral and sweepback to be effective.
528
529 llSetVehicleVectorParam( VEHICLE_ANGULAR_FRICTION_TIMESCALE, ANGULAR_FRICTION_TIMESCALE_0 );
530
531 // Along with angular motor time scale, this damps the rotational motion.
532
533 //
534
535 llSetVehicleFloatParam( VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 1000 ); // CG below center of lift, pendulum period.
536
537 llSetVehicleFloatParam( VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0 ); // damping, 0–1: 1. is fully damped.
538
539 // This needs to be weak for a stunt airplane, that should fly nearly the same upside down as right side up.
540
541 // It is desirable especially in free flight models, such as paper gliders. See the dynamic coupling in timer.
542
543 //
544
545 // This drives yaw in the direction of roll, imitating use of rudder by the pilot.
546
547 llSetVehicleFloatParam( VEHICLE_BANKING_EFFICIENCY, 0 ); // Is there a difference between time scale
548
549 llSetVehicleFloatParam( VEHICLE_BANKING_TIMESCALE, 1000 ); // and efficiency?
550
551 llSetVehicleFloatParam( VEHICLE_BANKING_MIX, 0 ); // more yaw control when moving, 0 = none at rest.
552
553 // Since this imitates a manual control, any convenient value set is physical (assuming a rotating tail wheel).
554
555 // The Wright brothers found that mechanical coupling of the rudder and ailerons was not sufficient,
556
557 // because of the delays involved.
558
559 // It is not used here, because it was not intended for attitudes far from right side up.
560
561 //
562
563 // "hover can be better than sliding along the ground during takeoff and landing
564
565 // but it only works over the terrain (not objects)"
566
568
570
572
574
575 //
576
577 // "non-zero buoyancy helps the airplane stay up
578
579 // set to zero if you don't want this crutch"
580
581 // This was useful in the initial stages of tuning. I think it simply reduces the gravitational
582
583 // contribution to downward acceleration. It, here, is supposed to allow a longer timer setting.
584
586
587 //
588
589 // Start with only vehicle torques. This is set in timer.
590
592
593 //
594
595 //-------------------------------------------------------------------------------------------------------
596
597 flying = FALSE; // Keep track of not flying.
598
599 llSetTimerEvent( 0. ); // Stop timer.
600
601 //StopSteam(); // Stop particles.
602
604
605 //llSetSoundQueueing( TRUE ); // This is supposed to make sounds wait for eachother, but it doesn't work.
606
607 // So llSleep is used below to force wait.
608
609 //
610
611 //llSay(0, (string)llGetMass()+" virtual kilograms." );
612
613 llSay(0, "Cogito ergo sum."); // (quote from 1952 Galaxy science fiction story)
614
615 llSay(0, "Touch to set center and start."); //
616
617 //
618
619 } // End init().
620
621 //
622
623 //-------------------------------------------------------------------------------------------------------------------
624
625 default
626
627 {
628
630
631 {
632
633 init();
634
635 }
636
637 //
638
639 on_rez(integer start_param)
640
641 {
642
643 init();
644
645 }
646
647 //
648
649 //----------------------------------------------------------------------------------------------------------------
650
651 touch_start(integer total_number)
652
653 {
654
655 if( llDetectedOwner( 0 ) != llGetOwner() )
656
657 {
658
659 // only the owner can use this vehicle
660
661 llSay(0, "Please take a copy of this airplane or bird and fly your own copy.
662
663 (If it is not set \"Free to copy\" or \"For sale l$ 0\", contact the owner or the creator.)
664
665 You aren't the owner -- only the owner can fly this plane.");
666
667 }
668
669 else
670
671 {
672
673 //
674
675 if( ! flying )
676
677 {
678
679 Center_0 = llGetPos();
680
681 global_pos = Center_0; // location relative to launch point
682
683 llPlaySound( "parrot2", 1.0 );
684
685 //
686
687 //StartSteam(); // Start paricle tracer smoke trail.
688
689 //
690
691 gLinearMotor = < 11., 0, 0. >; // Set thrust.
692
694
695 //
696
697 llSetStatus( STATUS_PHYSICS, TRUE ); // Enable physics.
698
699 //
700
701 llApplyImpulse( < 0.3, 0, 0.05 >, TRUE ); // Except for humbingbirds, birds run or push off with their feet.
702
703 //
704
705 flying = TRUE;
706
707 llSay(0, "Started.");
708
709 last_time = llGetTimeOfDay(); // to test for lag
710
711 llSetTimerEvent( 0.5 ); // seconds Timer controls flight.
712
713 //
714
715 llSleep( 2. );
716
717 llLoopSound( "parrot1", 0.25 );
718
719 //
720
721 }
722
723 else
724
725 {
726
728
729 llSay(0, "Stopped manually.");
730
731 llSetTimerEvent( 0. ); // Stop timer.
732
733 flying = FALSE;
734
736
737 //StopSteam();
738
739 //
740
741 }
742
743 //
744
745 } // End owner.
746
747 }
748
749 //
750
751 //======================================================================================================
752
753 timer()
754
755 {
756
757 //----------------------------------- Set parcel center. -------------------------------------------
758
759 //
760
761 // This vector should be changed to match the location available for flight. <--------------------<<<<
762
763 //
764
765 //vector Center = < 128., 128., 30.+20.+llFabs(llGround(<0,0,0>)-20.) >; // Use constant east, north.
766
767 //vector Center = Center_0 + < 0., 0., 30. >; // Use starting hight as flat ground level.
768
769 Center_0.z = 0.;
770
771 vector Center = Center_0 + < 0., 0., 30.+20.+llFabs(llGround(<0,0,0>)-20.) >; // higher over water
772
773 //vector Center = Center_0 + < 0., 0., 30.+10.+llGround(<0,0,0>) >; // lower over water
774
775 //
776
777 // This is the locaiton that it flies around. The z component is about the top of the flight pattern
778
779 // and should be high enough to keep it off the ground most of the time.
780
781 // The bird will stear to stay near the horizontal part and below the vertical value.
782
783 //
784
785 //---------------------------- Update position + 256 * sim count. ------------------------------------
786
787 //
788
789 vector pos = llGetPos();
790
791 //
792
793 vector delta_pos = pos-global_pos;
794
795 //
796
797 if( delta_pos.x < -128. ) delta_pos.x = delta_pos.x + 256.;
798
799 else if( delta_pos.x > 128. ) delta_pos.x = delta_pos.x - 256.;
800
801 //
802
803 if( delta_pos.y < -128. ) delta_pos.y = delta_pos.y + 256.;
804
805 else if( delta_pos.y > 128. ) delta_pos.y = delta_pos.y - 256.;
806
807 //
808
809 global_pos += delta_pos;
810
811 //
812
813 //----------------------------- Get some flight data used below. ------------------------------------
814
815 rotation rot = llGetRot();
816
817 vector glob_dorsal = <0,0,1> * rot; // dorsal direction in global coordinates
818
819 float horizontal = glob_dorsal * <0,0,1>;
820
821 //
822
823 vector v = llGetVel();
824
825 //
826
827 float speed = llSqrt( v * v );
828
829 //
830
831 //llShout( 0, (string) speed ); // debug and tuning
832
833 //
834
835 //-------------------------------- Refresh motor settings. -----------------------------------------
836
837 //
838
840
841 // This is to defeat VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE.
842
843 //
844
845 //---------------- Include speed increase of contol surface effectiveness. ----------------------------------
846
847 //
848
850
851 / ( 0.5 + 0.5 * speed / 8. ) ); // fuselage lift
852
853 //
854
856
857 / ( 0.15 + 0.85 * llSqrt( speed*speed ) / 8. ) ); // 1/strength of controls
858
859 //
860
861 //
862
863 //--------------------------------------------- Dynamics ------------------------------------------------------
864
865 //
866
867 //
868
869 steady_torque = < 0., 0, 0. >;
870
871 //
872
873 // >>>>>>-------------------------> Stear toward parcel center. <--------------------------------------<<<<<<
874
875 // (It can be allowed to wander by removing this section.)
876
877 //
878
879 vector toCenter = Center - global_pos; // global vector to center of parcel
880
881 //
882
883 if( toCenter.z < 0. ) { jump skip_dynamics; } // None of this dynamics makes any sense if we are above ceiling!
884
885 //
886
887 // Roll and yaw to the port of center, moving inward and to starboard when moving away from center.
888
889 // This moves it toward center, when circling right.
890
891 vector h_toCenter = toCenter;
892
893 h_toCenter.z = 0; // No vertical here.
894
895 vector loc_h_toCenter = h_toCenter / rot; // global to local coordinate transformation;
896
897 vector left = -loc_h_toCenter;
898
899 left.y = 0;
900
901 left.z = -2. * left.x; // Roll component goes to roll and yaw.
902
903 steady_torque += left * 0.0016 * speed; // Roll to left of center, to right away.
904
905 //
906
907 // Turn toward center. This tends to move it to center when not circeling.
908
909 vector turn_toCenter = < 1, 0, 0 > % loc_h_toCenter;
910
911 // Forward x [vector cross product] redius = torque toward center.
912
913 steady_torque += turn_toCenter * 0.0030 * speed; // Adjust strength. Add to torque.
914
915 //
916
917 //
918
919 // This replaces the code above, to move cross country:
920
921 //steady_torque += < -1, 1, 0 > / llSqrt(2.) * 1.2 / llGetRot(); // Turn to east.
922
923 // This line directs the average direction approximatly East. Rotate for other directions.
924
925 // That is, the version tested goes around 135 degrees to the right of the above constant vector.
926
927 //
928
929 //
930
931 //-------------------------------------- Reduce stability at high altitude. --------------------------------
932
933 float stability = toCenter.z / 30.;
934
935 stability = llFabs( stability ) + 0.001; // There have been run time math errors.
936
937 float sqr_stab = llSqrt( stability );
938
939 float fourR_stab = llSqrt( sqr_stab ) ;
940
941 float eightR_stab = llSqrt( fourR_stab ) ;
942
943 //
944
946
947 / ( 0.6 + 0.4*speed/8. ) * ( 0.1 + 0.9*stability ) ); // fin and stabalizer
948
949 // Too much fin and stabalizer reduces dynamic stability, at maximum height.
950
951 //
952
954
955 / ( sqr_stab ) );
956
957 // Along with angular motor time scale,
958
959 // Less angular friction reduces static (angle only) stability damping.
960
961 //
962
963 //
964
965 //--------------------------- Dynamic Coupling and Trim Tuneing -----------------------------------------------
966
967 //
968
969 vector local_vel = v / rot; // global to local coordines
970
971 //
972
973 // Spiral right to help stay in sim (and stabalize phugoid).
974
975 float right = 0.;
976
977 right += 0.04 * local_vel.x * fourR_stab;
978
979 right += 0.024 * local_vel.x * local_vel.x * fourR_stab;
980
981 right += 0.002 * local_vel.x * local_vel.x * local_vel.x;
982
983 steady_torque.x += right;
984
985 steady_torque.z -= 1.5 * right;
986
987 //
988
989 // Dihedral: Wing tip on the downward side lifts when moving sideways.
990
991 // If VEHICLE_ANGULAR_FRICTION_TIMESCALE.z holds the nose back from the turn
992
993 // and VEHICLE_LINEAR_FRICTION_TIMESCALE.y lets it slip slip sideways,
994
995 // then the dihedral lifts the inside wing in a turn.
996
997 //
998
999 steady_torque.x += 4. * local_vel.y; //
1000
1001 steady_torque.x += 0.5 * local_vel.y * speed * fourR_stab; //
1002
1003 steady_torque.x += 0.06 * local_vel.y * speed * speed * fourR_stab; //
1004
1005 //
1006
1007 // Wing sweep-back --- similar to dyhedral but only works when lifting
1008
1009 // The wing that is yawed forward and the body is sideslipping toward has more lift.
1010
1011 steady_torque.x -= 0.5 *( local_vel.y * local_vel.z * local_vel.x );
1012
1013 steady_torque.x -= 0.5 *( local_vel.y * local_vel.z * local_vel.x * local_vel.x );
1014
1015 //
1016
1017 // Turn upward: This is the trim incidence of the stabalizer.
1018
1019 steady_torque.y -= 0.10 * speed;
1020
1021 // Low powers of speed control the climb angle.
1022
1023 steady_torque.y -= 0.30 * local_vel.x * speed * speed;
1024
1025 // The high powers of speed make it recover quickly from steep dives.
1026
1027 steady_torque.y -= 0.03 * speed * speed * speed * speed / fourR_stab;
1028
1029 //
1030
1031 // Turn downward: Like the paper clip on the nose of a paper airplane.
1032
1033 steady_torque.y += 1.; // A steep slope of this torque with speed
1034
1035 steady_torque.y += 1.3 * horizontal // makes the phugoid unstable.
1036
1037 * sqr_stab; // Fades out to make it stall.
1038
1039 //
1040
1041 llSetVehicleVectorParam( VEHICLE_ANGULAR_MOTOR_DIRECTION, steady_torque ); // Apply the torque.
1042
1043 //
1044
1045 @skip_dynamics;
1046
1047 //----------------------------------- Handle Exceptions --------------------------------------------
1048
1049 //
1050
1051 // Lag
1052
1053 float time = llGetTimeOfDay();
1054
1055 //
1056
1057 if( time > last_time + 5. ) // Usually when crossing sim boundaries.
1058
1059 {
1060
1061 llSetStatus( STATUS_PHYSICS, FALSE ); // Turn off physics.
1062
1063 llSay( 0, "Flight suspended, for timer timeout." );
1064
1065 pause = -20;
1066
1067 }
1068
1069 last_time = time;
1070
1071 //
1072
1073 // Recovers from trying to enter restricted space.
1074
1075 if( !llGetStatus(STATUS_PHYSICS) && flying && pause>0 )
1076
1077 {
1078
1079 llSetRot( llGetRot() * llAxisAngle2Rot( <0,0,1>, PI*2./3. ) );
1080
1081 pause = -10;
1082
1083 }
1084
1085 //
1086
1087 // Low "energy"
1088
1089 float e = llGetEnergy();
1090
1091 //
1092
1093 if( e < 0.95 )
1094
1095 {
1096
1097 llSay( 0, (string) e );
1098
1099 //
1100
1101 if( e < 0.5 )
1102
1103 {
1104
1105 llSetStatus( STATUS_PHYSICS, FALSE ); // Pause physics.
1106
1107 llSay( 0, "Flight suspended, to catch his breath." );
1108
1109 pause = -30;
1110
1111 }
1112
1113 }
1114
1115 //
1116
1117 // Continue after timed pause.
1118
1119 pause += 1;
1120
1121 if( pause == 0 && flying )
1122
1123 {
1124
1125 llPlaySound( "parrot2", 1.0 );
1126
1128
1129 llSleep( 2. );
1130
1131 llLoopSound( "parrot1", 0.25 );
1132
1133 }
1134
1135 //
1136
1137 //-------------------------------------------------------------------------------------------------------------
1138
1139 //
1140
1141 // Break away if stuck.
1142
1144
1145 {
1146
1147 if( kownt_1 == 40 )
1148
1149 {
1150
1151 vector diff_a = pos - last_pos_1a;
1152
1153 vector diff_b = pos - last_pos_1b;
1154
1155 if( diff_a*diff_a + diff_b*diff_b < 2. )
1156
1157 {
1158
1159 llPlaySound( "parrot2", 1.0 );
1160
1161 llSay( 0, "Stuck!" );
1162
1164
1165 pos.z += leap; // Attempt to jump over obsticle.
1166
1167 if( pos.z > Center.z )
1168
1169 { pos.z = Center.z; } // But not above set ceiling.
1170
1171 llSetPos( pos );
1172
1174
1175 leap += 10.;
1176
1177 llSleep( 2. );
1178
1179 llLoopSound( "parrot1", 0.25 );
1180
1181 }
1182
1183 last_pos_1b = last_pos_1a;
1184
1185 last_pos_1a = pos;
1186
1187 kownt_1 = 0;
1188
1189 }
1190
1191 //
1192
1193 if( kownt_2 == 400 )
1194
1195 {
1196
1197 vector diff_a = pos - last_pos_2a;
1198
1199 vector diff_b = pos - last_pos_2b;
1200
1201 if( diff_a*diff_a + diff_b*diff_b < 6. )
1202
1203 {
1204
1205 llPlaySound( "parrot2", 1.0 );
1206
1207 llSay( 0, "Stuck!" );
1208
1210
1211 pos.z += leap; // Attempt to jump over obsticle.
1212
1213 if( pos.z > Center.z )
1214
1215 { pos.z = Center.z; } // But not above set ceiling.
1216
1217 llSetPos( pos );
1218
1220
1221 leap += 10.;
1222
1223 llSleep( 2. );
1224
1225 llLoopSound( "parrot1", 0.25 );
1226
1227 }
1228
1229 last_pos_2b = last_pos_2a;
1230
1231 last_pos_2a = pos;
1232
1233 kownt_2 = 0;
1234
1235 }
1236
1237 kownt_1 += 1;
1238
1239 kownt_2 += 1;
1240
1241 } // End STATUS_PHYSICS.
1242
1243 //
1244
1245 new_collision -= 1;
1246
1247 //
1248
1249 //
1250
1251 } // End timer. -------------------------------------------------------------------------------------------
1252
1253 //
1254
1255 land_collision( vector pos ) // It tends to get stuck on its back like a turtle.
1256
1257 {
1258
1259 if( flying )
1260
1261 {
1262
1263 if( new_collision <= 0 )
1264
1265 {
1266
1267 llStopSound(); // ?
1268
1269 llPlaySound( "parrot2", 1.0 );
1270
1271 //
1272
1273 llSetStatus( STATUS_PHYSICS, FALSE ); // Must be non-physical to set pos and rot.
1274
1275 //
1276
1277 llSetPos( llGetPos() + < 0, 0, 7. > );
1278
1279 //
1280
1281 rotation rot = llGetRot();
1282
1283 vector forward = llRot2Fwd( rot );
1284
1285 forward.z = 0.; // Keep only the rotation around the vertical axis.
1286
1287 rot = llAxes2Rot( forward, <0,0,1.>%forward, <0,0,1.> );
1288
1289 rot = llAxisAngle2Rot( <0, -1. ,0>, 30.*PI/180. ) * rot;
1290
1291 rot = llAxisAngle2Rot( <0,0, -1. >, 45.*PI/180. ) * rot;
1292
1293 rot = llAxisAngle2Rot( < 1., 0,0>, 10.*PI/180. ) * rot;
1294
1295 llSetRot( rot );
1296
1297 //
1298
1300
1301 //
1302
1303 //llSay(0, "Ouch!" );
1304
1305 //
1306
1307 llApplyImpulse( < 0.05, 0, 0.002 >, TRUE ); // Except for humbingbirds, birds run or push off with there feet.
1308
1309 //
1310
1311 last_time = llGetTimeOfDay(); // Don't time out for the time it took to do this.
1312
1313 //llSleep( 2. ); This was for the sound, but I think the script engine is not multi-threaded.
1314
1315 llStopSound(); // ? Otherwise it loops the wrong sound !?
1316
1317 llLoopSound( "parrot1", 0.25 );
1318
1319 new_collision = 10;
1320
1321 }
1322
1323 }
1324
1325 else
1326
1327 {
1328
1330
1331 }
1332
1333 } // End land_collision.
1334
1335 //
1336
1337 collision( integer n ) // It tends to get stuck on its back like a turtle.
1338
1339 {
1340
1341 if( flying )
1342
1343 {
1344
1345 if( new_collision <= 0 )
1346
1347 {
1348
1349 llStopSound(); // ?
1350
1351 llPlaySound( "parrot2", 0.1 );
1352
1353 //
1354
1355 llSetStatus( STATUS_PHYSICS, FALSE ); // Must be non-physical to set pos and rot.
1356
1357 //
1358
1359 rotation rot = llGetRot();
1360
1361 vector forward = llRot2Fwd( rot );
1362
1363 forward.z = 0.; // Keep only the rotation around the vertical axis.
1364
1365 rot = llAxes2Rot( forward, <0,0,1.>%forward, <0,0,1.> );
1366
1367 rot = llAxisAngle2Rot( <0, -1. ,0>, 30.*PI/180. ) * rot;
1368
1369 rot = llAxisAngle2Rot( <0,0, -1. >, 45.*PI/180. ) * rot;
1370
1371 rot = llAxisAngle2Rot( < 1., 0,0>, 10.*PI/180. ) * rot;
1372
1373 llSetRot( rot );
1374
1375 //
1376
1377 llSetPos( llGetPos() + < 0, 0, 2. > );
1378
1380
1381 //
1382
1383 //llSay(0, "Ouch!" );
1384
1385 //
1386
1387 llApplyImpulse( < 0.1, 0, 0.07 >, TRUE ); // Except for humbingbirds, birds run or push off with there feet.
1388
1389 //
1390
1391 last_time = llGetTimeOfDay(); // Don't time out for the time it took to do this.
1392
1393 //llSleep( 2. ); This was for the sound, but I think the script engine is not multi-threaded.
1394
1395 llStopSound(); // ? Otherwise it loops the wrong sound !?
1396
1397 llLoopSound( "parrot1", 0.05 );
1398
1399 new_collision = 10;
1400
1401 }
1402
1403 }
1404
1405 else
1406
1407 {
1408
1410
1411 }
1412
1413 } // End collision.
1414
1415 } // End default.

Back to the Best Free Tools in Second Life and OpenSim.