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
Vehicles Lil_Stinker_a_better_approach_to_sl  

Lil_Stinker_a_better_approach_to_sl

Basic flight script for birds
This script uses the SL physics engine to implement a standard simple linearized model of the flight of an airplane. As far a the author knows, this is the only real attempt by an sl scripter to model the forces on a flying body. Other flight scripts (except derivatives of this one) start from a generic sl vehicle and add airplane-like features such as banking and a minimum flight speed, an approach that will not lead to realistic flight without endless correction.
This script is still distributed under a GNU Free Public License, but, in case the copyright covers more than I realize, I specifically grant permission to use the methods and short sections of this script in proprietary scripts. Direct derivatives, on the other hand, can be used in proprietary airplanes, but the derived scripts must be distributed in editable form, in some way.

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

the Zip file

Download all files for Lil_Stinker_a_better_approach_to_sl
Contents are in zip format, with .LSL (text) source code and LSLEdit (text + Solution) formats.
Get file # 1. Lil_Stinker_a_better_approach_to_sl_1.lsl
1
2 // Li'l Stinker Flight Script, by Fritz t. Cat (Fritz Kakapo)
3
4 //
5
6 // Since the version I started with was public domain, with free software intentions expressed,
7
8 // I, Fritz t. Cat, hereby publish my modified version, below, under the GNU General Public License,
9
10 // on 2009 July 14 and subsequent versions as available. This means that it is a copyright violation to set
11
12 // no-copy, no-modify, no-transfer or turn off "allow anyone to copy" on this script,
13
14 // the Li'l Stinker Airplane for which it was written, or anything derived from either of them.
15
16 // And also that a GNU Licence statement and credits, according to the current version of the license,
17
18 // must accompany anything derived from this script or airplane. I have reproduced the public domain script,
19
20 // in a note card, for use in proprietary products.
21
22 // Airplanes with scripts derived from this one need to be sold or given along with a copy of the same code version
23
24 // as is in the airplane. Derived airplanes with other scripts need to be full permissions or distributed
25
26 // along with a full permissions version, but the unrelated script need not be copyable.
27
28 // The aerodynamics and algorithms uses are not copyrightable and may be freely used as a guide to other scripts.
29
30 // Please refer to some source, such as Wikipedia, for the exact license terms.
31
32 //
33
34 // I have kept some of the earlier comments here:
35
36 //"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
37
38 // Simple airplane script example
39
40 // THIS SCRIPT IS PUBLIC DOMAIN! Do not delete the credits at the top of this script!
41
42 // Nov 25, 2003 - created by Andrew Linden and posted in the Second Life scripting forum
43
44 // Jan 05, 2004 - Cubey Terra - minor changes: customized controls, added enable/disable physics events
45
46 // Feel free to copy, modify, and use this script.
47
48 // Always give credit to Andrew Linden and all people who modify it in a read me or in the object description.
49
50 //"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
51
52 //
53
54 // See the accompanying note card for operating instructions. <-----------------------------------------<<<<
55
56 //
57
58 //"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
59
60 //
61
62 // The VICE is taken from "Flight Script EEv3 (VICE 1.2.0)" and "VICE ALA Test Airplane v. 1.2.0".
63
64 //
65
66 //"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
67
68 //
69
70 // Since virtual materials are cheap, I am using carbon nanotubes for most of the structure,
71
72 // so this airplane is very light!
73
74 // (Alos other carbon forms and other materials not easily obtained in rl.
75
76 // The piston rings are osmium boride. Diamond is used extensively in the engine,
77
78 // because of its good heat conductivity.)
79
80 //
81
82 // The script assumes that the root primitive is oriented such that its:
83
84 // local x-axis points toward the nose of the plane, and its
85
86 // local z-axis points toward the top.
87
88 //
89
90 // Lift is proportional to the square of the speed, like centrifugal force, so (excluding structural failure)
91
92 // an airplane can turn in the same radius at high speed as at low speed, unlike a car. (Actually perhaps
93
94 // somewhat smaller, due to Reynolds number effects.) Without correction, the lift here due to turning the velocity
95
96 // is only proportional to the speed. Though still better than a car, that is not fully realistic or fun.
97
98 // If this were corrected, one could learn a maneuver and then keep doing it faster, as long as the simulator
99
100 // could support the speed and acceleration. This has partially been done in the timer routine near the end.
101
102 //
103
104 // The physics engine that applies the forces controled by the VEHICLE parameters appears to run at
105
106 // about 40 frames per second. These functions include lift and drag, as well as applying the torqes and damping
107
108 // set in timer, and calculation of the resulting rotation and motion. The controls are done with abrupt torques,
109
110 // so the time scale is that of the arrow key input, like ordinary SL movement and flying. An instantaneous torque is
111
112 // about the same response speed as simple mechanically operated control surfaces.
113
114 // The dynamic coupling and trim added, to make it really fly like an
115
116 // airplane, instead of like a generalized vehicle that flies and banks, runs in timer. The time interrupt
117
118 // rate is set for 0.5 sec., and the script tries to conpensate for slow response by slowing down.
119
120 //
121
122 //-----------------------------------------------------------------------------------------------------------------------------------
123
124 //
125
126 // Free VICE airplane script credits:
127
128 // This airplane is a freebie; it includes a modified freebie flight script (EEV3) designed to support VICE
129
130 // In VICE terms, this airplane is an ALA with 2 LMG guns (contained in the gun prims, naturally)
131
132 // This VICE mod is by Creem Pye, April 1 2008
133
134 // Special thanks to Xenox Snook for supplying the fuselage!
135
136 // All the other people credited below worked on the airplane script, as far as I know...
137
138 //
139
140 // Modified from Cubey Terra DIY Plane 1.0 by Eoin Widget and Kerian Bunin
141
142 // which was originaly marked as September 10, 2005
143
144 // Distribute freely. Go ahead and modify it for your own uses. Improve it and share it around.
145
146 // Some portions based on the Linden airplane script originall posted in the forums.
147
148 // ** Last Modified by Eoin Widget on March 26, 2006 **
149
150 //
151
152 //===================================================================================================================================
153
154 //
155
156 //
157
158 // control flags that we set later
159
160 integer gAngularControls = 0;
161
162 integer gLinearControls = 0;
163
164 //
165
166 // The propeller thrust is saved and restored as it decays, to continue cruising.
167
168 vector gLinearMotor = < 0, 0, 0 >;
169
170 //
171
172 float last_time = 99999999.; // previously stored time of day
173
174 integer sit = FALSE; // keeps track of whether flying or parked
175
176 integer motor_idle = TRUE; // Motor has been set to zero speed by touching the airplane.
177
178 //
179
180 float torque_factor = 1.; // Used to increase control effectiveness with speed.
181
182 //
183
184 vector steady_torque = < 0, 0, 0. >; // Aerodynamic dynamic torque, independant of controls.
185
186 //
187
188 float LINEAR_MOTOR_TIMESCALE_0 = 2.; // 1/strength when going slow
189
190 //
191
192 float ANGULAR_MOTOR_TIMESCALE_0 = 2.5 ; // 1/strength. Damping and dynamic torque.
193
194 //
195
196 vector LINEAR_FRICTION_TIMESCALE_0 = < 30., 4., 0.50 >;
197
198 //
199
200 vector ANGULAR_FRICTION_TIMESCALE_0 = < 2.5, 2.5, 7.5 >; // Along with angular motor time scale,
201
202 //
203
204 float speed = 0.;
205
206 float maxThrottle = 45;
207
208 float timer_dialation = 1.; // Slow down when lag is bad.
209
210 float o_t_d = 1.; // previous value of slow down
211
212 float energy = 1.; // From the physics engine.
213
214 //
215
216 float mass;
217
218 float mass_factor = 1.; // Adapt to a particular airplane.
219
220 float buoyancy = 0.3; // buoyancy for no lag, depends on touring or advanced mode
221
222 //
223
224 integer listenHandle;
225
226 integer homing = FALSE; // Try to stay in si
227
228 //
229
230 key pilot=NULL_KEY;
231
232 //
233
234 integer edges = 0;
235
236 integer levels = 0;
237
238 //
239
240 integer updating = FALSE;
241
242 integer kownt_3; // time since last control entry
243
244 //
245
246 //-----------------------------------------------------------------------------------------------------------------------------------
247
248 integer HUDon = TRUE;
249
250 string HUDtext="";
251
252 vector HUDcolor;
253
254 vector local_vel;
255
256 //===================================================================================================================================
257
258 //
259
260 //
261
262 // This is called whenever there is flight control input, from timer, from control, from listen and from touch_start.
263
264 Update()
265
266 {
267
268 if( updating ) jump GOTO; // Skip possible reentrant call, if possible in this system.
269
270 updating = TRUE;
271
272 //
273
274 vector v = llGetVel();
275
276 speed = llSqrt( v * v );
277
278 //
279
280 //----------------------------------------------- Handle Exceptions, Environment-----------------------------------------------------
281
282 //
283
284 // Slow down for lag. Pause if too bad.
285
286 float time = llGetTimeOfDay();
287
288 float time_interval = time - last_time;
289
290 if( time_interval <= 0. ) time_interval = 0.5; // Fix bad times.
291
292 last_time = time;
293
294 //
295
296 float lag = 1. / llSqrt( time_interval*time_interval + 1. ); // << 1 = laggy, otherwize near 1.
297
298 //
299
300 if( lag < timer_dialation )
301
302 { timer_dialation = lag; } // Take new lag if worse.
303
304 else
305
306 { timer_dialation = timer_dialation * 0.5 + lag * 0.5; } // Else smooth out a bit.
307
308 //
309
310 vector pos = llGetPos();
311
312 //
313
314 if( pos.x < -1. || pos.x > 257. ) { timer_dialation = timer_dialation*0.4; }
315
316 // Slow for delayed handover or other problem.
317
318 if( pos.y < -1. || pos.y > 257. ) { timer_dialation = timer_dialation*0.4; } // But continue along end of world.
319
320 if( pos.z < -1. ) { timer_dialation = timer_dialation*0.4; }
321
322 if( pos.z > 4000. )
323
324 {
325
326 llApplyImpulse( < -100., 0, -40. >, TRUE ); // Push back and down to stay on world.
327
328 llApplyRotationalImpulse( < 1.7, 1.7, -1.7 >, TRUE );
329
330 gLinearMotor = gLinearMotor*0.97;
331
332 llWhisper(0, "Altitude ceiling reached." );
333
334 } // But not top.
335
336 //
337
338 if( timer_dialation < 0.3 && timer_dialation < o_t_d ) { llWhisper(0, "Slowed to " + (string)timer_dialation + " for lag."); }
339
340 o_t_d = timer_dialation;
341
342 //
343
344 // Now look if we are approaching edge of sim.
345
346 vector projected = pos + v*time_interval*1.5; // engeneering margin
347
348 //
349
350 if( projected.x < 0. || projected.x > 256. )
351
352 {
353
354 if( llEdgeOfWorld( pos, < v.x, 0, 0 > ) )
355
356 {
357
358 // I want to turn away from the edge, but that is not simple.
359
360 // Can't set the speed, have to apply a force or impulse away from edge of world.
361
362 }
363
364 else // Expect sim crossing before next entry.
365
366 {
367
368 timer_dialation = timer_dialation * 0.2; // Slow down for crossing.
369
370 }
371
372 }
373
374 if( projected.y < 0. || projected.y > 256. )
375
376 {
377
378 if( llEdgeOfWorld( pos, < v.y, 0, 0 > ) )
379
380 {
381
382 // I want to turn away from the edge, but that is not simple.
383
384 // Can't set the speed, have to apply a force or impulse away from edge of world.
385
386 }
387
388 else // Expect sim crossing before next entry.
389
390 {
391
392 timer_dialation = timer_dialation * 0.2; // Slow down for crossing.
393
394 }
395
396 }
397
398 //
399
400 //
401
402 llSetVehicleVectorParam( VEHICLE_ANGULAR_FRICTION_TIMESCALE, ANGULAR_FRICTION_TIMESCALE_0 * timer_dialation );
403
404 //
405
406 llSetVehicleFloatParam( VEHICLE_BUOYANCY, 1. - timer_dialation*(1.-buoyancy) );
407
408 //
409
410 llSetVehicleVectorParam( VEHICLE_LINEAR_FRICTION_TIMESCALE, LINEAR_FRICTION_TIMESCALE_0 * timer_dialation / (speed+0.0005) );
411
412 //
413
414 if( time_interval > 20. * (1.+buoyancy) )
415
416 { llSetStatus(STATUS_PHYSICS, FALSE); llWhisper( 0, "Flight suspended, for timeout. Click to resume." ); }
417
418 // Turn off physics. Wait for user to be able to touch aircraft, showing that a simulator has them back together.
419
420 // Usually when crossing sim boundaries.
421
422 //
423
424 // See if the simulator thinks we have been too busy.
425
426 energy = energy * 0.75 + llGetEnergy() * 0.25; // Smooth over sim crossings.
427
428 if( energy < 0.45 )
429
430 {
431
432 llWhisper( 0, "Energy reduced to" + (string)energy );
433
434 //
435
436 if( energy < 0.2 )
437
438 { llSetStatus(STATUS_PHYSICS, FALSE); llWhisper( 0, "Flight suspended, to let the engine cool." ); } // Pause physics.
439
440 }
441
442 // End Exeptions.
443
444 //
445
446 //-------------------------Include speed increase of contol surface effectiveness. --------------------------
447
448 //
449
450 torque_factor = ( 0.15 + 40. * speed/8. * speed/8. ) * mass_factor * timer_dialation * (1.-buoyancy) * (1.-buoyancy);
451
452 //
453
454 llSetVehicleFloatParam( VEHICLE_ANGULAR_MOTOR_TIMESCALE, ANGULAR_MOTOR_TIMESCALE_0 / torque_factor );
455
456 //
457
458 //-------------------------------------------------------------------------------------------------------------------------------
459
460 steady_torque = < 0., 0, 0. >; // Start with no turn.
461
462 //
463
464 //---------------------------------------------------- Control ----------------------------------------------------------------
465
466 //
467
468 // only change linear motor if one or more of the linear controls is pressed, and only once
469
470 if( edges & levels & gLinearControls )
471
472 {
473
474 //
475
476 if( edges & levels & CONTROL_UP )
477
478 {
479
480 if( gLinearMotor.x < maxThrottle ) // "Damped to about 30." Over 30 to cover drag.
481
482 gLinearMotor.x += 3.;
483
484 }
485
486 if( edges & levels & CONTROL_DOWN )
487
488 {
489
490 if( gLinearMotor.x > -maxThrottle/3. )
491
492 gLinearMotor.x -= 3.;
493
494 }
495
496 //
497
498 if( levels & CONTROL_DOWN && levels & CONTROL_UP )
499
500 {
501
503
504 {
505
506 llSetStatus( STATUS_PHYSICS, TRUE ); // Resume flight, under pilot control.
507
508 llWhisper( 0, "Flight resumed." );
509
510 }
511
512 else
513
514 {
515
516 if( motor_idle )
517
518 {
519
521
522 llWhisper( 0, "Flight suspended, manually." );
523
524 }
525
526 else
527
528 {
529
530 gLinearMotor = <0,0,0>; // Stop the engine.
531
532 motor_idle = TRUE;
533
534 llWhisper( 0, "Throttle closed." );
535
536 }
537
538 }
539
540 }
541
542 else
543
544 {
545
546 motor_idle = FALSE;
547
548 }
549
550 //
551
552 float power = llSqrt( gLinearMotor * gLinearMotor + 0.1 );
553
554 llSetVehicleFloatParam( VEHICLE_LINEAR_MOTOR_TIMESCALE, LINEAR_MOTOR_TIMESCALE_0 / llSqrt(power) * 3. );
555
556 // 1/strength
557
558 } // End Linear.
559
560 //
561
562 // Angular Controles
563
564 // Changed to impulse angular control, but F. t. C.,
565
566 // for the faster response of a stunt plane.
567
568 //
569
570 if( levels & gAngularControls )
571
572 {
573
574 vector impulse_torque = <0,0,0>;
575
576 //
577
578 // Aileron roll control:
579
580 if( levels & CONTROL_ROT_LEFT )
581
582 {
583
584 if( edges & CONTROL_ROT_RIGHT && buoyancy == 0. )
585
586 impulse_torque.x -= 1.0 * torque_factor;
587
588 //
589
590 steady_torque.x -= 0.7;
591
592 }
593
594 if( levels & CONTROL_ROT_RIGHT )
595
596 {
597
598 if( edges & CONTROL_ROT_RIGHT && buoyancy == 0. )
599
600 impulse_torque.x += 1.0 * torque_factor;
601
602 //
603
604 steady_torque.x += 0.7;
605
606 }
607
608 //
609
610 // Pitch component, elevator ==> causes vehicle lift nose (in local frame):
611
612 if( levels & CONTROL_BACK )
613
614 {
615
616 if( edges & CONTROL_BACK && buoyancy == 0. ) // up
617
618 impulse_torque.y -= 0.7 * torque_factor;
619
620 //
621
622 steady_torque.y -= 0.5;
623
624 }
625
626 if( levels & CONTROL_FWD ) // down
627
628 {
629
630 if( edges & CONTROL_FWD && buoyancy == 0. )
631
632 impulse_torque.y += 0.7 * torque_factor;
633
634 //
635
636 steady_torque.y += 0.5;
637
638 }
639
640 //
641
642 // Rudder control:
643
644 if( levels & CONTROL_RIGHT )
645
646 {
647
648 if( edges & CONTROL_RIGHT && buoyancy == 0. )
649
650 impulse_torque.z -= 0.7 * torque_factor;
651
652 //
653
654 steady_torque.z -= 0.5;
655
656 }
657
658 if( levels & CONTROL_LEFT )
659
660 {
661
662 if( edges & CONTROL_LEFT && buoyancy == 0. )
663
664 impulse_torque.z += 0.7 * torque_factor;
665
666 //
667
668 steady_torque.z += 0.5;
669
670 }
671
672 //if( speed < 1.0 ) { impulse_torque = 5. * impulse_torque; } // Effective turn on ground.
673
674 //
675
676 llApplyRotationalImpulse( impulse_torque, TRUE );
677
678 //
679
680 edges = 0; // We only respond to these once.
681
682 } // End angular contols.
683
684 // End Control.
685
686 //
687
688 //----------------------------------- Routine Flight --------------------------------------------------------------------------
689
690 //-------------------------------------- Refresh motor settings. ------------------------------------------
691
692 //
693
695
696 // This is to defeat VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE.
697
698 //
699
700 //
701
702 local_vel = v / llGetRot(); // global to local coordines
703
704 //llWhisper(0, (string)local_vel );
705
706 //
707
708 //------------------------------------Stear Toward Regeon Center.----------------------------------------------
709
710 //
711
712 if( homing )
713
714 {
715
716 // This is not realistic for a piloted airplane, but it helps avoid sim boundaries.
717
718 // It is more like the Cox control line Little Stinker that flies constrained to a hemeshere.
719
720 //
721
722 vector toCenter = ( < 128, 128, 0 > - pos ); // global vector to center of sim
723
724 // This is the locaiton that it flies around.
725
726 //
727
728 // Roll and yaw to the port of center, moving inward and to starboard when moving away from center.
729
730 // This moves it toward center, when circling right.
731
732 vector h_toCenter = toCenter;
733
734 h_toCenter.z = 0; // No vertical here.
735
736 vector loc_h_toCenter = h_toCenter / llGetRot(); // global to local coordinate transformation;
737
738 vector left = -loc_h_toCenter * (local_vel.x/5.) * 0.00010;
739
740 left.y = 0; // No pitch.
741
742 left.z = -10 * left.x; // Roll component goes to roll and yaw.
743
744 steady_torque += left; // Roll to left of center, to right away.
745
746 //
747
748 // Turn toward center. This tends to move it to center when not circeling.
749
750 vector turn_toCenter = < 1, 0, 0 > % loc_h_toCenter * (local_vel.x/5.) * 0.0004;
751
752 // Forward x [vector cross product] radius = torque toward center. Adjust strength.
753
754 steady_torque += turn_toCenter; // Add to torque.
755
756 }
757
758 //
759
760 //
761
762 //
763
764 //--------------------------- Dynamic Coupling and Trim Tuning -----------------------------------------------
765
766 //
767
768 if( homing )
769
770 {
771
772 // Spiral right to help stay in sim. Physically, this comes from the left hand propeller rotation.
773
774 float right = 0.0; // (English and American propellers usually rotate like a right
775
776 right += -local_vel.z * 0.010; // hand screw, but old German and Swiss engines ran the other way.)
777
778 steady_torque.x += right;
779
780 steady_torque.z -= 2.3 * right;
781
782 }
783
784 //
785
786 // Dihedral: Wing tip on the downward side lifts when moving sideways.
787
788 steady_torque.x += 0.05 * local_vel.y;
789
790 //
791
792 // Wing sweep action: side slip times lift turns roll back up.
793
794 // The down side wing has more lift, but only if it is already lifting.
795
796 steady_torque.x -= 0.04 * ( local_vel.y * local_vel.z );
797
798 //
799
800 //
801
802 // Turn upward: This is the trim incidence of the stabalizer. Global down when up side down.
803
804 if( homing )
805
806 {
807
808 steady_torque.y -= 0.025 * local_vel.x/5. * (1.-buoyancy) * llSqrt(1.-buoyancy);
809
810 }
811
812 //
813
814 // Turn upward: I don't know how to do this in rl with a passive shape. Remains global up when up side down.
815
816 steady_torque.y += 0.004 * local_vel.x/5. * local_vel.z * (1.-buoyancy) * llSqrt(1.-buoyancy);
817
818 //
819
820 // Turn up.
821
822 steady_torque.y += 0.05 * local_vel.z * (1.-buoyancy) * llSqrt(1.-buoyancy);
823
824 //
825
826 //
827
829
830 refreshHUD();
831
832 //
833
834 updating = FALSE;
835
836 @ GOTO;
837
838 } // End Update.----------------------------------------------------------------------------------
839
840 //
841
842 //-----------------------------------------------------------------------------------------------------------------------------------
843
844 //
845
846 refreshHUD()
847
848 {
849
850 if( !sit )
851
852 {
853
854 HUDtext="Take a copy. \n Full permissions.
855
856 New aerodynamic flight script 4.0 .
857
858 Open the airplane as a box to get the documentation.";
859
860 HUDcolor = < 0.2, 0.4, 1. >;
861
862 jump early_exit;
863
864 }
865
866 //
867
868 if( !HUDon )
869
870 {
871
872 llSetText( "", <0,0,0>, 0. );
873
874 jump early_exit;
875
876 }
877
878 //
879
880 float fwd = gLinearMotor.x;
881
882 //
883
884 HUDtext="Airpeed: "+(string)llFloor((local_vel.x+0.5)) + " m/sec. = "+(string)llFloor((local_vel.x*1.94+0.5)) + " kts.
885
886 Throttle: "+(string)llFloor(fwd*100.0/maxThrottle)+"%";
887
888 HUDcolor=<1.0,1.0,1.0>; // white when combat is disabled
889
890 //
891
892 @early_exit;
893
894 //
895
896 llSetText( "", HUDcolor, 1.0);
897
898 //llSetText(HUDtext+"\n \n \n \n \n \n \n ", HUDcolor, 1.0);
899
900 //
901
902 llMessageLinked( 2, 25*(integer)(HUDcolor.x*4.)
903
904 + 5*(integer)(HUDcolor.y*4.)
905
906 + (integer)(HUDcolor.z*4.), "HUDcolor", NULL_KEY );
907
908 llMessageLinked( 2, 137, HUDtext+"\n \n \n \n \n \n \n \n ", NULL_KEY );
909
910 //
911
912 } // End refreshHUD().
913
914 //
915
916 //-----------------------------------------------------------------------------------------------------------------------------------
917
918 default
919
920 {
921
923
924 {
925
926 llSetSitText( "Fly" );
927
928 //llCollisionSound( "", 0.0 );
929
930
931
932
933
934
935
936 // the sit and camera placement is very shape dependent
937
938 // so modify these to suit your vehicle
939
940 llSitTarget( < 0.35, 0.0, 0.33 >, ZERO_ROTATION); // pilot position, relative to root
941
942 //
943
944 llSetCameraEyeOffset( < -11.5, 0.0, 4.5 > ); // location of camera, relative to vehicle
945
946 llSetCameraAtOffset( < 0.0, 0.0, 2.4 > ); // focus point of camera, " "
947
948 //
949
950 //---------------------------------------------------------------------------------------------------------------------------
951
952 //
953
954 llSetVehicleType( VEHICLE_TYPE_AIRPLANE ); // Sets default airplane-like parameters.
955
956
957
958
959
960
961
962 // action of the fin and stabilizer: Points toward velocity.
963
964 // The front turns toward the current velocity.
965
966 llSetVehicleFloatParam( VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 1. ); // "behave much like the deflection time scales"
967
969
970 //
971
972 // Fuselage lift. Wing lift is handled with VEHICLE_LINEAR_FRICTION_TIMESCALE below.
973
974 // The velocity turns toward the front. (Exact formula unknown.)
975
976 llSetVehicleFloatParam( VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 1.0 ); // "behave much like the deflection time scales"
977
979
980 //
981
982 // propeller thrust strength
983
984 // Shorter time scale makes it more stable. Longer makes it more physical (aerodynamic). Too long makes it hard to move.
985
986 llSetVehicleFloatParam( VEHICLE_LINEAR_MOTOR_TIMESCALE, LINEAR_MOTOR_TIMESCALE_0 ); // 1/strength
987
988 // "it cannot be set longer than 120 seconds"
989
990 llSetVehicleFloatParam( VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 5.); // Throttle gradually closes with time but defeated:
991
992 // Refreshed below in timer.
993
994 //
995
996 // control surfaces, ailerons, elevators (and maybe later rudder)
997
998 llSetVehicleFloatParam( VEHICLE_ANGULAR_MOTOR_TIMESCALE, ANGULAR_MOTOR_TIMESCALE_0 ); // 1/strength
999
1000 llSetVehicleFloatParam( VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 5. ); // Control returns to neutral when released.
1001
1002 //
1003
1004 //--------------------- linear friction ------------------------------------------------
1005
1006 // The x component is parasite drag (along with VEHICLE_LINEAR_MOTOR_TIMESCALE).
1007
1008 // The y component contributes to fuselage transverse lift and to drag due to yaw.
1009
1010 // The z component might seem to be just a vertical damping, but when pitch changes by a small amount,
1011
1012 // most of the motion in the direction that was previously forward, becomes motion in the new forward direction,
1013
1014 // with initially only a small transverse (up or down) component. With a short decay time scale
1015
1016 // in the z direction, that component is lost quickly, so the motion continues to follow the pitch angle.
1017
1018 // The larger the z time constant is, the more "induced drag" there is. That is VEHICLE_LINEAR_FRICTION_TIMESCALE.z
1019
1020 // greater than zero causes a drag that increases with lift, similarly to induced drag of a physical airplane.
1021
1022 //
1023
1024 // The z component gives the wing lift. Decreasing it allows the airplane to fly more slowly,
1025
1026 // without loss of speed or altitude. But it seems to be near the limit, to fly much slower one may need buoyancy.
1027
1028 llSetVehicleVectorParam( VEHICLE_LINEAR_FRICTION_TIMESCALE, LINEAR_FRICTION_TIMESCALE_0 );
1029
1030 //
1031
1032 llSetVehicleVectorParam( VEHICLE_ANGULAR_FRICTION_TIMESCALE, < 0.25, 0.5, 0.5 > ); // Along with angular motor time scale,
1033
1034 // This damps the rotational motion.
1035
1036 //
1037
1038 llSetVehicleFloatParam( VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 1000 ); // CG below center of lift, pendulum period.
1039
1040 llSetVehicleFloatParam( VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0 ); // damping, 0–1: 1. is fully damped.
1041
1042 // This needs to be weak for a stunt airplane, that should fly nearly the same upside down as right side up.
1043
1044 // It is desirable especially in free flight models, such as paper gliders. See the dynamic coupling in timer.
1045
1046 //
1047
1048 // This drives yaw in the direction of roll, imitating use of rudder by the pilot.
1049
1050 llSetVehicleFloatParam( VEHICLE_BANKING_EFFICIENCY, 0 ); // Is there a difference between time scale
1051
1052 llSetVehicleFloatParam( VEHICLE_BANKING_TIMESCALE, 1000 ); // and efficiency?
1053
1054 llSetVehicleFloatParam( VEHICLE_BANKING_MIX, 0 ); // more yaw control when moving, 0 = none at rest.
1055
1056 // Since this imitates a manual control, any convenient value set is physical (assuming a rotating tail wheel).
1057
1058 // The Wright brothers found that mechanical coupling of the rudder and ailerons was not sufficient,
1059
1060 // because of the delays involved.
1061
1062 // It is not used here, because it was not intended for attitudes far from right side up.
1063
1064 //
1065
1066 // "hover can be better than sliding along the ground during takeoff and landing
1067
1068 // but it only works over the terrain (not objects)"
1069
1071
1073
1075
1077
1078 //
1079
1080 // "non-zero buoyancy helps the airplane stay up
1081
1082 // set to zero if you don't want this crutch"
1083
1084 // This was useful in the initial stages of tuning. I think it simply reduces the gravitational
1085
1086 // contribution to downward acceleration. Try this to make it easier to fly.
1087
1089
1090 //
1091
1092 // define these here for convenience later
1093
1094 // CUBEY - modified these as per Shadow's prefs
1095
1097
1098 gLinearControls = CONTROL_UP | CONTROL_DOWN; // These control the engine throttle.
1099
1100 //
1101
1102 llSetStatus( STATUS_PHYSICS, FALSE ); //CUBEY - ensure that physics are disabled when plane is rezzed so it doesn't fly off
1103
1104 sit = FALSE; // Keep track of not flying.
1105
1106 //
1107
1108 mass = llGetMass();
1109
1110 mass_factor = (mass/12.5) * llSqrt( llSqrt(mass/12.5) );
1111
1112 //llSay(0, (string)mass+" virtual kilograms." );
1113
1114 llSay(0, "Ready to wash." );
1115
1116 refreshHUD();
1117
1118 //
1119
1120 } // End state_entry()
1121
1122 //-----------------------------------------------------------------------------------------------------------------------------------
1123
1124 //
1125
1126 // DETECT AV SITTING/UNSITTING AND TAKE CONTROLS
1127
1128 //-----------------------------------------------------------------------------------------------------------------------------------
1129
1130 changed(integer change)
1131
1132 {
1133
1134 if( change & CHANGED_LINK )
1135
1136 {
1137
1138 pilot = llAvatarOnSitTarget();
1139
1140 if(pilot)
1141
1142 {
1143
1144 if(pilot != llGetOwner())
1145
1146 //if( FALSE )
1147
1148 {
1149
1150 // only the owner can use this vehicle
1151
1152 llWhisper(0,
1153
1154 "Please take a copy of this airplane and fly your own copy.
1155
1156 (If it is not set \"free to copy\" or \"for sale 0 l$\" contact the owner or the creator.)
1157
1158 You aren't the owner -- only the owner can fly this plane.");
1159
1160 llUnSit(pilot);
1161
1162 //llPushObject(pilot, <0,0,10>, ZERO_VECTOR, FALSE);
1163
1164 }
1165
1166 else
1167
1168 { // Pilot sits on vehicle
1169
1170 // Clear linear motor on successful sit.
1171
1172 //llTriggerSound("cbb7a77f-4302-e3b3-4c1f-6dcb30bf3382",1.0); // engine startup
1173
1174 //sit = TRUE;
1175
1176 //onGround=TRUE;
1177
1178 llMessageLinked(LINK_SET, TRUE, "seated", pilot);
1179
1181
1182 listenHandle = llListen( 0, "", pilot, "" );
1183
1184 }
1185
1186 }
1187
1188 else if( sit )
1189
1190 // When changed is called with flying and CHANGED_LINK, it is usually that the avatar is getting up.
1191
1192 {
1193
1194 // Pilot is getting up.
1195
1196 llWhisper(0, "Ignition off.");
1197
1198 llMessageLinked(LINK_SET, FALSE, "seated", "");
1199
1200 //
1201
1202 // Stop the works.
1203
1204 llSetVehicleFloatParam( VEHICLE_ANGULAR_MOTOR_TIMESCALE, 2. ); // Allow it to rotate when it touches.
1205
1207
1208 llSetVehicleVectorParam( VEHICLE_LINEAR_MOTOR_DIRECTION, <0,0,0> ); // Turn off engine.
1209
1210 llSetVehicleFloatParam( VEHICLE_BUOYANCY, 0.0 ); // Allow it to fall or fly.
1211
1212 //
1213
1214 // Let friction slow the vehicle rather than pinning it in place.
1215
1216 //
1217
1219
1220 llStopAnimation("sit");
1221
1222 //
1223
1224 llSleep( 8. ); // Wait for it to stop.
1225
1226 //
1227
1228 llSetStatus( STATUS_PHYSICS, FALSE ); //Turn off "physics" to make sure the parked plane not be move.
1229
1230 sit = FALSE; // Keep track of whether sitting.
1231
1232 llSetTimerEvent( 0 ); // Stop timer.
1233
1234 llWhisper(0, "Brake set.");
1235
1236 refreshHUD();
1237
1238 //
1239
1240 }
1241
1242 }
1243
1244 } // End changed.
1245
1246 //-------------------------------------------------------------------------------------------------
1247
1249
1250 {
1251
1252 if(perm)
1253
1254 {
1255
1256 llStartAnimation("sit");
1257
1258 llTakeControls( gAngularControls | gLinearControls | CONTROL_LBUTTON, TRUE, FALSE );
1259
1260 gLinearMotor = < 0., 0., 0. >;
1261
1263
1265
1266 llSetStatus( STATUS_PHYSICS, TRUE ); //CUBEY - enable physics when avatar sits
1267
1268 sit = TRUE; // Keep track of whether flying or not.
1269
1270 //
1271
1272 llSetTimerEvent( 0.25 ); // seconds This is to refresh forces and torques that have decayed.
1273
1274 // Also dynamic coupling, etc.
1275
1276 last_time = llGetTimeOfDay(); // Here the script starts do it own "real" time. Initially only to tell when
1277
1278 // things are so bad we'd better pause the animation.
1279
1280 kownt_3 = 0;
1281
1282 llWhisper(0, "
1283
1284 Engine started.
1285
1286
1287
1288 Arrow keys -- up, down, roll right, left.
1289
1290 Shift with arrow keys works the rudder.
1291
1292 Flight modes are \"t\", \"n\" and \"e\".
1293
1294 \"s\" to toggle stear to stay in sim.");
1295
1296 //
1297
1298 //
1299
1300 }
1301
1302 }
1303
1304 //FLIGHT CONTROLS
1305
1306 //-----------------------------------------------------------------------------------------------------------------------------------
1307
1308 control( key id, integer control_levels, integer control_edges )
1309
1310 {
1311
1312 edges = control_edges;
1313
1314 levels = control_levels;
1315
1316 //
1317
1318 Update(); // Do everything.
1319
1320 //
1321
1322 kownt_3 = 0; // time since last control entry
1323
1324 } // End control.
1325
1326 // (The controls really aught to reverse when going backwards,
1327
1328 // but it seems convienient to be able to turn on the ground.)
1329
1330 //===============================================================================================================================
1331
1332 //
1333
1334 //
1335
1336 listen( integer channel, string name, key id, string message )
1337
1338 {
1339
1340 //
1341
1342 if( message == "hud on" || message == "HUD ON" ) // expert mode
1343
1344 {
1345
1346 HUDon = TRUE;
1347
1348 refreshHUD();
1349
1350 }
1351
1352 //
1353
1354 if( message == "hud off" || message == "HUD OFF" ) // expert mode
1355
1356 {
1357
1358 HUDon = FALSE;
1359
1360 refreshHUD();
1361
1362 }
1363
1364 //---------------------------------------------------------------------------------------------------------------------------
1365
1366 //
1367
1368 if( message == "e" || message == "E" ) // expert mode
1369
1370 {
1371
1372 buoyancy = 0.;
1373
1374 llWhisper(0, "Expert mode set." );
1375
1376 }
1377
1378 else if( message == "n" || message == "N" ) // normal mode
1379
1380 {
1381
1382 buoyancy = 0.4;
1383
1384 llWhisper(0, "Normal mode set." );
1385
1386 }
1387
1388 else if( message == "t" || message == "T" ) // touring mode
1389
1390 {
1391
1392 buoyancy = 0.6;
1393
1394 homing = FALSE;
1395
1396 llWhisper(0, "Touring mode set." );
1397
1398 }
1399
1400 else if( message == "s" || message == "S" ) // Stay on sim on, off.
1401
1402 {
1403
1404 if( homing )
1405
1406 {
1407
1408 homing = FALSE;
1409
1410 llWhisper(0, "Stear around sim center off." );
1411
1412 }
1413
1414 else
1415
1416 {
1417
1418 homing = TRUE;
1419
1420 llWhisper(0, "Stear around sim center on." );
1421
1422 }
1423
1424 }
1425
1426 //
1427
1428 //
1429
1430 Update(); // Periodic tasks
1431
1432 } // End listen.
1433
1434 //
1435
1436 //===============================================================================================================================
1437
1438 timer() // Added by F. t. C.
1439
1440 {
1441
1442 Update(); // Periodic tasks
1443
1444 //
1445
1446 // If timer is running but there has been no control recently, then the airplane must be lost,
1447
1448 // unless the auto-pilot is on.
1449
1450 if( kownt_3 == 2*60*4 && !homing )
1451
1452 {
1453
1455
1456 kownt_3 = -2*60*60*4; // how long till next IM
1457
1458 }
1459
1460 //llOwnerSay( (string)kownt_3 );
1461
1462 kownt_3 += 1; // time since last control entry
1463
1464 //
1465
1466 }// End timer.
1467
1468 //
1469
1470 //===============================================================================================================================
1471
1472 touch_start(integer total_number)
1473
1474 {
1475
1476 if( sit )
1477
1478 {
1479
1481
1482 {
1483
1484 llSetStatus( STATUS_PHYSICS, TRUE ); // Resume flight, under pilot control.
1485
1486 llWhisper( 0, "Flight resumed." );
1487
1488 }
1489
1490 else
1491
1492 {
1493
1494 if( motor_idle )
1495
1496 {
1497
1499
1500 llWhisper( 0, "Flight suspended, manually." );
1501
1502 }
1503
1504 else
1505
1506 {
1507
1508 gLinearMotor = <0,0,0>; // Stop the engine.
1509
1510 motor_idle = TRUE;
1511
1512 llWhisper( 0, "Throttle closed." );
1513
1514 }
1515
1516 }
1517
1518 }
1519
1520 //
1521
1522 Update(); //-------- Handle Exceptions, Environment----------------------------------------------
1523
1524 }
1525
1526 } // End default.
1527
1528 //
1529
1530 // (The controls really aught to reverse when going backwards,
1531
1532 // but it seems convienient to be able to turn on the ground.)

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