1 /*****************************************************************************
2 * $LastChangedDate: 2010-06-24 10:22:48 -0400 (Thu, 24 Jun 2010) $
3 * @file
4 * @author Jim E. Brooks http://www.palomino3d.org
5 * @brief Aircraft classes.
6 *//*
7 * LEGAL: COPYRIGHT (C) 2007 JIM E. BROOKS
8 * THIS SOURCE CODE IS RELEASED UNDER THE TERMS
9 * OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
10 *****************************************************************************/
11
12 // Enable this when editing an aircraft model's control surfaces.
13 // This causes the spec file to be reloaded continually after being edited.
14 #if DEBUG
15 //#define COMPILE_EDITING_MODEL 1
16 #endif
17
18 #define PROGRAM_AIRCRAFT_CC 1
19 #include "base/module.hh"
20 using namespace base;
21 #include "math/module.hh"
22 #include "math/funcs_trig.hh"
23 #include "math/funcs_vector.hh"
24 using namespace math;
25 #include "gfx/module.hh"
26 using namespace gfx;
27 #include "graph/module.hh"
28 #include "graph/subgraph.hh"
29 #include "graph/shadow_scene_graph.hh"
30 using namespace graph;
31 #include "object/module.hh"
32 #include "object/aircraft.hh"
33 using namespace object;
34 #include "control/module.hh"
35 #include "control/defs_axis.hh"
36 using namespace control;
37 #include "physics/module.hh"
38 using namespace physics;
39 #include "program/module.hh"
40 #include "program/aircraft_models.hh"
41
42 namespace program {
43
44 INTERN const fp THROTTLE_PROPELLER = 0.2f; // when propeller begins to spin
45 INTERN const fp THROTTLE_FLAME_LOW = 0.3f; // most models lack this
46 INTERN const fp THROTTLE_FLAME_HIGH = 0.7f;
47 INTERN const fp THROTTLE_FLAME = THROTTLE_FLAME_HIGH;
48 INTERN const fp F14_AILERONS_ACTIVE_SWING_WINGS = 0.75f;
49
50 ////////////////////////////////////////////////////////////////////////////////
51 /////////////////////////////// functions ////////////////////////////////////
52 ////////////////////////////////////////////////////////////////////////////////
53
54 #if COMPILE_EDITING_MODEL
55 #define CODE_CLASS_GET_SPECS( CONF_FILENAME ) \
56 { \
57 BEGIN_ONCE { \
58 CDEBUG << "Note: COMPILE_EDITING_MODEL enabled (slows program)" << endl;\
59 } END_ONCE \
60 \
61 /* Reload every time. */ \
62 PERSISTENT AircraftSpecs sAircraftSpecs; \
63 sAircraftSpecs.ReadSpecsFromConfFile( CONF_FILENAME ); \
64 return sAircraftSpecs; \
65 }
66 #else
67 #define CODE_CLASS_GET_SPECS( CONF_FILENAME ) \
68 { \
69 /* Load specs from a .conf file once. */ \
70 PERSISTENT AircraftSpecs sAircraftSpecs; \
71 BEGIN_ONCE { \
72 sAircraftSpecs.ReadSpecsFromConfFile( CONF_FILENAME ); \
73 } END_ONCE \
74 return sAircraftSpecs; \
75 }
76 #endif
77
78 /*****************************************************************************
79 * Make specified kind of aircraft.
80 * Some 3D models were defined with its center at the nose.
81 * physics_*.conf redefines an offset.
82 * @param aircraftType
83 * @param pos
84 * @param loadCopy
85 * Pass ModelCache::LOAD_SHARED or LOAD_COPY.
86 * To save memory, pass false for dummy (non-dynamic) aircraft
87 * such as those parked on the carrier.
88 *****************************************************************************/
89 shptr<Aircraft>
MakeAircraft(eAircraftType aircraftType,const WorldVertex & pos,const bool loadCopy)90 MakeAircraft( eAircraftType aircraftType, const WorldVertex& pos, const bool loadCopy )
91 {
92 shptr0<Aircraft> aircraft = NULL;
93 shptr0<Graph> graph = NULL;
94
95 #define MAKE_AIRCRAFT( CLASS ) \
96 { \
97 graph = Aircraft::LoadModel( CLASS::ClassGetSpecs(), loadCopy ).PTR(); \
98 aircraft = new CLASS( graph.PTR(), pos ); \
99 }
100
101 switch ( aircraftType )
102 {
103 case eAircraftType_Spitfire:
104 {
105 MAKE_AIRCRAFT( SpitfireAircraft );
106 }
107 break;
108
109 case eAircraftType_Corsair:
110 {
111 MAKE_AIRCRAFT( CorsairAircraft );
112 }
113 break;
114
115 case eAircraftType_P51:
116 {
117 MAKE_AIRCRAFT( P51Aircraft );
118 }
119 break;
120
121 case eAircraftType_F82:
122 {
123 MAKE_AIRCRAFT( F82Aircraft );
124 }
125 break;
126
127 case eAircraftType_F86:
128 {
129 MAKE_AIRCRAFT( F86Aircraft );
130 }
131 break;
132
133 case eAircraftType_A4:
134 {
135 MAKE_AIRCRAFT( A4Aircraft );
136 }
137 break;
138
139 case eAircraftType_F14:
140 {
141 MAKE_AIRCRAFT( F14Aircraft );
142 }
143 break;
144
145 case eAircraftType_F15:
146 {
147 MAKE_AIRCRAFT( F15Aircraft );
148 }
149 break;
150
151 case eAircraftType_F16:
152 {
153 MAKE_AIRCRAFT( F16Aircraft );
154 }
155 break;
156
157 case eAircraftType_F18:
158 {
159 MAKE_AIRCRAFT( F18Aircraft );
160 }
161 break;
162
163 case eAircraftType_SR71:
164 {
165 MAKE_AIRCRAFT( SR71Aircraft );
166 }
167 break;
168
169 case eAircraftType_Mirage2000:
170 {
171 MAKE_AIRCRAFT( Mirage2000Aircraft );
172 }
173 break;
174
175 case eAircraftType_SU37:
176 {
177 MAKE_AIRCRAFT( SU37Aircraft );
178 }
179 break;
180
181 case eAircraftType_Sikorsky:
182 {
183 MAKE_AIRCRAFT( SikorskyAircraft );
184 }
185 break;
186
187 case eAircraftType_SpaceShuttle:
188 {
189 MAKE_AIRCRAFT( SpaceShuttleAircraft );
190 }
191 break;
192
193 default:
194 {
195 ASSERT(0); // oops
196 }
197 break;
198 }
199
200 // Return Aircraft.
201 return aircraft.PTR();
202 }
203
204 ////////////////////////////////////////////////////////////////////////////////
205 //////////////////////////// SpitfireAircraft ////////////////////////////////
206 ////////////////////////////////////////////////////////////////////////////////
207
208 /*****************************************************************************
209 * ctor/dtor.
210 *****************************************************************************/
SpitfireAircraft(shptr<Graph> graph,const WorldVertex & pos)211 SpitfireAircraft::SpitfireAircraft( shptr<Graph> graph, const WorldVertex& pos )
212 : Parent(graph,pos,SpitfireAircraft::ClassGetSpecs()),
213 mSubgraphPropeller1(new Subgraph(graph,"Propeller1")),
214 mSubgraphPropeller2(new Subgraph(graph,"Propeller2")),
215 mSubgraphPropeller3(new Subgraph(graph,"Propeller3")),
216 mSubgraphPropeller4(new Subgraph(graph,"Propeller4")),
217 mSubgraphPropellerDisc(new Subgraph(graph,"noshadow.PropellerDisk")), // transparent
218 mSubgraphGear0(new Subgraph(graph,"Leg-Assembly-L")),
219 mSubgraphGear1(new Subgraph(graph,"Leg-Assembly-R")),
220 mSubgraphGear2(new Subgraph(graph,"Tail-Wheel-Assembly")),
221 //
222 mSubgraphAileronLeft(new Subgraph(graph,"Aileron-T")),
223 mSubgraphAileronRight(new Subgraph(graph,"Aileron-T.001")),
224 mSubgraphElevatorLeft(new Subgraph(graph,"Elevator-T.001")),
225 mSubgraphElevatorRight(new Subgraph(graph,"Elevator-T")),
226 mSubgraphRudder(new Subgraph(graph,"Rudder"))
227 {
228 ShadowSceneGraph::DisableShadows( mSubgraphPropellerDisc->GetRootNode() );
229 }
230
~SpitfireAircraft()231 SpitfireAircraft::~SpitfireAircraft()
232 {
233 // NOP
234 }
235
236 /*****************************************************************************
237 * @return Aircraft specifications struct.
238 *****************************************************************************/
239 const AircraftSpecs&
GetSpecs(void)240 SpitfireAircraft::GetSpecs( void ) // virtual method
241 {
242 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
243
244 return SpitfireAircraft::ClassGetSpecs();
245 }
246
247 const AircraftSpecs&
ClassGetSpecs(void)248 SpitfireAircraft::ClassGetSpecs( void ) // class method
249 {
250 CODE_CLASS_GET_SPECS( "physics_spitfire.conf" )
251 }
252
253 /*****************************************************************************
254 * Tick that pulses animation.
255 *****************************************************************************/
256 void
Tick(const Milliseconds millisecElapsed)257 SpitfireAircraft::Tick( const Milliseconds millisecElapsed )
258 {
259 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
260
261 Parent::Tick( millisecElapsed );
262
263 RotatePropeller();
264 }
265
266 /*****************************************************************************
267 * Rotate propeller.
268 *****************************************************************************/
269 // Rotate both propeller Groups.
270 void
RotatePropeller(void)271 SpitfireAircraft::RotatePropeller( void )
272 {
273 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
274
275 // Degree of rotation correlates to throttle.
276 const Degree degree = 35.0f * GetThrottle();
277 const Radian radian = Deg2Rad( -degree );
278 mSubgraphPropeller1->Rotate( XX, radian );
279 mSubgraphPropeller2->Rotate( XX, radian );
280 mSubgraphPropeller3->Rotate( XX, radian );
281 mSubgraphPropeller4->Rotate( XX, radian );
282 }
283
284 /*****************************************************************************
285 * Retract/extend landing gear.
286 *****************************************************************************/
287 void
SetLandingGear(const bool down)288 SpitfireAircraft::SetLandingGear( const bool down )
289 {
290 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
291
292 if ( IfCanSetLandingGear( down ) )
293 {
294 Parent::SetLandingGear( down );
295
296 mSubgraphGear0->Enable( down );
297 mSubgraphGear1->Enable( down );
298 mSubgraphGear2->Enable( down );
299 }
300 }
301
302 /*****************************************************************************
303 * When throttle is increased, spin propeller.
304 *****************************************************************************/
305 void
SetThrottle(const fp throttle)306 SpitfireAircraft::SetThrottle( const fp throttle )
307 {
308 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
309
310 Parent::SetThrottle( throttle );
311 mSubgraphPropellerDisc->Enable( throttle >= THROTTLE_PROPELLER ); // disable transparent disc
312 }
313
314 /*****************************************************************************
315 * Rotate control surfaces (ailerons etc).
316 *****************************************************************************/
317 void
RotateControlSurfaces(const uint axis,const fp controlFraction)318 SpitfireAircraft::RotateControlSurfaces( const uint axis, const fp controlFraction )
319 {
320 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
321 ASSERT_AXIS3(axis);
322
323 switch ( axis )
324 {
325 case AXIS_PITCH:
326 {
327 RotateElevator( *mSubgraphElevatorLeft, controlFraction );
328 RotateElevator( *mSubgraphElevatorRight, controlFraction );
329 }
330 break;
331
332 case AXIS_ROLL:
333 {
334 RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON );
335 RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON );
336 }
337 break;
338
339 case AXIS_YAW:
340 {
341 RotateRudder( *mSubgraphRudder, controlFraction );
342 }
343 break;
344 }
345 }
346
347 ////////////////////////////////////////////////////////////////////////////////
348 ///////////////////////////// CorsairAircraft ////////////////////////////////
349 ////////////////////////////////////////////////////////////////////////////////
350
351 /*****************************************************************************
352 * ctor/dtor.
353 *****************************************************************************/
CorsairAircraft(shptr<Graph> graph,const WorldVertex & pos)354 CorsairAircraft::CorsairAircraft( shptr<Graph> graph, const WorldVertex& pos )
355 : Parent(graph,pos,CorsairAircraft::ClassGetSpecs()),
356 mSubgraphPropeller0(new Subgraph(graph,"prop_0")),
357 mSubgraphPropeller1(new Subgraph(graph,"prop_1")),
358 mSubgraphGear0(new Subgraph(graph,"gearp2.L")),
359 mSubgraphGear1(new Subgraph(graph,"gearp2.R")),
360 mSubgraphGear2(new Subgraph(graph,"gearp3.L")),
361 mSubgraphGear3(new Subgraph(graph,"gearp3.R")),
362 mSubgraphGear4(new Subgraph(graph,"gearcylinder.L")),
363 mSubgraphGear5(new Subgraph(graph,"gearcylinder.R")),
364 mSubgraphGear6(new Subgraph(graph,"gearleg.L")),
365 mSubgraphGear7(new Subgraph(graph,"gearleg.R")),
366 mSubgraphGear8(new Subgraph(graph,"gearleg2.L")),
367 mSubgraphGear9(new Subgraph(graph,"gearleg2.R")),
368 mSubgraphGear10(new Subgraph(graph,"gearp1.L")),
369 mSubgraphGear11(new Subgraph(graph,"gearp1.R")),
370 mSubgraphGear12(new Subgraph(graph,"gearsc1.L")),
371 mSubgraphGear13(new Subgraph(graph,"gearsc2.L")),
372 mSubgraphGear14(new Subgraph(graph,"tailgear1")),
373 mSubgraphGear15(new Subgraph(graph,"tailgear2")),
374 mSubgraphGear16(new Subgraph(graph,"stopwheel.L")),
375 mSubgraphGear17(new Subgraph(graph,"stopwheel.R")),
376 mSubgraphGear18(new Subgraph(graph,"wheel.L")),
377 mSubgraphGear19(new Subgraph(graph,"wheel.R")),
378 mSubgraphGear20(new Subgraph(graph,"tailwheel")),
379 // Control surfaces:
380 mSubgraphAileronLeft(new Subgraph(graph,"aileron.L")),
381 mSubgraphAileronRight(new Subgraph(graph,"aileron.R")),
382 mSubgraphElevatorLeft(new Subgraph(graph,"elevator.L")),
383 mSubgraphElevatorRight(new Subgraph(graph,"elevator.R")),
384 mSubgraphRudder(new Subgraph(graph,"rudder"))
385 {
386 // NOP
387 }
388
~CorsairAircraft()389 CorsairAircraft::~CorsairAircraft()
390 {
391 // NOP
392 }
393
394 /*****************************************************************************
395 * @return Aircraft specifications struct.
396 *****************************************************************************/
397 const AircraftSpecs&
GetSpecs(void)398 CorsairAircraft::GetSpecs( void ) // virtual method
399 {
400 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
401 return CorsairAircraft::ClassGetSpecs();
402 }
403
404 const AircraftSpecs&
ClassGetSpecs(void)405 CorsairAircraft::ClassGetSpecs( void ) // class method
406 {
407 CODE_CLASS_GET_SPECS( "physics_corsair.conf" )
408 }
409
410 /*****************************************************************************
411 * Tick that pulses animation.
412 *****************************************************************************/
413 void
Tick(const Milliseconds millisecElapsed)414 CorsairAircraft::Tick( const Milliseconds millisecElapsed )
415 {
416 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
417
418 Parent::Tick( millisecElapsed );
419
420 RotatePropeller();
421 }
422
423 /*****************************************************************************
424 * Rotate propeller.
425 *****************************************************************************/
426 void
RotatePropeller(void)427 CorsairAircraft::RotatePropeller( void )
428 {
429 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
430
431 // Degree of rotation correlates to throttle.
432 const Degree degree = 35.0f * GetThrottle();
433 const Radian radian = Deg2Rad( -degree );
434 mSubgraphPropeller0->Rotate( XX, radian );
435 mSubgraphPropeller1->Rotate( XX, radian );
436 }
437
438 /*****************************************************************************
439 * Retract/extend landing gear.
440 *****************************************************************************/
441 void
SetLandingGear(const bool down)442 CorsairAircraft::SetLandingGear( const bool down )
443 {
444 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
445
446 if ( IfCanSetLandingGear( down ) )
447 {
448 Parent::SetLandingGear( down );
449
450 mSubgraphGear0->Enable( down ); mSubgraphGear1->Enable( down );
451 mSubgraphGear2->Enable( down ); mSubgraphGear3->Enable( down );
452 mSubgraphGear4->Enable( down ); mSubgraphGear5->Enable( down );
453 mSubgraphGear6->Enable( down ); mSubgraphGear7->Enable( down );
454 mSubgraphGear8->Enable( down ); mSubgraphGear9->Enable( down );
455 mSubgraphGear10->Enable( down ); mSubgraphGear11->Enable( down );
456 mSubgraphGear12->Enable( down ); mSubgraphGear13->Enable( down );
457 mSubgraphGear14->Enable( down ); mSubgraphGear15->Enable( down );
458 mSubgraphGear16->Enable( down ); mSubgraphGear17->Enable( down );
459 mSubgraphGear18->Enable( down ); mSubgraphGear19->Enable( down );
460 mSubgraphGear20->Enable( down );
461 }
462 }
463
464 /*****************************************************************************
465 * Rotate control surfaces (ailerons etc).
466 *****************************************************************************/
467 void
RotateControlSurfaces(const uint axis,const fp controlFraction)468 CorsairAircraft::RotateControlSurfaces( const uint axis, const fp controlFraction )
469 {
470 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
471 ASSERT_AXIS3(axis);
472
473 switch ( axis )
474 {
475 case AXIS_PITCH:
476 {
477 RotateElevator( *mSubgraphElevatorLeft, controlFraction );
478 RotateElevator( *mSubgraphElevatorRight, controlFraction );
479 }
480 break;
481
482 case AXIS_ROLL:
483 {
484 RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON );
485 RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON );
486 }
487 break;
488
489 case AXIS_YAW:
490 {
491 RotateRudder( *mSubgraphRudder, controlFraction );
492 }
493 break;
494 }
495 }
496
497 ////////////////////////////////////////////////////////////////////////////////
498 /////////////////////////////// P51Aircraft //////////////////////////////////
499 ////////////////////////////////////////////////////////////////////////////////
500
501 /*****************************************************************************
502 * ctor/dtor.
503 *****************************************************************************/
P51Aircraft(shptr<Graph> graph,const WorldVertex & pos)504 P51Aircraft::P51Aircraft( shptr<Graph> graph, const WorldVertex& pos )
505 : Parent(graph,pos,P51Aircraft::ClassGetSpecs()),
506 mSubgraphPropeller1(new Subgraph(graph,"Propeller1")),
507 mSubgraphPropeller2(new Subgraph(graph,"Propeller2")),
508 //
509 mSubgraphLeftGearWheel(new Subgraph(graph,"LeftGearWheel")),
510 mSubgraphLeftGearStrut(new Subgraph(graph,"LeftGearStrut")),
511 mSubgraphLeftInnerGearCover(new Subgraph(graph,"LeftInnerGearCover")),
512 mSubgraphLeftOuterGearCover(new Subgraph(graph,"LeftOuterGearCover")),
513 mSubgraphLeftTailGearDoor(new Subgraph(graph,"LeftTailGearDoor")),
514 //
515 mSubgraphRightGearWheel(new Subgraph(graph,"RightGearWheel")),
516 mSubgraphRightGearStrut(new Subgraph(graph,"RightGearStrut")),
517 mSubgraphRightInnerGearCover(new Subgraph(graph,"RightInnerGearCover")),
518 mSubgraphRightOuterGearCover(new Subgraph(graph,"RightOuterGearCover")),
519 mSubgraphRightTailGearDoor(new Subgraph(graph,"RightTailGearDoor")),
520 //
521 mSubgraphTailGearWheel(new Subgraph(graph,"TailGearWheel")),
522 mSubgraphTailGearStrut(new Subgraph(graph,"TailGearStrut")),
523 //
524 mSubgraphAileronLeft(new Subgraph(graph,"LeftAileron")),
525 mSubgraphAileronRight(new Subgraph(graph,"RightAileron")),
526 mSubgraphElevatorLeft(new Subgraph(graph,"LeftElevator")),
527 mSubgraphElevatorRight(new Subgraph(graph,"RightElevator")),
528 mSubgraphRudder(new Subgraph(graph,"Rudder")),
529 //
530 mSubgraphJunk0(new Subgraph(graph,"TailNavLightOff")),
531 mSubgraphJunk1(new Subgraph(graph,"TailNavLightOn"))
532 {
533 // Disable junk parts.
534 mSubgraphJunk0->Enable( false );
535 mSubgraphJunk1->Enable( false );
536 }
537
~P51Aircraft()538 P51Aircraft::~P51Aircraft()
539 {
540 // NOP
541 }
542
543 /*****************************************************************************
544 * @return Aircraft specifications struct.
545 *****************************************************************************/
546 const AircraftSpecs&
GetSpecs(void)547 P51Aircraft::GetSpecs( void ) // virtual method
548 {
549 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
550 return P51Aircraft::ClassGetSpecs();
551 }
552
553 const AircraftSpecs&
ClassGetSpecs(void)554 P51Aircraft::ClassGetSpecs( void ) // class method
555 {
556 CODE_CLASS_GET_SPECS( "physics_p51.conf" )
557 }
558
559 /*****************************************************************************
560 * Tick that pulses animation.
561 *****************************************************************************/
562 void
Tick(const Milliseconds millisecElapsed)563 P51Aircraft::Tick( const Milliseconds millisecElapsed )
564 {
565 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
566
567 Parent::Tick( millisecElapsed );
568
569 RotatePropeller();
570 }
571
572 /*****************************************************************************
573 * Rotate propeller.
574 *****************************************************************************/
575 void
RotatePropeller(void)576 P51Aircraft::RotatePropeller( void )
577 {
578 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
579
580 // Rotate both propeller Groups.
581 // Degree of rotation correlates to throttle.
582 const Degree degree = 35.0f * GetThrottle();
583 const Radian radian = Deg2Rad( -degree );
584 mSubgraphPropeller1->Rotate( XX, radian ); // this p51d-jw model splits propeller
585 mSubgraphPropeller2->Rotate( XX, radian ); // into two subgraphs
586 }
587
588 /*****************************************************************************
589 * Retract/extend landing gear.
590 *****************************************************************************/
591 void
SetLandingGear(const bool down)592 P51Aircraft::SetLandingGear( const bool down )
593 {
594 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
595
596 // The p51d-nw model apparently defines the origin of the landing gear
597 // at the center of the fuselage instead of the strut pivot.
598 // For now, just disable the nodes instead of doing rotation.
599
600 if ( IfCanSetLandingGear( down ) )
601 {
602 Parent::SetLandingGear( down );
603
604 mSubgraphLeftGearWheel->Enable( down );
605 mSubgraphLeftGearStrut->Enable( down );
606 mSubgraphLeftInnerGearCover->Enable( down );
607 mSubgraphLeftOuterGearCover->Enable( down );
608 mSubgraphLeftTailGearDoor->Enable( down );
609
610 mSubgraphRightGearWheel->Enable( down );
611 mSubgraphRightGearStrut->Enable( down );
612 mSubgraphRightInnerGearCover->Enable( down );
613 mSubgraphRightOuterGearCover->Enable( down );
614 mSubgraphRightTailGearDoor->Enable( down );
615
616 mSubgraphTailGearWheel->Enable( down );
617 mSubgraphTailGearStrut->Enable( down );
618 }
619 }
620
621 /*****************************************************************************
622 * Rotate control surfaces (ailerons etc).
623 *****************************************************************************/
624 void
RotateControlSurfaces(const uint axis,const fp controlFraction)625 P51Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction )
626 {
627 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
628 ASSERT_AXIS3(axis);
629
630 switch ( axis )
631 {
632 case AXIS_PITCH:
633 {
634 RotateElevator( *mSubgraphElevatorLeft, controlFraction );
635 RotateElevator( *mSubgraphElevatorRight, controlFraction );
636 }
637 break;
638
639 case AXIS_ROLL:
640 {
641 RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON );
642 RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON );
643 }
644 break;
645
646 case AXIS_YAW:
647 {
648 RotateRudder( *mSubgraphRudder, controlFraction );
649 }
650 break;
651 }
652 }
653
654 ////////////////////////////////////////////////////////////////////////////////
655 /////////////////////////////// F82Aircraft //////////////////////////////////
656 ////////////////////////////////////////////////////////////////////////////////
657
658 /*****************************************************************************
659 * ctor/dtor.
660 *****************************************************************************/
F82Aircraft(shptr<Graph> graph,const WorldVertex & pos)661 F82Aircraft::F82Aircraft( shptr<Graph> graph, const WorldVertex& pos )
662 : Parent(graph,pos,F82Aircraft::ClassGetSpecs()),
663 mSubgraphPropeller1(new Subgraph(graph,"Propeller1")),
664 mSubgraphPropeller2(new Subgraph(graph,"Propeller2")),
665 mSubgraphPropeller3(new Subgraph(graph,"Propeller1.002")),
666 mSubgraphPropeller4(new Subgraph(graph,"Propeller2.001")),
667 //
668 mSubgraphLeftGearWheel(new Subgraph(graph,"LeftGearWheel")),
669 mSubgraphLeftGearStrut(new Subgraph(graph,"LeftGearStrut")),
670 mSubgraphLeftInnerGearCover(new Subgraph(graph,"LeftInnerGearCover")),
671 mSubgraphLeftInnerGearCover2(new Subgraph(graph,"LeftInnerGearCove")), // sic/truncation
672 mSubgraphLeftOuterGearCover(new Subgraph(graph,"LeftOuterGearCover")),
673 mSubgraphLeftTailGearDoor(new Subgraph(graph,"LeftTailGearDoor")),
674 //
675 mSubgraphRightGearWheel(new Subgraph(graph,"RightGearWheel")),
676 mSubgraphRightGearStrut(new Subgraph(graph,"RightGearStrut")),
677 mSubgraphRightInnerGearCover(new Subgraph(graph,"RightInnerGearCover")),
678 mSubgraphRightInnerGearCover2(new Subgraph(graph,"RightInnerGearCov")), // sic/truncation
679 mSubgraphRightOuterGearCover(new Subgraph(graph,"RightOuterGearCover")),
680 mSubgraphRightTailGearDoor(new Subgraph(graph,"RightTailGearDoor")),
681 //
682 mSubgraphTailGearWheel(new Subgraph(graph,"TailGearWheel")),
683 mSubgraphTailGearStrut(new Subgraph(graph,"TailGearStrut")),
684 mSubgraphTailGearWheel2(new Subgraph(graph,"TailGearWheel.001")),
685 mSubgraphTailGearStrut2(new Subgraph(graph,"TailGearStrut.001")),
686 //
687 mSubgraphAileronLeft(new Subgraph(graph,"LeftAileron")),
688 mSubgraphAileronRight(new Subgraph(graph,"RightAileron")),
689 mSubgraphElevator(new Subgraph(graph,"LeftElevator.001")), // misnomer
690 mSubgraphRudderLeft(new Subgraph(graph,"Rudder")),
691 mSubgraphRudderRight(new Subgraph(graph,"Rudder.001")),
692 //
693 mSubgraphJunk0(new Subgraph(graph,"TailNavLightOff")),
694 mSubgraphJunk1(new Subgraph(graph,"TailNavLightOn"))
695 {
696 // Disable junk parts.
697 mSubgraphJunk0->Enable( false );
698 mSubgraphJunk1->Enable( false );
699 }
700
~F82Aircraft()701 F82Aircraft::~F82Aircraft()
702 {
703 // NOP
704 }
705
706 /*****************************************************************************
707 * @return Aircraft specifications struct.
708 *****************************************************************************/
709 const AircraftSpecs&
GetSpecs(void)710 F82Aircraft::GetSpecs( void ) // virtual method
711 {
712 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
713 return F82Aircraft::ClassGetSpecs();
714 }
715
716 const AircraftSpecs&
ClassGetSpecs(void)717 F82Aircraft::ClassGetSpecs( void ) // class method
718 {
719 CODE_CLASS_GET_SPECS( "physics_f82.conf" )
720 }
721
722 /*****************************************************************************
723 * Tick that pulses animation.
724 *****************************************************************************/
725 void
Tick(const Milliseconds millisecElapsed)726 F82Aircraft::Tick( const Milliseconds millisecElapsed )
727 {
728 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
729
730 Parent::Tick( millisecElapsed );
731
732 RotatePropeller();
733 }
734
735 /*****************************************************************************
736 * Rotate propeller.
737 *****************************************************************************/
738 void
TranslatePropeller(const fp dir)739 F82Aircraft::TranslatePropeller( const fp dir )
740 {
741 // In the F-82 model, the origin of the two propellers aren't centered correctly.
742 // This C++ code temporarily shifts the matrix origin.
743 //
744 // Using constants for translation is ok as they are scaled
745 // by the matrix scale set in the Object's Graph.
746
747 const uint outwardAxis = ZZ;
748 const fp outwardTrans = dir * 1.875f; // constant ok
749 mSubgraphPropeller1->Translate( outwardAxis, outwardTrans );
750 mSubgraphPropeller2->Translate( outwardAxis, outwardTrans );
751 mSubgraphPropeller3->Translate( outwardAxis, -outwardTrans );
752 mSubgraphPropeller4->Translate( outwardAxis, -outwardTrans );
753
754 const uint upwardAxis = YY;
755 const fp upwardTrans = dir * 0.1f; // constant ok
756 mSubgraphPropeller1->Translate( upwardAxis, upwardTrans );
757 mSubgraphPropeller2->Translate( upwardAxis, upwardTrans );
758 mSubgraphPropeller3->Translate( upwardAxis, upwardTrans );
759 mSubgraphPropeller4->Translate( upwardAxis, upwardTrans );
760 }
761
762 void
RotatePropeller(void)763 F82Aircraft::RotatePropeller( void )
764 {
765 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
766
767 // Rotate both propeller Groups.
768 // Degree of rotation correlates to throttle.
769 const Degree degree = 35.0f * GetThrottle();
770 const Radian radian = Deg2Rad( -degree );
771
772 TranslatePropeller( 1.0f );
773
774 mSubgraphPropeller1->Rotate( XX, radian ); // the p51d-jw model splits propeller
775 mSubgraphPropeller2->Rotate( XX, radian ); // into 2 subgraphs so the F-82 model has 4
776 mSubgraphPropeller3->Rotate( XX, radian );
777 mSubgraphPropeller4->Rotate( XX, radian );
778
779 TranslatePropeller( -1.0f ); // undo translation
780 }
781
782 /*****************************************************************************
783 * Retract/extend landing gear.
784 *****************************************************************************/
785 void
SetLandingGear(const bool down)786 F82Aircraft::SetLandingGear( const bool down )
787 {
788 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
789
790 // The model apparently defines the origin of the landing gear
791 // at the center of the fuselage instead of the strut pivot.
792 // For now, just disable the nodes instead of doing rotation.
793
794 if ( IfCanSetLandingGear( down ) )
795 {
796 Parent::SetLandingGear( down );
797
798 mSubgraphLeftGearWheel->Enable( down );
799 mSubgraphLeftGearStrut->Enable( down );
800 mSubgraphLeftInnerGearCover->Enable( down );
801 mSubgraphLeftInnerGearCover2->Enable( down );
802 mSubgraphLeftOuterGearCover->Enable( down );
803 mSubgraphLeftTailGearDoor->Enable( down );
804
805 mSubgraphRightGearWheel->Enable( down );
806 mSubgraphRightGearStrut->Enable( down );
807 mSubgraphRightInnerGearCover->Enable( down );
808 mSubgraphRightInnerGearCover2->Enable( down );
809 mSubgraphRightOuterGearCover->Enable( down );
810 mSubgraphRightTailGearDoor->Enable( down );
811
812 mSubgraphTailGearWheel->Enable( down );
813 mSubgraphTailGearStrut->Enable( down );
814 mSubgraphTailGearWheel2->Enable( down );
815 mSubgraphTailGearStrut2->Enable( down );
816 }
817 }
818
819 /*****************************************************************************
820 * Rotate control surfaces (ailerons etc).
821 *****************************************************************************/
822 void
RotateControlSurfaces(const uint axis,const fp controlFraction)823 F82Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction )
824 {
825 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
826 ASSERT_AXIS3(axis);
827
828 switch ( axis )
829 {
830 case AXIS_PITCH:
831 {
832 RotateElevator( *mSubgraphElevator, controlFraction );
833 }
834 break;
835
836 case AXIS_ROLL:
837 {
838 RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON );
839 RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON );
840 }
841 break;
842
843 case AXIS_YAW:
844 {
845 RotateRudder( *mSubgraphRudderLeft, controlFraction, LEFT_RUDDER );
846 RotateRudder( *mSubgraphRudderRight, controlFraction, RIGHT_RUDDER );
847 }
848 break;
849 }
850 }
851
852 ////////////////////////////////////////////////////////////////////////////////
853 /////////////////////////////// F86Aircraft //////////////////////////////////
854 ////////////////////////////////////////////////////////////////////////////////
855
856 /*****************************************************************************
857 * ctor/dtor.
858 *****************************************************************************/
F86Aircraft(shptr<Graph> graph,const WorldVertex & pos)859 F86Aircraft::F86Aircraft( shptr<Graph> graph, const WorldVertex& pos )
860 : Parent(graph,pos,F86Aircraft::ClassGetSpecs()),
861 mSubgraphGear0(new Subgraph(graph,"nosegear1")),
862 mSubgraphGear1(new Subgraph(graph,"nosewheel")),
863 mSubgraphGear2(new Subgraph(graph,"gear.L")),
864 mSubgraphGear3(new Subgraph(graph,"gear.R")),
865 mSubgraphGear4(new Subgraph(graph,"wheel.L")),
866 mSubgraphGear5(new Subgraph(graph,"wheel.R")),
867 // Control surfaces:
868 mSubgraphAileronLeft(new Subgraph(graph,"aileron.L")),
869 mSubgraphAileronRight(new Subgraph(graph,"aileron.R")),
870 mSubgraphElevatorLeft(new Subgraph(graph,"elevator.L")),
871 mSubgraphElevatorRight(new Subgraph(graph,"elevator.R")),
872 mSubgraphRudder(new Subgraph(graph,"rudder_1"))
873 // (no flame)
874 {
875 SetThrottle( 0.0f );
876 }
877
~F86Aircraft()878 F86Aircraft::~F86Aircraft()
879 {
880 // NOP
881 }
882
883 /*****************************************************************************
884 * @return Aircraft specifications struct.
885 *****************************************************************************/
886 const AircraftSpecs&
GetSpecs(void)887 F86Aircraft::GetSpecs( void ) // virtual method
888 {
889 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
890 return F86Aircraft::ClassGetSpecs();
891 }
892
893 const AircraftSpecs&
ClassGetSpecs(void)894 F86Aircraft::ClassGetSpecs( void ) // class method
895 {
896 CODE_CLASS_GET_SPECS( "physics_f86.conf" )
897 }
898
899 /*****************************************************************************
900 * Retract/extend landing gear.
901 *****************************************************************************/
902 void
SetLandingGear(const bool down)903 F86Aircraft::SetLandingGear( const bool down )
904 {
905 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
906
907 if ( IfCanSetLandingGear( down ) )
908 {
909 Parent::SetLandingGear( down );
910
911 mSubgraphGear0->Enable( down ); mSubgraphGear1->Enable( down );
912 mSubgraphGear2->Enable( down ); mSubgraphGear3->Enable( down );
913 mSubgraphGear4->Enable( down ); mSubgraphGear5->Enable( down );
914 }
915 }
916
917 /*****************************************************************************
918 * Rotate control surfaces (ailerons etc).
919 *****************************************************************************/
920 void
RotateControlSurfaces(const uint axis,const fp controlFraction)921 F86Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction )
922 {
923 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
924 ASSERT_AXIS3(axis);
925
926 switch ( axis )
927 {
928 case AXIS_PITCH:
929 {
930 RotateElevator( *mSubgraphElevatorLeft, controlFraction );
931 RotateElevator( *mSubgraphElevatorRight, controlFraction );
932 }
933 break;
934
935 case AXIS_ROLL:
936 {
937 RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON );
938 RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON );
939 }
940 break;
941
942 case AXIS_YAW:
943 {
944 RotateRudder( *mSubgraphRudder, controlFraction );
945 }
946 break;
947 }
948 }
949
950 ////////////////////////////////////////////////////////////////////////////////
951 //////////////////////////////// A4Aircraft //////////////////////////////////
952 ////////////////////////////////////////////////////////////////////////////////
953
954 /*****************************************************************************
955 * ctor/dtor.
956 *****************************************************************************/
A4Aircraft(shptr<Graph> graph,const WorldVertex & pos)957 A4Aircraft::A4Aircraft( shptr<Graph> graph, const WorldVertex& pos )
958 : Parent(graph,pos,A4Aircraft::ClassGetSpecs()),
959 mSubgraphGear0(new Subgraph(graph,"LeftWheel")),
960 mSubgraphGear1(new Subgraph(graph,"LeftLowerLeg")),
961 mSubgraphGear2(new Subgraph(graph,"LeftUpperLeg")),
962 mSubgraphGear3(new Subgraph(graph,"LeftGearDoor")),
963 mSubgraphGear4(new Subgraph(graph,"LeftGearStrut")),
964 mSubgraphGear5(new Subgraph(graph,"LeftLowerLegAssmbly")),
965 mSubgraphGear6(new Subgraph(graph,"RightWheel")),
966 mSubgraphGear7(new Subgraph(graph,"RightLowerLeg")),
967 mSubgraphGear8(new Subgraph(graph,"RightUpperLeg")),
968 mSubgraphGear9(new Subgraph(graph,"RightGearDoor")),
969 mSubgraphGear10(new Subgraph(graph,"RightGearStrut")),
970 mSubgraphGear11(new Subgraph(graph,"RightLowerLegAssmbly")),
971 mSubgraphGear12(new Subgraph(graph,"LandingLight")), // unique to left wheel
972 mSubgraphGear13(new Subgraph(graph,"NoseWheel")), // front wheel
973 mSubgraphGear14(new Subgraph(graph,"Upper-Leg-Nose")), // front wheel
974 mSubgraphGear15(new Subgraph(graph,"Lower-Leg")), // front wheel
975 mSubgraphGear16(new Subgraph(graph,"NoseGearStrut")), // front wheel
976 mSubgraphGear17(new Subgraph(graph,"NoseGearDoor")), // front wheel
977 // Control surfaces:
978 // This model lacks real ailerons.
979 mSubgraphAileronLeft(new Subgraph(graph,"LeftSpoiler")),
980 mSubgraphAileronRight(new Subgraph(graph,"RightSpoiler")),
981 mSubgraphAileronLeft2(new Subgraph(graph,"LeftFlap-New")),
982 mSubgraphAileronRight2(new Subgraph(graph,"RightFlap-New")),
983 mSubgraphElevatorLeft(new Subgraph(graph,"LeftElevator")),
984 mSubgraphElevatorRight(new Subgraph(graph,"RightElevator")),
985 mSubgraphRudder(new Subgraph(graph,"Rudder"))
986 // (no flame)
987 {
988 SetThrottle( 0.0f );
989 }
990
~A4Aircraft()991 A4Aircraft::~A4Aircraft()
992 {
993 // NOP
994 }
995
996 /*****************************************************************************
997 * @return Aircraft specifications struct.
998 *****************************************************************************/
999 const AircraftSpecs&
GetSpecs(void)1000 A4Aircraft::GetSpecs( void ) // virtual method
1001 {
1002 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1003 return A4Aircraft::ClassGetSpecs();
1004 }
1005
1006 const AircraftSpecs&
ClassGetSpecs(void)1007 A4Aircraft::ClassGetSpecs( void ) // class method
1008 {
1009 CODE_CLASS_GET_SPECS( "physics_a4.conf" )
1010 }
1011
1012 /*****************************************************************************
1013 * Retract/extend landing gear.
1014 *****************************************************************************/
1015 void
SetLandingGear(const bool down)1016 A4Aircraft::SetLandingGear( const bool down )
1017 {
1018 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1019
1020 if ( IfCanSetLandingGear( down ) )
1021 {
1022 Parent::SetLandingGear( down );
1023
1024 mSubgraphGear0->Enable( down ); mSubgraphGear1->Enable( down );
1025 mSubgraphGear2->Enable( down ); mSubgraphGear3->Enable( down );
1026 mSubgraphGear4->Enable( down ); mSubgraphGear5->Enable( down );
1027 mSubgraphGear6->Enable( down ); mSubgraphGear7->Enable( down );
1028 mSubgraphGear8->Enable( down ); mSubgraphGear9->Enable( down );
1029 mSubgraphGear10->Enable( down ); mSubgraphGear11->Enable( down );
1030 mSubgraphGear12->Enable( down ); mSubgraphGear13->Enable( down );
1031 mSubgraphGear14->Enable( down ); mSubgraphGear15->Enable( down );
1032 mSubgraphGear16->Enable( down ); mSubgraphGear17->Enable( down );
1033 }
1034 }
1035
1036 /*****************************************************************************
1037 * Rotate control surfaces (ailerons etc).
1038 *****************************************************************************/
1039 void
RotateControlSurfaces(const uint axis,const fp controlFraction)1040 A4Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction )
1041 {
1042 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1043 ASSERT_AXIS3(axis);
1044
1045 switch ( axis )
1046 {
1047 case AXIS_PITCH:
1048 {
1049 RotateElevator( *mSubgraphElevatorLeft, controlFraction );
1050 RotateElevator( *mSubgraphElevatorRight, controlFraction );
1051 }
1052 break;
1053
1054 case AXIS_ROLL:
1055 {
1056 RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON );
1057 RotateAileron( *mSubgraphAileronLeft2, controlFraction, LEFT_AILERON );
1058 RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON );
1059 RotateAileron( *mSubgraphAileronRight2, controlFraction, RIGHT_AILERON );
1060 }
1061 break;
1062
1063 case AXIS_YAW:
1064 {
1065 // Subgraph is the entire rudder.
1066 //RotateRudder( *mSubgraphRudder, controlFraction );
1067 }
1068 break;
1069 }
1070 }
1071
1072 ////////////////////////////////////////////////////////////////////////////////
1073 /////////////////////////////// F14Aircraft //////////////////////////////////
1074 ////////////////////////////////////////////////////////////////////////////////
1075
1076 /*****************************************************************************
1077 * ctor/dtor.
1078 *****************************************************************************/
F14Aircraft(shptr<Graph> graph,const WorldVertex & pos)1079 F14Aircraft::F14Aircraft( shptr<Graph> graph, const WorldVertex& pos )
1080 : Parent(graph,pos,F14Aircraft::ClassGetSpecs()),
1081 // gear:
1082 mSubgraphGear0(new Subgraph(graph,"MainWheelL")),
1083 mSubgraphGear1(new Subgraph(graph,"MainWheelR")),
1084 mSubgraphGear2(new Subgraph(graph,"NsWheel")),
1085 mSubgraphGear3(new Subgraph(graph,"FwdNsGrDoor")),
1086 mSubgraphGear4(new Subgraph(graph,"MidNsGrDoor")),
1087 mSubgraphGear5(new Subgraph(graph,"CatBar")),
1088 mSubgraphGear6(new Subgraph(graph,"CatBarLink")),
1089 mSubgraphGear7(new Subgraph(graph,"NsGearStrut")),
1090 mSubgraphGear8(new Subgraph(graph,"Tube.006")),
1091 mSubgraphGear9(new Subgraph(graph,"Tube.007")),
1092 mSubgraphGear10(new Subgraph(graph,"Tube.013")),
1093 mSubgraphGear11(new Subgraph(graph,"Tube.014")),
1094 mSubgraphGear12(new Subgraph(graph,"NsGrRotatingSleeve")),
1095 mSubgraphGear13(new Subgraph(graph,"RotatingSleeve-L")),
1096 mSubgraphGear14(new Subgraph(graph,"RotatingSleeve-R")),
1097 mSubgraphGear15(new Subgraph(graph,"MnGrStrut-L")),
1098 mSubgraphGear16(new Subgraph(graph,"MnGrStrut.001")),
1099 mSubgraphGear17(new Subgraph(graph,"Brace1")),
1100 mSubgraphGear18(new Subgraph(graph,"Brace1.001")),
1101 mSubgraphGear19(new Subgraph(graph,"Brace1.002")),
1102 mSubgraphGear20(new Subgraph(graph,"Brace1.003")),
1103 mSubgraphGear21(new Subgraph(graph,"HiCompassL")),
1104 mSubgraphGear22(new Subgraph(graph,"HiCompassR")),
1105 mSubgraphGear23(new Subgraph(graph,"LShock")),
1106 mSubgraphGear24(new Subgraph(graph,"RShock")),
1107 mSubgraphGear25(new Subgraph(graph,"NsShock")),
1108 mSubgraphGear26(new Subgraph(graph,"LoCompassL")),
1109 mSubgraphGear27(new Subgraph(graph,"LoCompassR")),
1110 mSubgraphGear28(new Subgraph(graph,"LoNsCompass")),
1111 mSubgraphGear29(new Subgraph(graph,"UpNsCompass")),
1112 mSubgraphGear30(new Subgraph(graph,"Downlock")),
1113 mSubgraphGear31(new Subgraph(graph,"Downlock.001")),
1114 mSubgraphGear32(new Subgraph(graph,"LandingLight")),
1115 mSubgraphGear33(new Subgraph(graph,"WheelBrake")),
1116 mSubgraphGear34(new Subgraph(graph,"WheelBrake.001")),
1117 //
1118 mSubgraphWingLeft0(new Subgraph(graph,"Wing_0")),
1119 mSubgraphWingLeft1(new Subgraph(graph,"Wing_1")),
1120 mSubgraphWingLeft2(new Subgraph(graph,"Flap1_0")),
1121 mSubgraphWingLeft3(new Subgraph(graph,"Flap1_1")),
1122 mSubgraphWingLeft4(new Subgraph(graph,"Flap2_0")),
1123 mSubgraphWingLeft5(new Subgraph(graph,"Flap2_1")),
1124 mSubgraphWingLeft6(new Subgraph(graph,"Flap3_0")),
1125 mSubgraphWingLeft7(new Subgraph(graph,"Flap3_1")),
1126 mSubgraphWingLeft8(new Subgraph(graph,"Flap1Brow")),
1127 mSubgraphWingLeft9(new Subgraph(graph,"Flap2Brow")),
1128 mSubgraphWingLeft10(new Subgraph(graph,"Flap3Brow")),
1129 mSubgraphWingLeft11(new Subgraph(graph,"FlapSeal1_0")),
1130 mSubgraphWingLeft12(new Subgraph(graph,"FlapSeal1_1")),
1131 mSubgraphWingLeft13(new Subgraph(graph,"FlapSeal2_0")),
1132 mSubgraphWingLeft14(new Subgraph(graph,"FlapSeal2_1")),
1133 mSubgraphWingLeft15(new Subgraph(graph,"FlapSeal3_0")),
1134 mSubgraphWingLeft16(new Subgraph(graph,"FlapSeal3_1")),
1135 mSubgraphWingLeft17(new Subgraph(graph,"Spoiler1_0")),
1136 mSubgraphWingLeft18(new Subgraph(graph,"Spoiler1_1")),
1137 mSubgraphWingLeft19(new Subgraph(graph,"Spoiler2_0")),
1138 mSubgraphWingLeft20(new Subgraph(graph,"Spoiler2_1")),
1139 mSubgraphWingLeft21(new Subgraph(graph,"Spoiler3_0")),
1140 mSubgraphWingLeft22(new Subgraph(graph,"Spoiler3_1")),
1141 mSubgraphWingLeft23(new Subgraph(graph,"Spoiler4_0")),
1142 mSubgraphWingLeft24(new Subgraph(graph,"Spoiler4_1")),
1143 mSubgraphWingLeft25(new Subgraph(graph,"Slat1_0")),
1144 mSubgraphWingLeft26(new Subgraph(graph,"Slat1_1")),
1145 mSubgraphWingLeft27(new Subgraph(graph,"Slat2_0")),
1146 mSubgraphWingLeft28(new Subgraph(graph,"Slat2_1")),
1147 mSubgraphWingLeft29(new Subgraph(graph,"LWingSlimmer")),
1148 //
1149 mSubgraphWingRight0(new Subgraph(graph,"Wing.001_0")),
1150 mSubgraphWingRight1(new Subgraph(graph,"Wing.001_1")),
1151 mSubgraphWingRight2(new Subgraph(graph,"Flap1.001_0")),
1152 mSubgraphWingRight3(new Subgraph(graph,"Flap1.001_1")),
1153 mSubgraphWingRight4(new Subgraph(graph,"Flap2.001_0")),
1154 mSubgraphWingRight5(new Subgraph(graph,"Flap2.001_1")),
1155 mSubgraphWingRight6(new Subgraph(graph,"Flap3.001_0")),
1156 mSubgraphWingRight7(new Subgraph(graph,"Flap3.001_1")),
1157 mSubgraphWingRight8(new Subgraph(graph,"Flap1Brow.001")),
1158 mSubgraphWingRight9(new Subgraph(graph,"Flap2Brow.001")),
1159 mSubgraphWingRight10(new Subgraph(graph,"Flap3Brow.001")),
1160 mSubgraphWingRight11(new Subgraph(graph,"FlapSeal1.001_0")),
1161 mSubgraphWingRight12(new Subgraph(graph,"FlapSeal1.001_1")),
1162 mSubgraphWingRight13(new Subgraph(graph,"FlapSeal2.001_0")),
1163 mSubgraphWingRight14(new Subgraph(graph,"FlapSeal2.001_1")),
1164 mSubgraphWingRight15(new Subgraph(graph,"FlapSeal3.001_0")),
1165 mSubgraphWingRight16(new Subgraph(graph,"FlapSeal3.001_1")),
1166 mSubgraphWingRight17(new Subgraph(graph,"Spoiler1.001_0")),
1167 mSubgraphWingRight18(new Subgraph(graph,"Spoiler1.001_1")),
1168 mSubgraphWingRight19(new Subgraph(graph,"Spoiler2.001_0")),
1169 mSubgraphWingRight20(new Subgraph(graph,"Spoiler2.001_1")),
1170 mSubgraphWingRight21(new Subgraph(graph,"Spoiler3.001_0")),
1171 mSubgraphWingRight22(new Subgraph(graph,"Spoiler3.001_1")),
1172 mSubgraphWingRight23(new Subgraph(graph,"Spoiler4.001_0")),
1173 mSubgraphWingRight24(new Subgraph(graph,"Spoiler4.001_1")),
1174 mSubgraphWingRight25(new Subgraph(graph,"Slat1.001_0")),
1175 mSubgraphWingRight26(new Subgraph(graph,"Slat1.001_1")),
1176 mSubgraphWingRight27(new Subgraph(graph,"Slat2.001_0")),
1177 mSubgraphWingRight28(new Subgraph(graph,"Slat2.001_1")),
1178 mSubgraphWingRight29(new Subgraph(graph,"RWingSlimmer")),
1179 mSubgraphTaileronLeft(new Subgraph(graph,"Stabilator")),
1180 mSubgraphTaileronRight(new Subgraph(graph,"Stabilator.001")),
1181 mSubgraphRudderLeft(new Subgraph(graph,"RudderL")),
1182 mSubgraphRudderRight(new Subgraph(graph,"RudderR")),
1183 //
1184 mSubgraphLadder0(new Subgraph(graph,"Ladder")),
1185 mSubgraphLadder1(new Subgraph(graph,"Ladder.001")),
1186 mSubgraphLadder2(new Subgraph(graph,"Ladder.002")),
1187 mSubgraphRefuelProbe(new Subgraph(graph,"RefuelProbe")),
1188 mSubgraphFlameInner0(new Subgraph(graph,"InnerFlameL")),
1189 mSubgraphFlameInner1(new Subgraph(graph,"InnerFlameR")),
1190 mSubgraphFlameOuter0(new Subgraph(graph,"outerFlame")),
1191 mSubgraphFlameOuter1(new Subgraph(graph,"outerFlame.001")),
1192 mSubgraphShockWave(new Subgraph(graph,"ShockWave")),
1193 mSubgraphManeuverVortexLeft(new Subgraph(graph,"ManeuverVortexL")),
1194 mSubgraphManeuverVortexRight(new Subgraph(graph,"ManeuverVortexR")),
1195 //
1196 mGearSubgraphs(), mLeftWingSubgraphs(), mRightWingSubgraphs(),
1197 //
1198 mSwingWingsFraction(0.0f),
1199 mAileronFraction(0.0f)
1200 {
1201 SetThrottle( 0.0f );
1202
1203 // Hide superfluous parts.
1204 mSubgraphLadder0->Enable( false );
1205 mSubgraphLadder1->Enable( false );
1206 mSubgraphLadder2->Enable( false );
1207 mSubgraphRefuelProbe->Enable( false );
1208 mSubgraphShockWave->Enable( false );
1209 mSubgraphManeuverVortexLeft->Enable( false );
1210 mSubgraphManeuverVortexRight->Enable( false );
1211
1212 // Build list of gear subgraphs.
1213 mLeftWingSubgraphs.reserve( 50 );
1214 mRightWingSubgraphs.reserve( 50 );
1215 #define F14_PUSH_GEAR_SUBGRAPH( NUM ) \
1216 mGearSubgraphs.push_back( mSubgraphGear##NUM );
1217 F14_PUSH_GEAR_SUBGRAPH( 0 ); F14_PUSH_GEAR_SUBGRAPH( 1 );
1218 F14_PUSH_GEAR_SUBGRAPH( 2 ); F14_PUSH_GEAR_SUBGRAPH( 3 );
1219 F14_PUSH_GEAR_SUBGRAPH( 4 ); F14_PUSH_GEAR_SUBGRAPH( 5 );
1220 F14_PUSH_GEAR_SUBGRAPH( 6 ); F14_PUSH_GEAR_SUBGRAPH( 7 );
1221 F14_PUSH_GEAR_SUBGRAPH( 8 ); F14_PUSH_GEAR_SUBGRAPH( 9 );
1222 F14_PUSH_GEAR_SUBGRAPH( 10 ); F14_PUSH_GEAR_SUBGRAPH( 11 );
1223 F14_PUSH_GEAR_SUBGRAPH( 12 ); F14_PUSH_GEAR_SUBGRAPH( 13 );
1224 F14_PUSH_GEAR_SUBGRAPH( 14 ); F14_PUSH_GEAR_SUBGRAPH( 15 );
1225 F14_PUSH_GEAR_SUBGRAPH( 16 ); F14_PUSH_GEAR_SUBGRAPH( 17 );
1226 F14_PUSH_GEAR_SUBGRAPH( 18 ); F14_PUSH_GEAR_SUBGRAPH( 19 );
1227 F14_PUSH_GEAR_SUBGRAPH( 20 ); F14_PUSH_GEAR_SUBGRAPH( 21 );
1228 F14_PUSH_GEAR_SUBGRAPH( 22 ); F14_PUSH_GEAR_SUBGRAPH( 23 );
1229 F14_PUSH_GEAR_SUBGRAPH( 24 ); F14_PUSH_GEAR_SUBGRAPH( 25 );
1230 F14_PUSH_GEAR_SUBGRAPH( 26 ); F14_PUSH_GEAR_SUBGRAPH( 27 );
1231 F14_PUSH_GEAR_SUBGRAPH( 28 ); F14_PUSH_GEAR_SUBGRAPH( 29 );
1232 F14_PUSH_GEAR_SUBGRAPH( 30 ); F14_PUSH_GEAR_SUBGRAPH( 31 );
1233 F14_PUSH_GEAR_SUBGRAPH( 32 ); F14_PUSH_GEAR_SUBGRAPH( 33 );
1234 F14_PUSH_GEAR_SUBGRAPH( 34 );
1235
1236 // Build list of wing subgraphs.
1237 mLeftWingSubgraphs.reserve( 50 );
1238 mRightWingSubgraphs.reserve( 50 );
1239 #define F14_PUSH_WING_SUBGRAPH( NUM ) \
1240 mLeftWingSubgraphs.push_back( mSubgraphWingLeft##NUM ); \
1241 mRightWingSubgraphs.push_back( mSubgraphWingRight##NUM );
1242 F14_PUSH_WING_SUBGRAPH( 0 ); F14_PUSH_WING_SUBGRAPH( 1 );
1243 F14_PUSH_WING_SUBGRAPH( 2 ); F14_PUSH_WING_SUBGRAPH( 3 );
1244 F14_PUSH_WING_SUBGRAPH( 4 ); F14_PUSH_WING_SUBGRAPH( 5 );
1245 F14_PUSH_WING_SUBGRAPH( 6 ); F14_PUSH_WING_SUBGRAPH( 7 );
1246 F14_PUSH_WING_SUBGRAPH( 8 ); F14_PUSH_WING_SUBGRAPH( 9 );
1247 F14_PUSH_WING_SUBGRAPH( 10 ); F14_PUSH_WING_SUBGRAPH( 11 );
1248 F14_PUSH_WING_SUBGRAPH( 12 ); F14_PUSH_WING_SUBGRAPH( 13 );
1249 F14_PUSH_WING_SUBGRAPH( 14 ); F14_PUSH_WING_SUBGRAPH( 15 );
1250 F14_PUSH_WING_SUBGRAPH( 16 ); F14_PUSH_WING_SUBGRAPH( 17 );
1251 F14_PUSH_WING_SUBGRAPH( 18 ); F14_PUSH_WING_SUBGRAPH( 19 );
1252 F14_PUSH_WING_SUBGRAPH( 20 ); F14_PUSH_WING_SUBGRAPH( 21 );
1253 F14_PUSH_WING_SUBGRAPH( 22 ); F14_PUSH_WING_SUBGRAPH( 23 );
1254 F14_PUSH_WING_SUBGRAPH( 24 ); F14_PUSH_WING_SUBGRAPH( 25 );
1255 F14_PUSH_WING_SUBGRAPH( 26 ); F14_PUSH_WING_SUBGRAPH( 27 );
1256 F14_PUSH_WING_SUBGRAPH( 28 ); F14_PUSH_WING_SUBGRAPH( 29 );
1257
1258 // Exhaust flame shouldn't cast shadows.
1259 ShadowSceneGraph::DisableShadows( mSubgraphFlameInner0->GetRootNode() );
1260 ShadowSceneGraph::DisableShadows( mSubgraphFlameInner1->GetRootNode() );
1261 ShadowSceneGraph::DisableShadows( mSubgraphFlameOuter0->GetRootNode() );
1262 ShadowSceneGraph::DisableShadows( mSubgraphFlameOuter1->GetRootNode() );
1263 }
1264
~F14Aircraft()1265 F14Aircraft::~F14Aircraft()
1266 {
1267 // NOP
1268 }
1269
1270 /*****************************************************************************
1271 * Reset.
1272 *****************************************************************************/
1273 void
Reset(void)1274 F14Aircraft::Reset( void )
1275 {
1276 Parent::Reset();
1277
1278 // Swing wings forward.
1279 SwingWings( 0.0f );
1280 }
1281
1282 /*****************************************************************************
1283 * @return Aircraft specifications struct.
1284 *****************************************************************************/
1285 const AircraftSpecs&
GetSpecs(void)1286 F14Aircraft::GetSpecs( void ) // virtual method
1287 {
1288 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1289 return F14Aircraft::ClassGetSpecs();
1290 }
1291
1292 const AircraftSpecs&
ClassGetSpecs(void)1293 F14Aircraft::ClassGetSpecs( void ) // class method
1294 {
1295 CODE_CLASS_GET_SPECS( "physics_f14.conf" )
1296 }
1297
1298 /*****************************************************************************
1299 * Retract/extend landing gear.
1300 *****************************************************************************/
1301 void
SetLandingGear(const bool down)1302 F14Aircraft::SetLandingGear( const bool down )
1303 {
1304 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1305
1306 if ( IfCanSetLandingGear( down ) )
1307 {
1308 Parent::SetLandingGear( down );
1309
1310 for ( uint i = 0; i < mGearSubgraphs.size(); ++i )
1311 mGearSubgraphs[i]->Enable( down );
1312 }
1313 }
1314
1315 /*****************************************************************************
1316 * When throttle is changed, animate jet exhaust flame.
1317 *****************************************************************************/
1318 void
SetThrottle(const fp throttle)1319 F14Aircraft::SetThrottle( const fp throttle )
1320 {
1321 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1322
1323 Parent::SetThrottle( throttle );
1324 const bool flameInner = (throttle >= THROTTLE_FLAME_LOW);
1325 const bool flameOuter = (throttle >= THROTTLE_FLAME_HIGH);
1326 mSubgraphFlameInner0->Enable( flameInner );
1327 mSubgraphFlameInner1->Enable( flameInner );
1328 mSubgraphFlameOuter0->Enable( flameOuter );
1329 mSubgraphFlameOuter1->Enable( flameOuter );
1330 }
1331
1332 /*****************************************************************************
1333 * Swing wings { 0.0:forward...1.0:back }
1334 *****************************************************************************/
1335 void
SwingWings(const float fraction)1336 F14Aircraft::SwingWings( const float fraction )
1337 {
1338 ASSERT( mLeftWingSubgraphs.size() == mRightWingSubgraphs.size() );
1339
1340 mSwingWingsFraction = Clamp1( fraction );
1341
1342 // Undo rotation/translation of wing subgraphs from previous call.
1343 for ( uint i = 0; i < mLeftWingSubgraphs.size(); ++i )
1344 {
1345 mLeftWingSubgraphs[i]->Reset();
1346 mRightWingSubgraphs[i]->Reset();
1347 }
1348
1349 // deg = 0 fully forward
1350 // deg = 45 fully back
1351 const Degree deg = mSwingWingsFraction * 45.0f;
1352 const Radian rad = Deg2Rad( deg );
1353
1354 // This particular 3D model requires translating the position
1355 // of the subgraphs as a function of swing-wings.
1356 // offset_x = 0.00 swing forward
1357 // offset_z = 0.00 swing forward
1358 // offset_x = -1.40 swing back
1359 // offset_z = +-1.75 swing back (+- for left/right wing)
1360 const fp offset_x = mSwingWingsFraction * -1.40f;
1361 const fp offset_z = mSwingWingsFraction * 1.75f;
1362 for ( uint i = 0; i < mLeftWingSubgraphs.size(); ++i )
1363 {
1364 mLeftWingSubgraphs[i]->Translate( XX, offset_x ); // move along fuselage
1365 mRightWingSubgraphs[i]->Translate( XX, offset_x );
1366
1367 mLeftWingSubgraphs[i]->Translate( ZZ, offset_z ); // move outwards (along wings)
1368 mRightWingSubgraphs[i]->Translate( ZZ, -offset_z );
1369
1370 mLeftWingSubgraphs[i]->Rotate( YY, rad );
1371 mRightWingSubgraphs[i]->Rotate( YY, -rad );
1372 }
1373 }
1374
1375 /*****************************************************************************
1376 * Rotate control surfaces (ailerons etc).
1377 *****************************************************************************/
1378 void
RotateControlSurfaces(const uint axis,const fp controlFraction)1379 F14Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction )
1380 {
1381 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1382 ASSERT_AXIS3(axis);
1383
1384 const AircraftSpecs& specs = GetSpecs();
1385
1386 switch ( axis )
1387 {
1388 case AXIS_PITCH:
1389 {
1390 RotateElevator( *mSubgraphTaileronLeft, controlFraction );
1391 RotateElevator( *mSubgraphTaileronRight, controlFraction );
1392 }
1393 break;
1394
1395 case AXIS_ROLL:
1396 {
1397 // F-14 wings are complex.
1398
1399 // Tailerons:
1400 RotateAileron( *mSubgraphTaileronLeft, controlFraction, LEFT_AILERON, specs.mElevatorOffset );
1401 RotateAileron( *mSubgraphTaileronRight, controlFraction, RIGHT_AILERON, specs.mElevatorOffset );
1402
1403 // Ailerons (outer flaps) if wings are straight-out.
1404 if ( mSwingWingsFraction <= F14_AILERONS_ACTIVE_SWING_WINGS )
1405 {
1406 // Specially rotate the F-14 ailerons.
1407 #define F14_ROTATE_AILERONS( SUBGRAPH, CONTROL_FRACTION, AILERON ) \
1408 {{ \
1409 (SUBGRAPH).Translate( specs.mAileronOffset ); \
1410 (SUBGRAPH).Rotate( MODEL_AXIS_PITCH, \
1411 specs.mAileronROF * (CONTROL_FRACTION) * int(AILERON) ); \
1412 (SUBGRAPH).Translate( -specs.mAileronOffset ); \
1413 }}
1414
1415 // Undo previous rotation.
1416 F14_ROTATE_AILERONS( *mSubgraphWingLeft3, -mAileronFraction, LEFT_AILERON );
1417 F14_ROTATE_AILERONS( *mSubgraphWingRight3, -mAileronFraction, RIGHT_AILERON );
1418
1419 // Apply current rotation.
1420 F14_ROTATE_AILERONS( *mSubgraphWingLeft3, controlFraction, LEFT_AILERON );
1421 F14_ROTATE_AILERONS( *mSubgraphWingRight3, controlFraction, RIGHT_AILERON );
1422
1423 // Remember for next time.
1424 mAileronFraction = controlFraction;
1425 }
1426 }
1427 break;
1428
1429 case AXIS_YAW:
1430 {
1431 RotateRudder( *mSubgraphRudderLeft, controlFraction, LEFT_RUDDER );
1432 RotateRudder( *mSubgraphRudderRight, controlFraction, RIGHT_RUDDER );
1433 }
1434 break;
1435 }
1436 }
1437
1438 ////////////////////////////////////////////////////////////////////////////////
1439 /////////////////////////////// F15Aircraft //////////////////////////////////
1440 ////////////////////////////////////////////////////////////////////////////////
1441
1442 /*****************************************************************************
1443 * ctor/dtor.
1444 *****************************************************************************/
F15Aircraft(shptr<Graph> graph,const WorldVertex & pos)1445 F15Aircraft::F15Aircraft( shptr<Graph> graph, const WorldVertex& pos )
1446 : Parent(graph,pos,F15Aircraft::ClassGetSpecs()),
1447 // gear:
1448 mSubgraphGear0(new Subgraph(graph,"LeftWheel")),
1449 mSubgraphGear1(new Subgraph(graph,"LeftWheelTire")),
1450 mSubgraphGear2(new Subgraph(graph,"RightWheel")),
1451 mSubgraphGear3(new Subgraph(graph,"RightWheelTire")),
1452 mSubgraphGear4(new Subgraph(graph,"FrontWheel")),
1453 mSubgraphGear5(new Subgraph(graph,"FrontWheelTire")),
1454 // exhaust flame:
1455 mSubgraphFlame0(new Subgraph(graph,"InternalFlame")),
1456 mSubgraphFlame1(new Subgraph(graph,"ExternalFlame")),
1457 // control surfaces:
1458 mSubgraphAileronLeft(new Subgraph(graph,"AileronLeft")),
1459 mSubgraphAileronRight(new Subgraph(graph,"AileronRight")),
1460 mSubgraphElevatorLeft(new Subgraph(graph,"ElevatorLeft")),
1461 mSubgraphElevatorRight(new Subgraph(graph,"ElevatorRight")),
1462 mSubgraphRudderLeft(new Subgraph(graph,"RudderLeft")),
1463 mSubgraphRudderRight(new Subgraph(graph,"RudderRight"))
1464 {
1465 SetThrottle( 0.0f );
1466
1467 // Exhaust flame shouldn't cast shadows.
1468 ShadowSceneGraph::DisableShadows( mSubgraphFlame0->GetRootNode() );
1469 ShadowSceneGraph::DisableShadows( mSubgraphFlame1->GetRootNode() );
1470 }
1471
~F15Aircraft()1472 F15Aircraft::~F15Aircraft()
1473 {
1474 // NOP
1475 }
1476
1477 /*****************************************************************************
1478 * @return Aircraft specifications struct.
1479 *****************************************************************************/
1480 const AircraftSpecs&
GetSpecs(void)1481 F15Aircraft::GetSpecs( void ) // virtual method
1482 {
1483 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1484 return F15Aircraft::ClassGetSpecs();
1485 }
1486
1487 const AircraftSpecs&
ClassGetSpecs(void)1488 F15Aircraft::ClassGetSpecs( void ) // class method
1489 {
1490 CODE_CLASS_GET_SPECS( "physics_f15.conf" )
1491 }
1492
1493 /*****************************************************************************
1494 * Retract/extend landing gear.
1495 *****************************************************************************/
1496 void
SetLandingGear(const bool down)1497 F15Aircraft::SetLandingGear( const bool down )
1498 {
1499 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1500
1501 if ( IfCanSetLandingGear( down ) )
1502 {
1503 Parent::SetLandingGear( down );
1504
1505 mSubgraphGear0->Enable( down );
1506 mSubgraphGear1->Enable( down );
1507 mSubgraphGear2->Enable( down );
1508 mSubgraphGear3->Enable( down );
1509 mSubgraphGear4->Enable( down );
1510 mSubgraphGear5->Enable( down );
1511 }
1512 }
1513
1514 /*****************************************************************************
1515 * When throttle is changed, animate jet exhaust flame.
1516 *****************************************************************************/
1517 void
SetThrottle(const fp throttle)1518 F15Aircraft::SetThrottle( const fp throttle )
1519 {
1520 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1521
1522 Parent::SetThrottle( throttle );
1523 mSubgraphFlame0->Enable( throttle >= THROTTLE_FLAME_LOW );
1524 mSubgraphFlame1->Enable( throttle >= THROTTLE_FLAME_HIGH ); // afterburner
1525 }
1526
1527 /*****************************************************************************
1528 * Rotate control surfaces (ailerons etc).
1529 *****************************************************************************/
1530 void
RotateControlSurfaces(const uint axis,const fp controlFraction)1531 F15Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction )
1532 {
1533 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1534 ASSERT_AXIS3(axis);
1535
1536 switch ( axis )
1537 {
1538 case AXIS_PITCH:
1539 {
1540 RotateElevator( *mSubgraphElevatorLeft, controlFraction );
1541 RotateElevator( *mSubgraphElevatorRight, controlFraction );
1542 }
1543 break;
1544
1545 case AXIS_ROLL:
1546 {
1547 RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON );
1548 RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON );
1549 }
1550 break;
1551
1552 case AXIS_YAW:
1553 {
1554 RotateRudder( *mSubgraphRudderLeft, controlFraction, LEFT_RUDDER );
1555 RotateRudder( *mSubgraphRudderRight, controlFraction, RIGHT_RUDDER );
1556 }
1557 break;
1558 }
1559 }
1560
1561 ////////////////////////////////////////////////////////////////////////////////
1562 /////////////////////////////// F16Aircraft //////////////////////////////////
1563 ////////////////////////////////////////////////////////////////////////////////
1564
1565 /*****************************************************************************
1566 * ctor/dtor.
1567 *****************************************************************************/
F16Aircraft(shptr<Graph> graph,const WorldVertex & pos)1568 F16Aircraft::F16Aircraft( shptr<Graph> graph, const WorldVertex& pos )
1569 : Parent(graph,pos,F16Aircraft::ClassGetSpecs()),
1570 // gear:
1571 mSubgraphGear0(new Subgraph(graph,"internal_front_gear_door")),
1572 mSubgraphGear1(new Subgraph(graph,"internal_right_main_door")),
1573 mSubgraphGear2(new Subgraph(graph,"internal_left_main_door")),
1574 //
1575 mSubgraphGear3(new Subgraph(graph,"front_tire")),
1576 mSubgraphGear4(new Subgraph(graph,"front_aft_strut")),
1577 mSubgraphGear5(new Subgraph(graph,"front_lower_strut")),
1578 mSubgraphGear6(new Subgraph(graph,"front_upper_strut")),
1579 //
1580 mSubgraphGear7(new Subgraph(graph,"left_main_strut")),
1581 mSubgraphGear8(new Subgraph(graph,"left_main_tire")),
1582 mSubgraphGear9(new Subgraph(graph,"left_lower_main_strut")),
1583 mSubgraphGear10(new Subgraph(graph,"left_upper_main_strut")),
1584 //
1585 mSubgraphGear11(new Subgraph(graph,"right_main_strut")),
1586 mSubgraphGear12(new Subgraph(graph,"right_main_tire")),
1587 mSubgraphGear13(new Subgraph(graph,"right_lower_main_strut")),
1588 mSubgraphGear14(new Subgraph(graph,"right_upper_main_strut")),
1589 //
1590 mSubgraphGear15(new Subgraph(graph,"external_front_gear_door")),
1591 mSubgraphGear16(new Subgraph(graph,"external_left_main_door")),
1592 mSubgraphGear17(new Subgraph(graph,"external_right_main_door")),
1593 // exhaust flame:
1594 mSubgraphFlame0(new Subgraph(graph,"internal_flame")),
1595 mSubgraphFlame1(new Subgraph(graph,"external_flame")),
1596 // control surfaces:
1597 mSubgraphAileronLeft(new Subgraph(graph,"left_upper_aileron")),
1598 mSubgraphAileronRight(new Subgraph(graph,"right_upper_aileron")),
1599 mSubgraphFlapLeft(new Subgraph(graph,"left_upper_flap")),
1600 mSubgraphFlapRight(new Subgraph(graph,"right_upper_flap")),
1601 mSubgraphElevatorLeft(new Subgraph(graph,"left_upper_horizontal_tail")),
1602 mSubgraphElevatorRight(new Subgraph(graph,"right_upper_horizontal_tail")),
1603 mSubgraphRudder0(new Subgraph(graph,"rudder2")),
1604 mSubgraphRudder1(new Subgraph(graph,"rudder3")),
1605 mSubgraphRudder2(new Subgraph(graph,"rudder5")),
1606 mSubgraphRudder3(new Subgraph(graph,"rudder6")),
1607 // junk:
1608 mSubgraphJunk0(new Subgraph(graph,"lhocondenscone")),
1609 mSubgraphJunk1(new Subgraph(graph,"rhocondenscone"))
1610 {
1611 SetThrottle( 0.0f );
1612
1613 // Exhaust flame shouldn't cast shadows.
1614 ShadowSceneGraph::DisableShadows( mSubgraphFlame0->GetRootNode() );
1615 ShadowSceneGraph::DisableShadows( mSubgraphFlame1->GetRootNode() );
1616
1617 // Disable junk parts of F-16 model.
1618 mSubgraphJunk0->Enable( false );
1619 mSubgraphJunk1->Enable( false );
1620 }
1621
~F16Aircraft()1622 F16Aircraft::~F16Aircraft()
1623 {
1624 // NOP
1625 }
1626
1627 /*****************************************************************************
1628 * @return Aircraft specifications struct.
1629 *****************************************************************************/
1630 const AircraftSpecs&
GetSpecs(void)1631 F16Aircraft::GetSpecs( void ) // virtual method
1632 {
1633 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1634 return F16Aircraft::ClassGetSpecs();
1635 }
1636
1637 const AircraftSpecs&
ClassGetSpecs(void)1638 F16Aircraft::ClassGetSpecs( void ) // class method
1639 {
1640 CODE_CLASS_GET_SPECS( "physics_f16.conf" )
1641 }
1642
1643 /*****************************************************************************
1644 * Retract/extend landing gear.
1645 *****************************************************************************/
1646 void
SetLandingGear(const bool down)1647 F16Aircraft::SetLandingGear( const bool down )
1648 {
1649 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1650
1651 // Known problem: The door for the front wheel should be rotated
1652 // into the fuselage but isn't implemented.
1653
1654 if ( IfCanSetLandingGear( down ) )
1655 {
1656 Parent::SetLandingGear( down );
1657
1658 mSubgraphGear0->Enable( down ); mSubgraphGear1->Enable( down );
1659 mSubgraphGear2->Enable( down ); mSubgraphGear3->Enable( down );
1660 mSubgraphGear4->Enable( down ); mSubgraphGear5->Enable( down );
1661 mSubgraphGear6->Enable( down ); mSubgraphGear7->Enable( down );
1662 mSubgraphGear8->Enable( down ); mSubgraphGear9->Enable( down );
1663 mSubgraphGear10->Enable( down ); mSubgraphGear11->Enable( down );
1664 mSubgraphGear12->Enable( down ); mSubgraphGear13->Enable( down );
1665 mSubgraphGear14->Enable( down ); mSubgraphGear15->Enable( down );
1666 //mSubgraphGear16->Enable( down ); mSubgraphGear17->Enable( down );
1667 }
1668 }
1669
1670 /*****************************************************************************
1671 * When throttle is changed, animate jet exhaust flame.
1672 *****************************************************************************/
1673 void
SetThrottle(const fp throttle)1674 F16Aircraft::SetThrottle( const fp throttle )
1675 {
1676 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1677
1678 Parent::SetThrottle( throttle );
1679 // mSubgraphFlame0->Enable( throttle >= THROTTLE_FLAME_LOW ); // see-thru problem
1680 mSubgraphFlame1->Enable( throttle >= THROTTLE_FLAME_HIGH ); // afterburner
1681 }
1682
1683 /*****************************************************************************
1684 * Rotate control surfaces (ailerons etc).
1685 *****************************************************************************/
1686 void
RotateControlSurfaces(const uint axis,const fp controlFraction)1687 F16Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction )
1688 {
1689 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1690 ASSERT_AXIS3(axis);
1691
1692 switch ( axis )
1693 {
1694 case AXIS_PITCH:
1695 {
1696 RotateElevator( *mSubgraphElevatorLeft, controlFraction );
1697 RotateElevator( *mSubgraphElevatorRight, controlFraction );
1698 }
1699 break;
1700
1701 case AXIS_ROLL:
1702 {
1703 RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON );
1704 RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON );
1705 #if 0
1706 RotateAileron( *mSubgraphFlapLeft, controlFraction, LEFT_AILERON );
1707 RotateAileron( *mSubgraphFlapRight, controlFraction, RIGHT_AILERON );
1708 #endif
1709 }
1710 break;
1711
1712 case AXIS_YAW:
1713 {
1714 RotateRudder( *mSubgraphRudder0, controlFraction );
1715 RotateRudder( *mSubgraphRudder1, controlFraction );
1716 RotateRudder( *mSubgraphRudder2, controlFraction );
1717 RotateRudder( *mSubgraphRudder3, controlFraction );
1718 }
1719 break;
1720 }
1721 }
1722
1723 ////////////////////////////////////////////////////////////////////////////////
1724 /////////////////////////////// F18Aircraft //////////////////////////////////
1725 ////////////////////////////////////////////////////////////////////////////////
1726
1727 /*****************************************************************************
1728 * ctor/dtor.
1729 *****************************************************************************/
F18Aircraft(shptr<Graph> graph,const WorldVertex & pos)1730 F18Aircraft::F18Aircraft( shptr<Graph> graph, const WorldVertex& pos )
1731 : Parent(graph,pos,F18Aircraft::ClassGetSpecs()),
1732 // gear:
1733 mSubgraphGear0(new Subgraph(graph,"LeftWheel")),
1734 mSubgraphGear1(new Subgraph(graph,"LeftDoor")),
1735 mSubgraphGear2(new Subgraph(graph,"RightWheel")),
1736 mSubgraphGear3(new Subgraph(graph,"RightDoor")),
1737 mSubgraphGear4(new Subgraph(graph,"FrontWheel")),
1738 mSubgraphGear5(new Subgraph(graph,"FrontDoor")),
1739 // exhaust flame:
1740 mSubgraphFlame0(new Subgraph(graph,"InternalFlame")),
1741 mSubgraphFlame1(new Subgraph(graph,"ExternalFlame")),
1742 // control surfaces:
1743 mSubgraphAileronLeft(new Subgraph(graph,"AileronLeft")),
1744 mSubgraphAileronRight(new Subgraph(graph,"AileronRight")),
1745 mSubgraphElevatorLeft(new Subgraph(graph,"ElevatorLeft")),
1746 mSubgraphElevatorRight(new Subgraph(graph,"ElevatorRight")),
1747 mSubgraphRudderLeft(new Subgraph(graph,"RudderLeft")),
1748 mSubgraphRudderRight(new Subgraph(graph,"RudderRight"))
1749 {
1750 SetThrottle( 0.0f );
1751
1752 // Exhaust flame shouldn't cast shadows.
1753 ShadowSceneGraph::DisableShadows( mSubgraphFlame0->GetRootNode() );
1754 ShadowSceneGraph::DisableShadows( mSubgraphFlame1->GetRootNode() );
1755 }
1756
~F18Aircraft()1757 F18Aircraft::~F18Aircraft()
1758 {
1759 // NOP
1760 }
1761
1762 /*****************************************************************************
1763 * @return Aircraft specifications struct.
1764 *****************************************************************************/
1765 const AircraftSpecs&
GetSpecs(void)1766 F18Aircraft::GetSpecs( void ) // virtual method
1767 {
1768 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1769 return F18Aircraft::ClassGetSpecs();
1770 }
1771
1772 const AircraftSpecs&
ClassGetSpecs(void)1773 F18Aircraft::ClassGetSpecs( void ) // class method
1774 {
1775 CODE_CLASS_GET_SPECS( "physics_f18.conf" )
1776 }
1777
1778 /*****************************************************************************
1779 * Retract/extend landing gear.
1780 *****************************************************************************/
1781 void
SetLandingGear(const bool down)1782 F18Aircraft::SetLandingGear( const bool down )
1783 {
1784 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1785
1786 if ( IfCanSetLandingGear( down ) )
1787 {
1788 Parent::SetLandingGear( down );
1789
1790 mSubgraphGear0->Enable( down );
1791 mSubgraphGear1->Enable( down );
1792 mSubgraphGear2->Enable( down );
1793 mSubgraphGear3->Enable( down );
1794 mSubgraphGear4->Enable( down );
1795 mSubgraphGear5->Enable( down );
1796 }
1797 }
1798
1799 /*****************************************************************************
1800 * When throttle is changed, animate jet exhaust flame.
1801 *****************************************************************************/
1802 void
SetThrottle(const fp throttle)1803 F18Aircraft::SetThrottle( const fp throttle )
1804 {
1805 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1806
1807 Parent::SetThrottle( throttle );
1808 //mSubgraphFlame0->Enable( throttle >= THROTTLE_FLAME_LOW ); // see-thru problem
1809 mSubgraphFlame1->Enable( throttle >= THROTTLE_FLAME_HIGH ); // afterburner
1810 }
1811
1812 /*****************************************************************************
1813 * Rotate control surfaces (ailerons etc).
1814 *****************************************************************************/
1815 void
RotateControlSurfaces(const uint axis,const fp controlFraction)1816 F18Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction )
1817 {
1818 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1819 ASSERT_AXIS3(axis);
1820
1821 switch ( axis )
1822 {
1823 case AXIS_PITCH:
1824 {
1825 RotateElevator( *mSubgraphElevatorLeft, controlFraction );
1826 RotateElevator( *mSubgraphElevatorRight, controlFraction );
1827 }
1828 break;
1829
1830 case AXIS_ROLL:
1831 {
1832 RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON );
1833 RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON );
1834 }
1835 break;
1836
1837 case AXIS_YAW:
1838 {
1839 RotateRudder( *mSubgraphRudderLeft, controlFraction, LEFT_RUDDER );
1840 RotateRudder( *mSubgraphRudderRight, controlFraction, RIGHT_RUDDER );
1841 }
1842 break;
1843 }
1844 }
1845
1846 ////////////////////////////////////////////////////////////////////////////////
1847 /////////////////////////////// SR71Aircraft //////////////////////////////////
1848 ////////////////////////////////////////////////////////////////////////////////
1849
1850 /*****************************************************************************
1851 * ctor/dtor.
1852 *****************************************************************************/
SR71Aircraft(shptr<Graph> graph,const WorldVertex & pos)1853 SR71Aircraft::SR71Aircraft( shptr<Graph> graph, const WorldVertex& pos )
1854 : Parent(graph,pos,SR71Aircraft::ClassGetSpecs()),
1855 // gear:
1856 mSubgraphGear0(new Subgraph(graph,"roueA")), // roue means wheel in French
1857 mSubgraphGear1(new Subgraph(graph,"roueD")),
1858 mSubgraphGear2(new Subgraph(graph,"roueG")),
1859 // struts:
1860 mSubgraphStrut0(new Subgraph(graph,"axeA")),
1861 mSubgraphStrut1(new Subgraph(graph,"axeD")),
1862 mSubgraphStrut2(new Subgraph(graph,"axeG")),
1863 mSubgraphStrut3(new Subgraph(graph,"barrebasA")),
1864 mSubgraphStrut4(new Subgraph(graph,"barrebasD")),
1865 mSubgraphStrut5(new Subgraph(graph,"barrebasG")),
1866 mSubgraphStrut6(new Subgraph(graph,"barrehautA")),
1867 mSubgraphStrut7(new Subgraph(graph,"barrehautD")),
1868 mSubgraphStrut8(new Subgraph(graph,"barrehautG")),
1869 mSubgraphStrut9(new Subgraph(graph,"porteD1")),
1870 mSubgraphStrut10(new Subgraph(graph,"porteD2")),
1871 mSubgraphStrut11(new Subgraph(graph,"porteG1")),
1872 mSubgraphStrut12(new Subgraph(graph,"porteG2")),
1873 mSubgraphStrut13(new Subgraph(graph,"verrinA")),
1874 mSubgraphStrut14(new Subgraph(graph,"verrinD")),
1875 mSubgraphStrut15(new Subgraph(graph,"verrinG")),
1876 // parachute:
1877 mSubgraphParachute(new Subgraph(graph,"parachute")),
1878 // exhaust flame:
1879 mSubgraphFlame0(new Subgraph(graph,"flammeD1")),
1880 mSubgraphFlame1(new Subgraph(graph,"flammeD2")),
1881 mSubgraphFlame2(new Subgraph(graph,"flammeD3")),
1882 mSubgraphFlame3(new Subgraph(graph,"flammeG1")),
1883 mSubgraphFlame4(new Subgraph(graph,"flammeG2")),
1884 mSubgraphFlame5(new Subgraph(graph,"flammeG3")),
1885 // Control surfaces:
1886 mSubgraphAileronLeft(new Subgraph(graph,"aileronG")),
1887 mSubgraphAileronRight(new Subgraph(graph,"aileronD")),
1888 mSubgraphElevatorLeft(new Subgraph(graph,"profondeurG")),
1889 mSubgraphElevatorRight(new Subgraph(graph,"profondeurD"))
1890 // (rudder omitted)
1891 {
1892 SetThrottle( 0.0f );
1893
1894 // Exhaust flame shouldn't cast shadows.
1895 ShadowSceneGraph::DisableShadows( mSubgraphFlame0->GetRootNode() );
1896 ShadowSceneGraph::DisableShadows( mSubgraphFlame1->GetRootNode() );
1897 ShadowSceneGraph::DisableShadows( mSubgraphFlame2->GetRootNode() );
1898 ShadowSceneGraph::DisableShadows( mSubgraphFlame3->GetRootNode() );
1899 ShadowSceneGraph::DisableShadows( mSubgraphFlame4->GetRootNode() );
1900 ShadowSceneGraph::DisableShadows( mSubgraphFlame5->GetRootNode() );
1901
1902 mSubgraphParachute->Enable( false );
1903 }
1904
~SR71Aircraft()1905 SR71Aircraft::~SR71Aircraft()
1906 {
1907 // NOP
1908 }
1909
1910 /*****************************************************************************
1911 * @return Aircraft specifications struct.
1912 *****************************************************************************/
1913 const AircraftSpecs&
GetSpecs(void)1914 SR71Aircraft::GetSpecs( void ) // virtual method
1915 {
1916 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1917 return SR71Aircraft::ClassGetSpecs();
1918 }
1919
1920 const AircraftSpecs&
ClassGetSpecs(void)1921 SR71Aircraft::ClassGetSpecs( void ) // class method
1922 {
1923 CODE_CLASS_GET_SPECS( "physics_sr71.conf" )
1924 }
1925
1926 /*****************************************************************************
1927 * Retract/extend landing gear.
1928 *****************************************************************************/
1929 void
SetLandingGear(const bool down)1930 SR71Aircraft::SetLandingGear( const bool down )
1931 {
1932 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1933
1934 if ( IfCanSetLandingGear( down ))
1935 {
1936 Parent::SetLandingGear( down );
1937
1938 mSubgraphGear0->Enable( down );
1939 mSubgraphGear1->Enable( down );
1940 mSubgraphGear2->Enable( down );
1941
1942 mSubgraphStrut0->Enable( down );
1943 mSubgraphStrut1->Enable( down );
1944 mSubgraphStrut2->Enable( down );
1945 mSubgraphStrut3->Enable( down );
1946 mSubgraphStrut4->Enable( down );
1947 mSubgraphStrut5->Enable( down );
1948 mSubgraphStrut6->Enable( down );
1949 mSubgraphStrut7->Enable( down );
1950 mSubgraphStrut8->Enable( down );
1951 mSubgraphStrut9->Enable( down );
1952 mSubgraphStrut10->Enable( down );
1953 mSubgraphStrut11->Enable( down );
1954 mSubgraphStrut12->Enable( down );
1955 mSubgraphStrut13->Enable( down );
1956 mSubgraphStrut14->Enable( down );
1957 mSubgraphStrut15->Enable( down );
1958 }
1959 }
1960
1961 /*****************************************************************************
1962 * When throttle is changed, animate jet exhaust flame.
1963 *****************************************************************************/
1964 void
SetThrottle(const fp throttle)1965 SR71Aircraft::SetThrottle( const fp throttle )
1966 {
1967 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1968
1969 Parent::SetThrottle( throttle );
1970 const bool flame = (throttle >= THROTTLE_FLAME);
1971 mSubgraphFlame0->Enable( flame );
1972 mSubgraphFlame1->Enable( flame );
1973 mSubgraphFlame2->Enable( flame );
1974 mSubgraphFlame3->Enable( flame );
1975 mSubgraphFlame4->Enable( flame );
1976 mSubgraphFlame5->Enable( flame );
1977 }
1978
1979 /*****************************************************************************
1980 * Rotate control surfaces (ailerons etc).
1981 *****************************************************************************/
1982 void
RotateControlSurfaces(const uint axis,const fp controlFraction)1983 SR71Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction )
1984 {
1985 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
1986 ASSERT_AXIS3(axis);
1987
1988 switch ( axis )
1989 {
1990 case AXIS_PITCH:
1991 {
1992 RotateElevator( *mSubgraphElevatorLeft, controlFraction );
1993 RotateElevator( *mSubgraphElevatorRight, controlFraction );
1994 }
1995 break;
1996
1997 case AXIS_ROLL:
1998 {
1999 RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON );
2000 RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON );
2001 }
2002 break;
2003
2004 #if 0
2005 case AXIS_YAW:
2006 {
2007 RotateRudder( *mSubgraphRudder, controlFraction );
2008 }
2009 break;
2010 #endif
2011 }
2012 }
2013
2014 ////////////////////////////////////////////////////////////////////////////////
2015 //////////////////////////// Mirage2000Aircraft //////////////////////////////
2016 ////////////////////////////////////////////////////////////////////////////////
2017
2018 /*****************************************************************************
2019 * ctor/dtor.
2020 *****************************************************************************/
Mirage2000Aircraft(shptr<Graph> graph,const WorldVertex & pos)2021 Mirage2000Aircraft::Mirage2000Aircraft( shptr<Graph> graph, const WorldVertex& pos )
2022 : Parent(graph,pos,Mirage2000Aircraft::ClassGetSpecs()),
2023 // gear:
2024 mSubgraphGear0(new Subgraph(graph,"front_tire")),
2025 mSubgraphGear1(new Subgraph(graph,"front_wheel")),
2026 mSubgraphGear2(new Subgraph(graph,"front_door_fwd")),
2027 mSubgraphGear3(new Subgraph(graph,"left_wheel")),
2028 mSubgraphGear4(new Subgraph(graph,"left_tire")),
2029 mSubgraphGear5(new Subgraph(graph,"left_door")),
2030 mSubgraphGear6(new Subgraph(graph,"right_wheel")),
2031 mSubgraphGear7(new Subgraph(graph,"right_tire")),
2032 mSubgraphGear8(new Subgraph(graph,"right_door")),
2033 // exhaust flame:
2034 mSubgraphFlame0(new Subgraph(graph,"internal_flame")),
2035 mSubgraphFlame1(new Subgraph(graph,"external_flame")),
2036 // Control surfaces:
2037 mSubgraphAileronLeft(new Subgraph(graph,"VoletGauche")), // are elevators too
2038 mSubgraphAileronRight(new Subgraph(graph,"VoletDroit")),
2039 mSubgraphRudder(new Subgraph(graph,"rudder"))
2040 {
2041 SetThrottle( 0.0f );
2042
2043 // Exhaust flame shouldn't cast shadows.
2044 ShadowSceneGraph::DisableShadows( mSubgraphFlame0->GetRootNode() );
2045 ShadowSceneGraph::DisableShadows( mSubgraphFlame1->GetRootNode() );
2046 }
2047
~Mirage2000Aircraft()2048 Mirage2000Aircraft::~Mirage2000Aircraft()
2049 {
2050 // NOP
2051 }
2052
2053 /*****************************************************************************
2054 * @return Aircraft specifications struct.
2055 *****************************************************************************/
2056 const AircraftSpecs&
GetSpecs(void)2057 Mirage2000Aircraft::GetSpecs( void ) // virtual method
2058 {
2059 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
2060 return Mirage2000Aircraft::ClassGetSpecs();
2061 }
2062
2063 const AircraftSpecs&
ClassGetSpecs(void)2064 Mirage2000Aircraft::ClassGetSpecs( void ) // class method
2065 {
2066 CODE_CLASS_GET_SPECS( "physics_mirage2000.conf" )
2067 }
2068
2069 /*****************************************************************************
2070 * Retract/extend landing gear.
2071 *****************************************************************************/
2072 void
SetLandingGear(const bool down)2073 Mirage2000Aircraft::SetLandingGear( const bool down )
2074 {
2075 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
2076
2077 if ( IfCanSetLandingGear( down ))
2078 {
2079 Parent::SetLandingGear( down );
2080
2081 mSubgraphGear0->Enable( down );
2082 mSubgraphGear1->Enable( down );
2083 mSubgraphGear2->Enable( down );
2084 mSubgraphGear3->Enable( down );
2085 mSubgraphGear4->Enable( down );
2086 mSubgraphGear5->Enable( down );
2087 mSubgraphGear6->Enable( down );
2088 mSubgraphGear7->Enable( down );
2089 mSubgraphGear8->Enable( down );
2090 }
2091 }
2092
2093 /*****************************************************************************
2094 * When throttle is changed, animate jet exhaust flame.
2095 *****************************************************************************/
2096 void
SetThrottle(const fp throttle)2097 Mirage2000Aircraft::SetThrottle( const fp throttle )
2098 {
2099 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
2100
2101 Parent::SetThrottle( throttle );
2102 // mSubgraphFlame0->Enable( throttle >= THROTTLE_FLAME_LOW ); // see-thru problem
2103 mSubgraphFlame1->Enable( throttle >= THROTTLE_FLAME ); // afterburner
2104 }
2105
2106 /*****************************************************************************
2107 * Rotate control surfaces (ailerons etc).
2108 *****************************************************************************/
2109 void
RotateControlSurfaces(const uint axis,const fp controlFraction)2110 Mirage2000Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction )
2111 {
2112 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
2113 ASSERT_AXIS3(axis);
2114
2115 switch ( axis )
2116 {
2117 // On Mirage, ailerons are also elevators.
2118 case AXIS_PITCH:
2119 {
2120 RotateElevator( *mSubgraphAileronLeft, controlFraction );
2121 RotateElevator( *mSubgraphAileronRight, controlFraction );
2122 }
2123 break;
2124
2125 case AXIS_ROLL:
2126 {
2127 RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON );
2128 RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON );
2129 }
2130 break;
2131
2132 case AXIS_YAW:
2133 {
2134 RotateRudder( *mSubgraphRudder, controlFraction );
2135 }
2136 break;
2137 }
2138 }
2139
2140 ////////////////////////////////////////////////////////////////////////////////
2141 /////////////////////////////// SU37Aircraft /////////////////////////////////
2142 ////////////////////////////////////////////////////////////////////////////////
2143
2144 /*****************************************************************************
2145 * ctor/dtor.
2146 *****************************************************************************/
SU37Aircraft(shptr<Graph> graph,const WorldVertex & pos)2147 SU37Aircraft::SU37Aircraft( shptr<Graph> graph, const WorldVertex& pos )
2148 : Parent(graph,pos,SU37Aircraft::ClassGetSpecs()),
2149 // gear:
2150 mSubgraphGear0(new Subgraph(graph,"UC")), // under carriage
2151 // exhaust flame:
2152 mSubgraphFlame0(new Subgraph(graph,"L_Reheat")),
2153 mSubgraphFlame1(new Subgraph(graph,"R_Reheat")),
2154 // control surfaces:
2155 mSubgraphAileronLeft(new Subgraph(graph,"WNG_Left_Flaperon")),
2156 mSubgraphAileronRight(new Subgraph(graph,"WNG_Right_Flaperon")),
2157 mSubgraphElevatorLeft(new Subgraph(graph,"ELV_Elevon_Left")),
2158 mSubgraphElevatorRight(new Subgraph(graph,"ELV_Elevon_Right")),
2159 mSubgraphRudderLeft(new Subgraph(graph,"TF_Left_Rudder")),
2160 mSubgraphRudderRight(new Subgraph(graph,"TF_Right_Rudder"))
2161
2162 {
2163 SetThrottle( 0.0f );
2164
2165 // Exhaust flame shouldn't cast shadows.
2166 ShadowSceneGraph::DisableShadows( mSubgraphFlame0->GetRootNode() );
2167 ShadowSceneGraph::DisableShadows( mSubgraphFlame1->GetRootNode() );
2168 }
2169
~SU37Aircraft()2170 SU37Aircraft::~SU37Aircraft()
2171 {
2172 // NOP
2173 }
2174
2175 /*****************************************************************************
2176 * @return Aircraft specifications struct.
2177 *****************************************************************************/
2178 const AircraftSpecs&
GetSpecs(void)2179 SU37Aircraft::GetSpecs( void ) // virtual method
2180 {
2181 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
2182 return SU37Aircraft::ClassGetSpecs();
2183 }
2184
2185 const AircraftSpecs&
ClassGetSpecs(void)2186 SU37Aircraft::ClassGetSpecs( void ) // class method
2187 {
2188 CODE_CLASS_GET_SPECS( "physics_su37.conf" )
2189 }
2190
2191 /*****************************************************************************
2192 * Retract/extend landing gear.
2193 *****************************************************************************/
2194 void
SetLandingGear(const bool down)2195 SU37Aircraft::SetLandingGear( const bool down )
2196 {
2197 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
2198
2199 if ( IfCanSetLandingGear( down ))
2200 {
2201 Parent::SetLandingGear( down );
2202
2203 mSubgraphGear0->Enable( down );
2204 }
2205 }
2206
2207 /*****************************************************************************
2208 * When throttle is changed, animate jet exhaust flame.
2209 *****************************************************************************/
2210 void
SetThrottle(const fp throttle)2211 SU37Aircraft::SetThrottle( const fp throttle )
2212 {
2213 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
2214
2215 Parent::SetThrottle( throttle );
2216 const bool flame = (throttle >= THROTTLE_FLAME);
2217 mSubgraphFlame0->Enable( flame );
2218 mSubgraphFlame1->Enable( flame );
2219 }
2220
2221 /*****************************************************************************
2222 * Rotate control surfaces (ailerons etc).
2223 *****************************************************************************/
2224 void
RotateControlSurfaces(const uint axis,const fp controlFraction)2225 SU37Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction )
2226 {
2227 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
2228 ASSERT_AXIS3(axis);
2229
2230 switch ( axis )
2231 {
2232 case AXIS_PITCH:
2233 {
2234 RotateElevator( *mSubgraphElevatorLeft, controlFraction );
2235 RotateElevator( *mSubgraphElevatorRight, controlFraction );
2236 }
2237 break;
2238
2239 case AXIS_ROLL:
2240 {
2241 RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON );
2242 RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON );
2243 }
2244 break;
2245
2246 case AXIS_YAW:
2247 {
2248 RotateRudder( *mSubgraphRudderLeft, controlFraction, LEFT_RUDDER );
2249 RotateRudder( *mSubgraphRudderRight, controlFraction, RIGHT_RUDDER );
2250 }
2251 break;
2252 }
2253 }
2254
2255 ////////////////////////////////////////////////////////////////////////////////
2256 ////////////////////////// SpaceShuttleAircraft //////////////////////////////
2257 ////////////////////////////////////////////////////////////////////////////////
2258
2259 /*****************************************************************************
2260 * ctor/dtor.
2261 *****************************************************************************/
SpaceShuttleAircraft(shptr<Graph> graph,const WorldVertex & pos)2262 SpaceShuttleAircraft::SpaceShuttleAircraft( shptr<Graph> graph, const WorldVertex& pos )
2263 : Parent(graph,pos,SpaceShuttleAircraft::ClassGetSpecs()),
2264 mSubgraphBayDoorLeft(new Subgraph(graph,"bay_door_left")),
2265 mSubgraphBayDoorRight(new Subgraph(graph,"bay_door_right")),
2266 mBayDoorsFraction(0.0f)
2267 {
2268 // NOP
2269 }
2270
~SpaceShuttleAircraft()2271 SpaceShuttleAircraft::~SpaceShuttleAircraft()
2272 {
2273 // NOP
2274 }
2275
2276 /*****************************************************************************
2277 * Reset.
2278 *****************************************************************************/
2279 void
Reset(void)2280 SpaceShuttleAircraft::Reset( void )
2281 {
2282 Parent::Reset();
2283
2284 // Close bay doors.
2285 SwingBayDoors( 0.0f );
2286 }
2287
2288 /*****************************************************************************
2289 * @return Aircraft specifications struct.
2290 *****************************************************************************/
2291 const AircraftSpecs&
GetSpecs(void)2292 SpaceShuttleAircraft::GetSpecs( void ) // virtual method
2293 {
2294 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
2295
2296 return SpaceShuttleAircraft::ClassGetSpecs();
2297 }
2298
2299 const AircraftSpecs&
ClassGetSpecs(void)2300 SpaceShuttleAircraft::ClassGetSpecs( void ) // class method
2301 {
2302 CODE_CLASS_GET_SPECS( "physics_spaceShuttle.conf" )
2303 }
2304
2305 /*****************************************************************************
2306 * Really open bay doors.
2307 * Reason for this subterfuge is to reuse keyboard control for swinging wings.
2308 *****************************************************************************/
2309 void
SwingWings(const float fraction)2310 SpaceShuttleAircraft::SwingWings( const float fraction )
2311 {
2312 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
2313
2314 SwingBayDoors( fraction );
2315 }
2316
2317 /*****************************************************************************
2318 * Open bay doors { 0.0:closed ... 1.0:open }
2319 *****************************************************************************/
2320 void
SwingBayDoors(const float fraction)2321 SpaceShuttleAircraft::SwingBayDoors( const float fraction )
2322 {
2323 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
2324
2325 mBayDoorsFraction = Clamp1( fraction );
2326
2327 // Undo rotation/translation of wing subgraphs from previous call.
2328 mSubgraphBayDoorLeft->Reset();
2329 mSubgraphBayDoorRight->Reset();
2330
2331 // deg = 0 fully closed
2332 // deg = 70 fully open
2333 const Degree deg = mBayDoorsFraction * 70.0f;
2334 const Radian rad = Deg2Rad( deg );
2335
2336 // Translate to center the pivot at door hinges.
2337 fp offset0 = 0.03f;
2338 fp offset1 = 0.08f;
2339 mSubgraphBayDoorLeft->Translate( YY, offset0 ); // up
2340 mSubgraphBayDoorRight->Translate( YY, offset0 ); // up
2341 mSubgraphBayDoorLeft->Translate( XX, -offset1 ); // horz
2342 mSubgraphBayDoorRight->Translate( XX, offset1 ); // horz
2343
2344 mSubgraphBayDoorLeft->Rotate( ZZ, rad );
2345 mSubgraphBayDoorRight->Rotate( ZZ, -rad );
2346
2347 // Undo translation.
2348 offset0 = -offset0;
2349 offset1 = -offset1;
2350 mSubgraphBayDoorLeft->Translate( YY, offset0 ); // up
2351 mSubgraphBayDoorRight->Translate( YY, offset0 ); // up
2352 mSubgraphBayDoorLeft->Translate( XX, -offset1 ); // horz
2353 mSubgraphBayDoorRight->Translate( XX, offset1 ); // horz
2354 }
2355
2356 ////////////////////////////////////////////////////////////////////////////////
2357 //////////////////////////// SikorskyAircraft ////////////////////////////////
2358 ////////////////////////////////////////////////////////////////////////////////
2359
2360 /*****************************************************************************
2361 * ctor/dtor.
2362 *****************************************************************************/
SikorskyAircraft(shptr<Graph> graph,const WorldVertex & pos)2363 SikorskyAircraft::SikorskyAircraft( shptr<Graph> graph, const WorldVertex& pos )
2364 : Parent(graph,pos,SikorskyAircraft::ClassGetSpecs()),
2365 mSubgraphRotor0(new Subgraph(graph,"blade1")),
2366 mSubgraphRotor1(new Subgraph(graph,"blade2")),
2367 mSubgraphRotor2(new Subgraph(graph,"blade3")),
2368 mSubgraphRotor3(new Subgraph(graph,"blade4")),
2369 mSubgraphRotor4(new Subgraph(graph,"fastblade1")), // blurred
2370 mSubgraphRotor5(new Subgraph(graph,"fastblade2")), // blurred
2371 mSubgraphRotor6(new Subgraph(graph,"fastblade3")), // blurred
2372 mSubgraphRotor7(new Subgraph(graph,"fastblade4")), // blurred
2373 mSubgraphTailRotor(new Subgraph(graph,"TailRotor"))
2374 {
2375 // NOP
2376 }
2377
~SikorskyAircraft()2378 SikorskyAircraft::~SikorskyAircraft()
2379 {
2380 // NOP
2381 }
2382
2383 /*****************************************************************************
2384 * @return Aircraft specifications struct.
2385 *****************************************************************************/
2386 const AircraftSpecs&
GetSpecs(void)2387 SikorskyAircraft::GetSpecs( void ) // virtual method
2388 {
2389 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
2390
2391 return SikorskyAircraft::ClassGetSpecs();
2392 }
2393
2394 const AircraftSpecs&
ClassGetSpecs(void)2395 SikorskyAircraft::ClassGetSpecs( void ) // class method
2396 {
2397 CODE_CLASS_GET_SPECS( "physics_sikorsky.conf" )
2398 }
2399
2400 /*****************************************************************************
2401 * Tick that pulses animation.
2402 *****************************************************************************/
2403 void
Tick(const Milliseconds millisecElapsed)2404 SikorskyAircraft::Tick( const Milliseconds millisecElapsed )
2405 {
2406 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
2407
2408 Parent::Tick( millisecElapsed );
2409
2410 RotateRotors();
2411 }
2412
2413 /*****************************************************************************
2414 * Rotate propeller.
2415 *****************************************************************************/
2416 void
RotateRotors(void)2417 SikorskyAircraft::RotateRotors( void )
2418 {
2419 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
2420
2421 const uint axisRotor = YY; // main rotors
2422 // const uint axisTailRotor = ZZ;
2423 {
2424 const Radian radian = Deg2Rad( Degree(10.0f) );
2425 mSubgraphRotor0->Rotate( axisRotor, radian );
2426 mSubgraphRotor1->Rotate( axisRotor, radian );
2427 mSubgraphRotor2->Rotate( axisRotor, radian );
2428 mSubgraphRotor3->Rotate( axisRotor, radian );
2429 }
2430 {
2431 const Radian radian = Deg2Rad( Degree(5.0f) ); // blurred rotors
2432 mSubgraphRotor4->Rotate( axisRotor, radian );
2433 mSubgraphRotor5->Rotate( axisRotor, radian );
2434 mSubgraphRotor6->Rotate( axisRotor, radian );
2435 mSubgraphRotor7->Rotate( axisRotor, radian );
2436 }
2437
2438 // The origin of the tail rotor is the center of the helicopter
2439 // rather than the rotor's hub, so just toggle enablement.
2440 #if 1
2441 mSubgraphTailRotor->Enable( not mSubgraphTailRotor->IfEnabled() );
2442 #else
2443 {
2444 const Radian radian = Deg2Rad( Degree(30.0f) );
2445 mSubgraphTailRotor->Rotate( axisTailRotor, radian );
2446 }
2447 #endif
2448 }
2449
2450 /*****************************************************************************
2451 * Retract/extend landing gear.
2452 *****************************************************************************/
2453 void
SetLandingGear(const bool down)2454 SikorskyAircraft::SetLandingGear( const bool down )
2455 {
2456 CHECK_TYPESIG(this,TYPESIG_AIRCRAFT);
2457
2458 if ( IfCanSetLandingGear( down ) )
2459 {
2460 Parent::SetLandingGear( down );
2461
2462 Parent::mLandingGearDown = true; // override
2463 }
2464 }
2465
2466 } // namespace program
2467