/***************************************************************************** * $LastChangedDate: 2010-06-24 10:22:48 -0400 (Thu, 24 Jun 2010) $ * @file * @author Jim E. Brooks http://www.palomino3d.org * @brief Aircraft classes. *//* * LEGAL: COPYRIGHT (C) 2007 JIM E. BROOKS * THIS SOURCE CODE IS RELEASED UNDER THE TERMS * OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2). *****************************************************************************/ // Enable this when editing an aircraft model's control surfaces. // This causes the spec file to be reloaded continually after being edited. #if DEBUG //#define COMPILE_EDITING_MODEL 1 #endif #define PROGRAM_AIRCRAFT_CC 1 #include "base/module.hh" using namespace base; #include "math/module.hh" #include "math/funcs_trig.hh" #include "math/funcs_vector.hh" using namespace math; #include "gfx/module.hh" using namespace gfx; #include "graph/module.hh" #include "graph/subgraph.hh" #include "graph/shadow_scene_graph.hh" using namespace graph; #include "object/module.hh" #include "object/aircraft.hh" using namespace object; #include "control/module.hh" #include "control/defs_axis.hh" using namespace control; #include "physics/module.hh" using namespace physics; #include "program/module.hh" #include "program/aircraft_models.hh" namespace program { INTERN const fp THROTTLE_PROPELLER = 0.2f; // when propeller begins to spin INTERN const fp THROTTLE_FLAME_LOW = 0.3f; // most models lack this INTERN const fp THROTTLE_FLAME_HIGH = 0.7f; INTERN const fp THROTTLE_FLAME = THROTTLE_FLAME_HIGH; INTERN const fp F14_AILERONS_ACTIVE_SWING_WINGS = 0.75f; //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// functions //////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// #if COMPILE_EDITING_MODEL #define CODE_CLASS_GET_SPECS( CONF_FILENAME ) \ { \ BEGIN_ONCE { \ CDEBUG << "Note: COMPILE_EDITING_MODEL enabled (slows program)" << endl;\ } END_ONCE \ \ /* Reload every time. */ \ PERSISTENT AircraftSpecs sAircraftSpecs; \ sAircraftSpecs.ReadSpecsFromConfFile( CONF_FILENAME ); \ return sAircraftSpecs; \ } #else #define CODE_CLASS_GET_SPECS( CONF_FILENAME ) \ { \ /* Load specs from a .conf file once. */ \ PERSISTENT AircraftSpecs sAircraftSpecs; \ BEGIN_ONCE { \ sAircraftSpecs.ReadSpecsFromConfFile( CONF_FILENAME ); \ } END_ONCE \ return sAircraftSpecs; \ } #endif /***************************************************************************** * Make specified kind of aircraft. * Some 3D models were defined with its center at the nose. * physics_*.conf redefines an offset. * @param aircraftType * @param pos * @param loadCopy * Pass ModelCache::LOAD_SHARED or LOAD_COPY. * To save memory, pass false for dummy (non-dynamic) aircraft * such as those parked on the carrier. *****************************************************************************/ shptr MakeAircraft( eAircraftType aircraftType, const WorldVertex& pos, const bool loadCopy ) { shptr0 aircraft = NULL; shptr0 graph = NULL; #define MAKE_AIRCRAFT( CLASS ) \ { \ graph = Aircraft::LoadModel( CLASS::ClassGetSpecs(), loadCopy ).PTR(); \ aircraft = new CLASS( graph.PTR(), pos ); \ } switch ( aircraftType ) { case eAircraftType_Spitfire: { MAKE_AIRCRAFT( SpitfireAircraft ); } break; case eAircraftType_Corsair: { MAKE_AIRCRAFT( CorsairAircraft ); } break; case eAircraftType_P51: { MAKE_AIRCRAFT( P51Aircraft ); } break; case eAircraftType_F82: { MAKE_AIRCRAFT( F82Aircraft ); } break; case eAircraftType_F86: { MAKE_AIRCRAFT( F86Aircraft ); } break; case eAircraftType_A4: { MAKE_AIRCRAFT( A4Aircraft ); } break; case eAircraftType_F14: { MAKE_AIRCRAFT( F14Aircraft ); } break; case eAircraftType_F15: { MAKE_AIRCRAFT( F15Aircraft ); } break; case eAircraftType_F16: { MAKE_AIRCRAFT( F16Aircraft ); } break; case eAircraftType_F18: { MAKE_AIRCRAFT( F18Aircraft ); } break; case eAircraftType_SR71: { MAKE_AIRCRAFT( SR71Aircraft ); } break; case eAircraftType_Mirage2000: { MAKE_AIRCRAFT( Mirage2000Aircraft ); } break; case eAircraftType_SU37: { MAKE_AIRCRAFT( SU37Aircraft ); } break; case eAircraftType_Sikorsky: { MAKE_AIRCRAFT( SikorskyAircraft ); } break; case eAircraftType_SpaceShuttle: { MAKE_AIRCRAFT( SpaceShuttleAircraft ); } break; default: { ASSERT(0); // oops } break; } // Return Aircraft. return aircraft.PTR(); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////// SpitfireAircraft //////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /***************************************************************************** * ctor/dtor. *****************************************************************************/ SpitfireAircraft::SpitfireAircraft( shptr graph, const WorldVertex& pos ) : Parent(graph,pos,SpitfireAircraft::ClassGetSpecs()), mSubgraphPropeller1(new Subgraph(graph,"Propeller1")), mSubgraphPropeller2(new Subgraph(graph,"Propeller2")), mSubgraphPropeller3(new Subgraph(graph,"Propeller3")), mSubgraphPropeller4(new Subgraph(graph,"Propeller4")), mSubgraphPropellerDisc(new Subgraph(graph,"noshadow.PropellerDisk")), // transparent mSubgraphGear0(new Subgraph(graph,"Leg-Assembly-L")), mSubgraphGear1(new Subgraph(graph,"Leg-Assembly-R")), mSubgraphGear2(new Subgraph(graph,"Tail-Wheel-Assembly")), // mSubgraphAileronLeft(new Subgraph(graph,"Aileron-T")), mSubgraphAileronRight(new Subgraph(graph,"Aileron-T.001")), mSubgraphElevatorLeft(new Subgraph(graph,"Elevator-T.001")), mSubgraphElevatorRight(new Subgraph(graph,"Elevator-T")), mSubgraphRudder(new Subgraph(graph,"Rudder")) { ShadowSceneGraph::DisableShadows( mSubgraphPropellerDisc->GetRootNode() ); } SpitfireAircraft::~SpitfireAircraft() { // NOP } /***************************************************************************** * @return Aircraft specifications struct. *****************************************************************************/ const AircraftSpecs& SpitfireAircraft::GetSpecs( void ) // virtual method { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); return SpitfireAircraft::ClassGetSpecs(); } const AircraftSpecs& SpitfireAircraft::ClassGetSpecs( void ) // class method { CODE_CLASS_GET_SPECS( "physics_spitfire.conf" ) } /***************************************************************************** * Tick that pulses animation. *****************************************************************************/ void SpitfireAircraft::Tick( const Milliseconds millisecElapsed ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); Parent::Tick( millisecElapsed ); RotatePropeller(); } /***************************************************************************** * Rotate propeller. *****************************************************************************/ // Rotate both propeller Groups. void SpitfireAircraft::RotatePropeller( void ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); // Degree of rotation correlates to throttle. const Degree degree = 35.0f * GetThrottle(); const Radian radian = Deg2Rad( -degree ); mSubgraphPropeller1->Rotate( XX, radian ); mSubgraphPropeller2->Rotate( XX, radian ); mSubgraphPropeller3->Rotate( XX, radian ); mSubgraphPropeller4->Rotate( XX, radian ); } /***************************************************************************** * Retract/extend landing gear. *****************************************************************************/ void SpitfireAircraft::SetLandingGear( const bool down ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); if ( IfCanSetLandingGear( down ) ) { Parent::SetLandingGear( down ); mSubgraphGear0->Enable( down ); mSubgraphGear1->Enable( down ); mSubgraphGear2->Enable( down ); } } /***************************************************************************** * When throttle is increased, spin propeller. *****************************************************************************/ void SpitfireAircraft::SetThrottle( const fp throttle ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); Parent::SetThrottle( throttle ); mSubgraphPropellerDisc->Enable( throttle >= THROTTLE_PROPELLER ); // disable transparent disc } /***************************************************************************** * Rotate control surfaces (ailerons etc). *****************************************************************************/ void SpitfireAircraft::RotateControlSurfaces( const uint axis, const fp controlFraction ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); ASSERT_AXIS3(axis); switch ( axis ) { case AXIS_PITCH: { RotateElevator( *mSubgraphElevatorLeft, controlFraction ); RotateElevator( *mSubgraphElevatorRight, controlFraction ); } break; case AXIS_ROLL: { RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON ); RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON ); } break; case AXIS_YAW: { RotateRudder( *mSubgraphRudder, controlFraction ); } break; } } //////////////////////////////////////////////////////////////////////////////// ///////////////////////////// CorsairAircraft //////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /***************************************************************************** * ctor/dtor. *****************************************************************************/ CorsairAircraft::CorsairAircraft( shptr graph, const WorldVertex& pos ) : Parent(graph,pos,CorsairAircraft::ClassGetSpecs()), mSubgraphPropeller0(new Subgraph(graph,"prop_0")), mSubgraphPropeller1(new Subgraph(graph,"prop_1")), mSubgraphGear0(new Subgraph(graph,"gearp2.L")), mSubgraphGear1(new Subgraph(graph,"gearp2.R")), mSubgraphGear2(new Subgraph(graph,"gearp3.L")), mSubgraphGear3(new Subgraph(graph,"gearp3.R")), mSubgraphGear4(new Subgraph(graph,"gearcylinder.L")), mSubgraphGear5(new Subgraph(graph,"gearcylinder.R")), mSubgraphGear6(new Subgraph(graph,"gearleg.L")), mSubgraphGear7(new Subgraph(graph,"gearleg.R")), mSubgraphGear8(new Subgraph(graph,"gearleg2.L")), mSubgraphGear9(new Subgraph(graph,"gearleg2.R")), mSubgraphGear10(new Subgraph(graph,"gearp1.L")), mSubgraphGear11(new Subgraph(graph,"gearp1.R")), mSubgraphGear12(new Subgraph(graph,"gearsc1.L")), mSubgraphGear13(new Subgraph(graph,"gearsc2.L")), mSubgraphGear14(new Subgraph(graph,"tailgear1")), mSubgraphGear15(new Subgraph(graph,"tailgear2")), mSubgraphGear16(new Subgraph(graph,"stopwheel.L")), mSubgraphGear17(new Subgraph(graph,"stopwheel.R")), mSubgraphGear18(new Subgraph(graph,"wheel.L")), mSubgraphGear19(new Subgraph(graph,"wheel.R")), mSubgraphGear20(new Subgraph(graph,"tailwheel")), // Control surfaces: mSubgraphAileronLeft(new Subgraph(graph,"aileron.L")), mSubgraphAileronRight(new Subgraph(graph,"aileron.R")), mSubgraphElevatorLeft(new Subgraph(graph,"elevator.L")), mSubgraphElevatorRight(new Subgraph(graph,"elevator.R")), mSubgraphRudder(new Subgraph(graph,"rudder")) { // NOP } CorsairAircraft::~CorsairAircraft() { // NOP } /***************************************************************************** * @return Aircraft specifications struct. *****************************************************************************/ const AircraftSpecs& CorsairAircraft::GetSpecs( void ) // virtual method { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); return CorsairAircraft::ClassGetSpecs(); } const AircraftSpecs& CorsairAircraft::ClassGetSpecs( void ) // class method { CODE_CLASS_GET_SPECS( "physics_corsair.conf" ) } /***************************************************************************** * Tick that pulses animation. *****************************************************************************/ void CorsairAircraft::Tick( const Milliseconds millisecElapsed ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); Parent::Tick( millisecElapsed ); RotatePropeller(); } /***************************************************************************** * Rotate propeller. *****************************************************************************/ void CorsairAircraft::RotatePropeller( void ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); // Degree of rotation correlates to throttle. const Degree degree = 35.0f * GetThrottle(); const Radian radian = Deg2Rad( -degree ); mSubgraphPropeller0->Rotate( XX, radian ); mSubgraphPropeller1->Rotate( XX, radian ); } /***************************************************************************** * Retract/extend landing gear. *****************************************************************************/ void CorsairAircraft::SetLandingGear( const bool down ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); if ( IfCanSetLandingGear( down ) ) { Parent::SetLandingGear( down ); mSubgraphGear0->Enable( down ); mSubgraphGear1->Enable( down ); mSubgraphGear2->Enable( down ); mSubgraphGear3->Enable( down ); mSubgraphGear4->Enable( down ); mSubgraphGear5->Enable( down ); mSubgraphGear6->Enable( down ); mSubgraphGear7->Enable( down ); mSubgraphGear8->Enable( down ); mSubgraphGear9->Enable( down ); mSubgraphGear10->Enable( down ); mSubgraphGear11->Enable( down ); mSubgraphGear12->Enable( down ); mSubgraphGear13->Enable( down ); mSubgraphGear14->Enable( down ); mSubgraphGear15->Enable( down ); mSubgraphGear16->Enable( down ); mSubgraphGear17->Enable( down ); mSubgraphGear18->Enable( down ); mSubgraphGear19->Enable( down ); mSubgraphGear20->Enable( down ); } } /***************************************************************************** * Rotate control surfaces (ailerons etc). *****************************************************************************/ void CorsairAircraft::RotateControlSurfaces( const uint axis, const fp controlFraction ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); ASSERT_AXIS3(axis); switch ( axis ) { case AXIS_PITCH: { RotateElevator( *mSubgraphElevatorLeft, controlFraction ); RotateElevator( *mSubgraphElevatorRight, controlFraction ); } break; case AXIS_ROLL: { RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON ); RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON ); } break; case AXIS_YAW: { RotateRudder( *mSubgraphRudder, controlFraction ); } break; } } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// P51Aircraft ////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /***************************************************************************** * ctor/dtor. *****************************************************************************/ P51Aircraft::P51Aircraft( shptr graph, const WorldVertex& pos ) : Parent(graph,pos,P51Aircraft::ClassGetSpecs()), mSubgraphPropeller1(new Subgraph(graph,"Propeller1")), mSubgraphPropeller2(new Subgraph(graph,"Propeller2")), // mSubgraphLeftGearWheel(new Subgraph(graph,"LeftGearWheel")), mSubgraphLeftGearStrut(new Subgraph(graph,"LeftGearStrut")), mSubgraphLeftInnerGearCover(new Subgraph(graph,"LeftInnerGearCover")), mSubgraphLeftOuterGearCover(new Subgraph(graph,"LeftOuterGearCover")), mSubgraphLeftTailGearDoor(new Subgraph(graph,"LeftTailGearDoor")), // mSubgraphRightGearWheel(new Subgraph(graph,"RightGearWheel")), mSubgraphRightGearStrut(new Subgraph(graph,"RightGearStrut")), mSubgraphRightInnerGearCover(new Subgraph(graph,"RightInnerGearCover")), mSubgraphRightOuterGearCover(new Subgraph(graph,"RightOuterGearCover")), mSubgraphRightTailGearDoor(new Subgraph(graph,"RightTailGearDoor")), // mSubgraphTailGearWheel(new Subgraph(graph,"TailGearWheel")), mSubgraphTailGearStrut(new Subgraph(graph,"TailGearStrut")), // mSubgraphAileronLeft(new Subgraph(graph,"LeftAileron")), mSubgraphAileronRight(new Subgraph(graph,"RightAileron")), mSubgraphElevatorLeft(new Subgraph(graph,"LeftElevator")), mSubgraphElevatorRight(new Subgraph(graph,"RightElevator")), mSubgraphRudder(new Subgraph(graph,"Rudder")), // mSubgraphJunk0(new Subgraph(graph,"TailNavLightOff")), mSubgraphJunk1(new Subgraph(graph,"TailNavLightOn")) { // Disable junk parts. mSubgraphJunk0->Enable( false ); mSubgraphJunk1->Enable( false ); } P51Aircraft::~P51Aircraft() { // NOP } /***************************************************************************** * @return Aircraft specifications struct. *****************************************************************************/ const AircraftSpecs& P51Aircraft::GetSpecs( void ) // virtual method { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); return P51Aircraft::ClassGetSpecs(); } const AircraftSpecs& P51Aircraft::ClassGetSpecs( void ) // class method { CODE_CLASS_GET_SPECS( "physics_p51.conf" ) } /***************************************************************************** * Tick that pulses animation. *****************************************************************************/ void P51Aircraft::Tick( const Milliseconds millisecElapsed ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); Parent::Tick( millisecElapsed ); RotatePropeller(); } /***************************************************************************** * Rotate propeller. *****************************************************************************/ void P51Aircraft::RotatePropeller( void ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); // Rotate both propeller Groups. // Degree of rotation correlates to throttle. const Degree degree = 35.0f * GetThrottle(); const Radian radian = Deg2Rad( -degree ); mSubgraphPropeller1->Rotate( XX, radian ); // this p51d-jw model splits propeller mSubgraphPropeller2->Rotate( XX, radian ); // into two subgraphs } /***************************************************************************** * Retract/extend landing gear. *****************************************************************************/ void P51Aircraft::SetLandingGear( const bool down ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); // The p51d-nw model apparently defines the origin of the landing gear // at the center of the fuselage instead of the strut pivot. // For now, just disable the nodes instead of doing rotation. if ( IfCanSetLandingGear( down ) ) { Parent::SetLandingGear( down ); mSubgraphLeftGearWheel->Enable( down ); mSubgraphLeftGearStrut->Enable( down ); mSubgraphLeftInnerGearCover->Enable( down ); mSubgraphLeftOuterGearCover->Enable( down ); mSubgraphLeftTailGearDoor->Enable( down ); mSubgraphRightGearWheel->Enable( down ); mSubgraphRightGearStrut->Enable( down ); mSubgraphRightInnerGearCover->Enable( down ); mSubgraphRightOuterGearCover->Enable( down ); mSubgraphRightTailGearDoor->Enable( down ); mSubgraphTailGearWheel->Enable( down ); mSubgraphTailGearStrut->Enable( down ); } } /***************************************************************************** * Rotate control surfaces (ailerons etc). *****************************************************************************/ void P51Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); ASSERT_AXIS3(axis); switch ( axis ) { case AXIS_PITCH: { RotateElevator( *mSubgraphElevatorLeft, controlFraction ); RotateElevator( *mSubgraphElevatorRight, controlFraction ); } break; case AXIS_ROLL: { RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON ); RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON ); } break; case AXIS_YAW: { RotateRudder( *mSubgraphRudder, controlFraction ); } break; } } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// F82Aircraft ////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /***************************************************************************** * ctor/dtor. *****************************************************************************/ F82Aircraft::F82Aircraft( shptr graph, const WorldVertex& pos ) : Parent(graph,pos,F82Aircraft::ClassGetSpecs()), mSubgraphPropeller1(new Subgraph(graph,"Propeller1")), mSubgraphPropeller2(new Subgraph(graph,"Propeller2")), mSubgraphPropeller3(new Subgraph(graph,"Propeller1.002")), mSubgraphPropeller4(new Subgraph(graph,"Propeller2.001")), // mSubgraphLeftGearWheel(new Subgraph(graph,"LeftGearWheel")), mSubgraphLeftGearStrut(new Subgraph(graph,"LeftGearStrut")), mSubgraphLeftInnerGearCover(new Subgraph(graph,"LeftInnerGearCover")), mSubgraphLeftInnerGearCover2(new Subgraph(graph,"LeftInnerGearCove")), // sic/truncation mSubgraphLeftOuterGearCover(new Subgraph(graph,"LeftOuterGearCover")), mSubgraphLeftTailGearDoor(new Subgraph(graph,"LeftTailGearDoor")), // mSubgraphRightGearWheel(new Subgraph(graph,"RightGearWheel")), mSubgraphRightGearStrut(new Subgraph(graph,"RightGearStrut")), mSubgraphRightInnerGearCover(new Subgraph(graph,"RightInnerGearCover")), mSubgraphRightInnerGearCover2(new Subgraph(graph,"RightInnerGearCov")), // sic/truncation mSubgraphRightOuterGearCover(new Subgraph(graph,"RightOuterGearCover")), mSubgraphRightTailGearDoor(new Subgraph(graph,"RightTailGearDoor")), // mSubgraphTailGearWheel(new Subgraph(graph,"TailGearWheel")), mSubgraphTailGearStrut(new Subgraph(graph,"TailGearStrut")), mSubgraphTailGearWheel2(new Subgraph(graph,"TailGearWheel.001")), mSubgraphTailGearStrut2(new Subgraph(graph,"TailGearStrut.001")), // mSubgraphAileronLeft(new Subgraph(graph,"LeftAileron")), mSubgraphAileronRight(new Subgraph(graph,"RightAileron")), mSubgraphElevator(new Subgraph(graph,"LeftElevator.001")), // misnomer mSubgraphRudderLeft(new Subgraph(graph,"Rudder")), mSubgraphRudderRight(new Subgraph(graph,"Rudder.001")), // mSubgraphJunk0(new Subgraph(graph,"TailNavLightOff")), mSubgraphJunk1(new Subgraph(graph,"TailNavLightOn")) { // Disable junk parts. mSubgraphJunk0->Enable( false ); mSubgraphJunk1->Enable( false ); } F82Aircraft::~F82Aircraft() { // NOP } /***************************************************************************** * @return Aircraft specifications struct. *****************************************************************************/ const AircraftSpecs& F82Aircraft::GetSpecs( void ) // virtual method { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); return F82Aircraft::ClassGetSpecs(); } const AircraftSpecs& F82Aircraft::ClassGetSpecs( void ) // class method { CODE_CLASS_GET_SPECS( "physics_f82.conf" ) } /***************************************************************************** * Tick that pulses animation. *****************************************************************************/ void F82Aircraft::Tick( const Milliseconds millisecElapsed ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); Parent::Tick( millisecElapsed ); RotatePropeller(); } /***************************************************************************** * Rotate propeller. *****************************************************************************/ void F82Aircraft::TranslatePropeller( const fp dir ) { // In the F-82 model, the origin of the two propellers aren't centered correctly. // This C++ code temporarily shifts the matrix origin. // // Using constants for translation is ok as they are scaled // by the matrix scale set in the Object's Graph. const uint outwardAxis = ZZ; const fp outwardTrans = dir * 1.875f; // constant ok mSubgraphPropeller1->Translate( outwardAxis, outwardTrans ); mSubgraphPropeller2->Translate( outwardAxis, outwardTrans ); mSubgraphPropeller3->Translate( outwardAxis, -outwardTrans ); mSubgraphPropeller4->Translate( outwardAxis, -outwardTrans ); const uint upwardAxis = YY; const fp upwardTrans = dir * 0.1f; // constant ok mSubgraphPropeller1->Translate( upwardAxis, upwardTrans ); mSubgraphPropeller2->Translate( upwardAxis, upwardTrans ); mSubgraphPropeller3->Translate( upwardAxis, upwardTrans ); mSubgraphPropeller4->Translate( upwardAxis, upwardTrans ); } void F82Aircraft::RotatePropeller( void ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); // Rotate both propeller Groups. // Degree of rotation correlates to throttle. const Degree degree = 35.0f * GetThrottle(); const Radian radian = Deg2Rad( -degree ); TranslatePropeller( 1.0f ); mSubgraphPropeller1->Rotate( XX, radian ); // the p51d-jw model splits propeller mSubgraphPropeller2->Rotate( XX, radian ); // into 2 subgraphs so the F-82 model has 4 mSubgraphPropeller3->Rotate( XX, radian ); mSubgraphPropeller4->Rotate( XX, radian ); TranslatePropeller( -1.0f ); // undo translation } /***************************************************************************** * Retract/extend landing gear. *****************************************************************************/ void F82Aircraft::SetLandingGear( const bool down ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); // The model apparently defines the origin of the landing gear // at the center of the fuselage instead of the strut pivot. // For now, just disable the nodes instead of doing rotation. if ( IfCanSetLandingGear( down ) ) { Parent::SetLandingGear( down ); mSubgraphLeftGearWheel->Enable( down ); mSubgraphLeftGearStrut->Enable( down ); mSubgraphLeftInnerGearCover->Enable( down ); mSubgraphLeftInnerGearCover2->Enable( down ); mSubgraphLeftOuterGearCover->Enable( down ); mSubgraphLeftTailGearDoor->Enable( down ); mSubgraphRightGearWheel->Enable( down ); mSubgraphRightGearStrut->Enable( down ); mSubgraphRightInnerGearCover->Enable( down ); mSubgraphRightInnerGearCover2->Enable( down ); mSubgraphRightOuterGearCover->Enable( down ); mSubgraphRightTailGearDoor->Enable( down ); mSubgraphTailGearWheel->Enable( down ); mSubgraphTailGearStrut->Enable( down ); mSubgraphTailGearWheel2->Enable( down ); mSubgraphTailGearStrut2->Enable( down ); } } /***************************************************************************** * Rotate control surfaces (ailerons etc). *****************************************************************************/ void F82Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); ASSERT_AXIS3(axis); switch ( axis ) { case AXIS_PITCH: { RotateElevator( *mSubgraphElevator, controlFraction ); } break; case AXIS_ROLL: { RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON ); RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON ); } break; case AXIS_YAW: { RotateRudder( *mSubgraphRudderLeft, controlFraction, LEFT_RUDDER ); RotateRudder( *mSubgraphRudderRight, controlFraction, RIGHT_RUDDER ); } break; } } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// F86Aircraft ////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /***************************************************************************** * ctor/dtor. *****************************************************************************/ F86Aircraft::F86Aircraft( shptr graph, const WorldVertex& pos ) : Parent(graph,pos,F86Aircraft::ClassGetSpecs()), mSubgraphGear0(new Subgraph(graph,"nosegear1")), mSubgraphGear1(new Subgraph(graph,"nosewheel")), mSubgraphGear2(new Subgraph(graph,"gear.L")), mSubgraphGear3(new Subgraph(graph,"gear.R")), mSubgraphGear4(new Subgraph(graph,"wheel.L")), mSubgraphGear5(new Subgraph(graph,"wheel.R")), // Control surfaces: mSubgraphAileronLeft(new Subgraph(graph,"aileron.L")), mSubgraphAileronRight(new Subgraph(graph,"aileron.R")), mSubgraphElevatorLeft(new Subgraph(graph,"elevator.L")), mSubgraphElevatorRight(new Subgraph(graph,"elevator.R")), mSubgraphRudder(new Subgraph(graph,"rudder_1")) // (no flame) { SetThrottle( 0.0f ); } F86Aircraft::~F86Aircraft() { // NOP } /***************************************************************************** * @return Aircraft specifications struct. *****************************************************************************/ const AircraftSpecs& F86Aircraft::GetSpecs( void ) // virtual method { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); return F86Aircraft::ClassGetSpecs(); } const AircraftSpecs& F86Aircraft::ClassGetSpecs( void ) // class method { CODE_CLASS_GET_SPECS( "physics_f86.conf" ) } /***************************************************************************** * Retract/extend landing gear. *****************************************************************************/ void F86Aircraft::SetLandingGear( const bool down ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); if ( IfCanSetLandingGear( down ) ) { Parent::SetLandingGear( down ); mSubgraphGear0->Enable( down ); mSubgraphGear1->Enable( down ); mSubgraphGear2->Enable( down ); mSubgraphGear3->Enable( down ); mSubgraphGear4->Enable( down ); mSubgraphGear5->Enable( down ); } } /***************************************************************************** * Rotate control surfaces (ailerons etc). *****************************************************************************/ void F86Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); ASSERT_AXIS3(axis); switch ( axis ) { case AXIS_PITCH: { RotateElevator( *mSubgraphElevatorLeft, controlFraction ); RotateElevator( *mSubgraphElevatorRight, controlFraction ); } break; case AXIS_ROLL: { RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON ); RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON ); } break; case AXIS_YAW: { RotateRudder( *mSubgraphRudder, controlFraction ); } break; } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////// A4Aircraft ////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /***************************************************************************** * ctor/dtor. *****************************************************************************/ A4Aircraft::A4Aircraft( shptr graph, const WorldVertex& pos ) : Parent(graph,pos,A4Aircraft::ClassGetSpecs()), mSubgraphGear0(new Subgraph(graph,"LeftWheel")), mSubgraphGear1(new Subgraph(graph,"LeftLowerLeg")), mSubgraphGear2(new Subgraph(graph,"LeftUpperLeg")), mSubgraphGear3(new Subgraph(graph,"LeftGearDoor")), mSubgraphGear4(new Subgraph(graph,"LeftGearStrut")), mSubgraphGear5(new Subgraph(graph,"LeftLowerLegAssmbly")), mSubgraphGear6(new Subgraph(graph,"RightWheel")), mSubgraphGear7(new Subgraph(graph,"RightLowerLeg")), mSubgraphGear8(new Subgraph(graph,"RightUpperLeg")), mSubgraphGear9(new Subgraph(graph,"RightGearDoor")), mSubgraphGear10(new Subgraph(graph,"RightGearStrut")), mSubgraphGear11(new Subgraph(graph,"RightLowerLegAssmbly")), mSubgraphGear12(new Subgraph(graph,"LandingLight")), // unique to left wheel mSubgraphGear13(new Subgraph(graph,"NoseWheel")), // front wheel mSubgraphGear14(new Subgraph(graph,"Upper-Leg-Nose")), // front wheel mSubgraphGear15(new Subgraph(graph,"Lower-Leg")), // front wheel mSubgraphGear16(new Subgraph(graph,"NoseGearStrut")), // front wheel mSubgraphGear17(new Subgraph(graph,"NoseGearDoor")), // front wheel // Control surfaces: // This model lacks real ailerons. mSubgraphAileronLeft(new Subgraph(graph,"LeftSpoiler")), mSubgraphAileronRight(new Subgraph(graph,"RightSpoiler")), mSubgraphAileronLeft2(new Subgraph(graph,"LeftFlap-New")), mSubgraphAileronRight2(new Subgraph(graph,"RightFlap-New")), mSubgraphElevatorLeft(new Subgraph(graph,"LeftElevator")), mSubgraphElevatorRight(new Subgraph(graph,"RightElevator")), mSubgraphRudder(new Subgraph(graph,"Rudder")) // (no flame) { SetThrottle( 0.0f ); } A4Aircraft::~A4Aircraft() { // NOP } /***************************************************************************** * @return Aircraft specifications struct. *****************************************************************************/ const AircraftSpecs& A4Aircraft::GetSpecs( void ) // virtual method { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); return A4Aircraft::ClassGetSpecs(); } const AircraftSpecs& A4Aircraft::ClassGetSpecs( void ) // class method { CODE_CLASS_GET_SPECS( "physics_a4.conf" ) } /***************************************************************************** * Retract/extend landing gear. *****************************************************************************/ void A4Aircraft::SetLandingGear( const bool down ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); if ( IfCanSetLandingGear( down ) ) { Parent::SetLandingGear( down ); mSubgraphGear0->Enable( down ); mSubgraphGear1->Enable( down ); mSubgraphGear2->Enable( down ); mSubgraphGear3->Enable( down ); mSubgraphGear4->Enable( down ); mSubgraphGear5->Enable( down ); mSubgraphGear6->Enable( down ); mSubgraphGear7->Enable( down ); mSubgraphGear8->Enable( down ); mSubgraphGear9->Enable( down ); mSubgraphGear10->Enable( down ); mSubgraphGear11->Enable( down ); mSubgraphGear12->Enable( down ); mSubgraphGear13->Enable( down ); mSubgraphGear14->Enable( down ); mSubgraphGear15->Enable( down ); mSubgraphGear16->Enable( down ); mSubgraphGear17->Enable( down ); } } /***************************************************************************** * Rotate control surfaces (ailerons etc). *****************************************************************************/ void A4Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); ASSERT_AXIS3(axis); switch ( axis ) { case AXIS_PITCH: { RotateElevator( *mSubgraphElevatorLeft, controlFraction ); RotateElevator( *mSubgraphElevatorRight, controlFraction ); } break; case AXIS_ROLL: { RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON ); RotateAileron( *mSubgraphAileronLeft2, controlFraction, LEFT_AILERON ); RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON ); RotateAileron( *mSubgraphAileronRight2, controlFraction, RIGHT_AILERON ); } break; case AXIS_YAW: { // Subgraph is the entire rudder. //RotateRudder( *mSubgraphRudder, controlFraction ); } break; } } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// F14Aircraft ////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /***************************************************************************** * ctor/dtor. *****************************************************************************/ F14Aircraft::F14Aircraft( shptr graph, const WorldVertex& pos ) : Parent(graph,pos,F14Aircraft::ClassGetSpecs()), // gear: mSubgraphGear0(new Subgraph(graph,"MainWheelL")), mSubgraphGear1(new Subgraph(graph,"MainWheelR")), mSubgraphGear2(new Subgraph(graph,"NsWheel")), mSubgraphGear3(new Subgraph(graph,"FwdNsGrDoor")), mSubgraphGear4(new Subgraph(graph,"MidNsGrDoor")), mSubgraphGear5(new Subgraph(graph,"CatBar")), mSubgraphGear6(new Subgraph(graph,"CatBarLink")), mSubgraphGear7(new Subgraph(graph,"NsGearStrut")), mSubgraphGear8(new Subgraph(graph,"Tube.006")), mSubgraphGear9(new Subgraph(graph,"Tube.007")), mSubgraphGear10(new Subgraph(graph,"Tube.013")), mSubgraphGear11(new Subgraph(graph,"Tube.014")), mSubgraphGear12(new Subgraph(graph,"NsGrRotatingSleeve")), mSubgraphGear13(new Subgraph(graph,"RotatingSleeve-L")), mSubgraphGear14(new Subgraph(graph,"RotatingSleeve-R")), mSubgraphGear15(new Subgraph(graph,"MnGrStrut-L")), mSubgraphGear16(new Subgraph(graph,"MnGrStrut.001")), mSubgraphGear17(new Subgraph(graph,"Brace1")), mSubgraphGear18(new Subgraph(graph,"Brace1.001")), mSubgraphGear19(new Subgraph(graph,"Brace1.002")), mSubgraphGear20(new Subgraph(graph,"Brace1.003")), mSubgraphGear21(new Subgraph(graph,"HiCompassL")), mSubgraphGear22(new Subgraph(graph,"HiCompassR")), mSubgraphGear23(new Subgraph(graph,"LShock")), mSubgraphGear24(new Subgraph(graph,"RShock")), mSubgraphGear25(new Subgraph(graph,"NsShock")), mSubgraphGear26(new Subgraph(graph,"LoCompassL")), mSubgraphGear27(new Subgraph(graph,"LoCompassR")), mSubgraphGear28(new Subgraph(graph,"LoNsCompass")), mSubgraphGear29(new Subgraph(graph,"UpNsCompass")), mSubgraphGear30(new Subgraph(graph,"Downlock")), mSubgraphGear31(new Subgraph(graph,"Downlock.001")), mSubgraphGear32(new Subgraph(graph,"LandingLight")), mSubgraphGear33(new Subgraph(graph,"WheelBrake")), mSubgraphGear34(new Subgraph(graph,"WheelBrake.001")), // mSubgraphWingLeft0(new Subgraph(graph,"Wing_0")), mSubgraphWingLeft1(new Subgraph(graph,"Wing_1")), mSubgraphWingLeft2(new Subgraph(graph,"Flap1_0")), mSubgraphWingLeft3(new Subgraph(graph,"Flap1_1")), mSubgraphWingLeft4(new Subgraph(graph,"Flap2_0")), mSubgraphWingLeft5(new Subgraph(graph,"Flap2_1")), mSubgraphWingLeft6(new Subgraph(graph,"Flap3_0")), mSubgraphWingLeft7(new Subgraph(graph,"Flap3_1")), mSubgraphWingLeft8(new Subgraph(graph,"Flap1Brow")), mSubgraphWingLeft9(new Subgraph(graph,"Flap2Brow")), mSubgraphWingLeft10(new Subgraph(graph,"Flap3Brow")), mSubgraphWingLeft11(new Subgraph(graph,"FlapSeal1_0")), mSubgraphWingLeft12(new Subgraph(graph,"FlapSeal1_1")), mSubgraphWingLeft13(new Subgraph(graph,"FlapSeal2_0")), mSubgraphWingLeft14(new Subgraph(graph,"FlapSeal2_1")), mSubgraphWingLeft15(new Subgraph(graph,"FlapSeal3_0")), mSubgraphWingLeft16(new Subgraph(graph,"FlapSeal3_1")), mSubgraphWingLeft17(new Subgraph(graph,"Spoiler1_0")), mSubgraphWingLeft18(new Subgraph(graph,"Spoiler1_1")), mSubgraphWingLeft19(new Subgraph(graph,"Spoiler2_0")), mSubgraphWingLeft20(new Subgraph(graph,"Spoiler2_1")), mSubgraphWingLeft21(new Subgraph(graph,"Spoiler3_0")), mSubgraphWingLeft22(new Subgraph(graph,"Spoiler3_1")), mSubgraphWingLeft23(new Subgraph(graph,"Spoiler4_0")), mSubgraphWingLeft24(new Subgraph(graph,"Spoiler4_1")), mSubgraphWingLeft25(new Subgraph(graph,"Slat1_0")), mSubgraphWingLeft26(new Subgraph(graph,"Slat1_1")), mSubgraphWingLeft27(new Subgraph(graph,"Slat2_0")), mSubgraphWingLeft28(new Subgraph(graph,"Slat2_1")), mSubgraphWingLeft29(new Subgraph(graph,"LWingSlimmer")), // mSubgraphWingRight0(new Subgraph(graph,"Wing.001_0")), mSubgraphWingRight1(new Subgraph(graph,"Wing.001_1")), mSubgraphWingRight2(new Subgraph(graph,"Flap1.001_0")), mSubgraphWingRight3(new Subgraph(graph,"Flap1.001_1")), mSubgraphWingRight4(new Subgraph(graph,"Flap2.001_0")), mSubgraphWingRight5(new Subgraph(graph,"Flap2.001_1")), mSubgraphWingRight6(new Subgraph(graph,"Flap3.001_0")), mSubgraphWingRight7(new Subgraph(graph,"Flap3.001_1")), mSubgraphWingRight8(new Subgraph(graph,"Flap1Brow.001")), mSubgraphWingRight9(new Subgraph(graph,"Flap2Brow.001")), mSubgraphWingRight10(new Subgraph(graph,"Flap3Brow.001")), mSubgraphWingRight11(new Subgraph(graph,"FlapSeal1.001_0")), mSubgraphWingRight12(new Subgraph(graph,"FlapSeal1.001_1")), mSubgraphWingRight13(new Subgraph(graph,"FlapSeal2.001_0")), mSubgraphWingRight14(new Subgraph(graph,"FlapSeal2.001_1")), mSubgraphWingRight15(new Subgraph(graph,"FlapSeal3.001_0")), mSubgraphWingRight16(new Subgraph(graph,"FlapSeal3.001_1")), mSubgraphWingRight17(new Subgraph(graph,"Spoiler1.001_0")), mSubgraphWingRight18(new Subgraph(graph,"Spoiler1.001_1")), mSubgraphWingRight19(new Subgraph(graph,"Spoiler2.001_0")), mSubgraphWingRight20(new Subgraph(graph,"Spoiler2.001_1")), mSubgraphWingRight21(new Subgraph(graph,"Spoiler3.001_0")), mSubgraphWingRight22(new Subgraph(graph,"Spoiler3.001_1")), mSubgraphWingRight23(new Subgraph(graph,"Spoiler4.001_0")), mSubgraphWingRight24(new Subgraph(graph,"Spoiler4.001_1")), mSubgraphWingRight25(new Subgraph(graph,"Slat1.001_0")), mSubgraphWingRight26(new Subgraph(graph,"Slat1.001_1")), mSubgraphWingRight27(new Subgraph(graph,"Slat2.001_0")), mSubgraphWingRight28(new Subgraph(graph,"Slat2.001_1")), mSubgraphWingRight29(new Subgraph(graph,"RWingSlimmer")), mSubgraphTaileronLeft(new Subgraph(graph,"Stabilator")), mSubgraphTaileronRight(new Subgraph(graph,"Stabilator.001")), mSubgraphRudderLeft(new Subgraph(graph,"RudderL")), mSubgraphRudderRight(new Subgraph(graph,"RudderR")), // mSubgraphLadder0(new Subgraph(graph,"Ladder")), mSubgraphLadder1(new Subgraph(graph,"Ladder.001")), mSubgraphLadder2(new Subgraph(graph,"Ladder.002")), mSubgraphRefuelProbe(new Subgraph(graph,"RefuelProbe")), mSubgraphFlameInner0(new Subgraph(graph,"InnerFlameL")), mSubgraphFlameInner1(new Subgraph(graph,"InnerFlameR")), mSubgraphFlameOuter0(new Subgraph(graph,"outerFlame")), mSubgraphFlameOuter1(new Subgraph(graph,"outerFlame.001")), mSubgraphShockWave(new Subgraph(graph,"ShockWave")), mSubgraphManeuverVortexLeft(new Subgraph(graph,"ManeuverVortexL")), mSubgraphManeuverVortexRight(new Subgraph(graph,"ManeuverVortexR")), // mGearSubgraphs(), mLeftWingSubgraphs(), mRightWingSubgraphs(), // mSwingWingsFraction(0.0f), mAileronFraction(0.0f) { SetThrottle( 0.0f ); // Hide superfluous parts. mSubgraphLadder0->Enable( false ); mSubgraphLadder1->Enable( false ); mSubgraphLadder2->Enable( false ); mSubgraphRefuelProbe->Enable( false ); mSubgraphShockWave->Enable( false ); mSubgraphManeuverVortexLeft->Enable( false ); mSubgraphManeuverVortexRight->Enable( false ); // Build list of gear subgraphs. mLeftWingSubgraphs.reserve( 50 ); mRightWingSubgraphs.reserve( 50 ); #define F14_PUSH_GEAR_SUBGRAPH( NUM ) \ mGearSubgraphs.push_back( mSubgraphGear##NUM ); F14_PUSH_GEAR_SUBGRAPH( 0 ); F14_PUSH_GEAR_SUBGRAPH( 1 ); F14_PUSH_GEAR_SUBGRAPH( 2 ); F14_PUSH_GEAR_SUBGRAPH( 3 ); F14_PUSH_GEAR_SUBGRAPH( 4 ); F14_PUSH_GEAR_SUBGRAPH( 5 ); F14_PUSH_GEAR_SUBGRAPH( 6 ); F14_PUSH_GEAR_SUBGRAPH( 7 ); F14_PUSH_GEAR_SUBGRAPH( 8 ); F14_PUSH_GEAR_SUBGRAPH( 9 ); F14_PUSH_GEAR_SUBGRAPH( 10 ); F14_PUSH_GEAR_SUBGRAPH( 11 ); F14_PUSH_GEAR_SUBGRAPH( 12 ); F14_PUSH_GEAR_SUBGRAPH( 13 ); F14_PUSH_GEAR_SUBGRAPH( 14 ); F14_PUSH_GEAR_SUBGRAPH( 15 ); F14_PUSH_GEAR_SUBGRAPH( 16 ); F14_PUSH_GEAR_SUBGRAPH( 17 ); F14_PUSH_GEAR_SUBGRAPH( 18 ); F14_PUSH_GEAR_SUBGRAPH( 19 ); F14_PUSH_GEAR_SUBGRAPH( 20 ); F14_PUSH_GEAR_SUBGRAPH( 21 ); F14_PUSH_GEAR_SUBGRAPH( 22 ); F14_PUSH_GEAR_SUBGRAPH( 23 ); F14_PUSH_GEAR_SUBGRAPH( 24 ); F14_PUSH_GEAR_SUBGRAPH( 25 ); F14_PUSH_GEAR_SUBGRAPH( 26 ); F14_PUSH_GEAR_SUBGRAPH( 27 ); F14_PUSH_GEAR_SUBGRAPH( 28 ); F14_PUSH_GEAR_SUBGRAPH( 29 ); F14_PUSH_GEAR_SUBGRAPH( 30 ); F14_PUSH_GEAR_SUBGRAPH( 31 ); F14_PUSH_GEAR_SUBGRAPH( 32 ); F14_PUSH_GEAR_SUBGRAPH( 33 ); F14_PUSH_GEAR_SUBGRAPH( 34 ); // Build list of wing subgraphs. mLeftWingSubgraphs.reserve( 50 ); mRightWingSubgraphs.reserve( 50 ); #define F14_PUSH_WING_SUBGRAPH( NUM ) \ mLeftWingSubgraphs.push_back( mSubgraphWingLeft##NUM ); \ mRightWingSubgraphs.push_back( mSubgraphWingRight##NUM ); F14_PUSH_WING_SUBGRAPH( 0 ); F14_PUSH_WING_SUBGRAPH( 1 ); F14_PUSH_WING_SUBGRAPH( 2 ); F14_PUSH_WING_SUBGRAPH( 3 ); F14_PUSH_WING_SUBGRAPH( 4 ); F14_PUSH_WING_SUBGRAPH( 5 ); F14_PUSH_WING_SUBGRAPH( 6 ); F14_PUSH_WING_SUBGRAPH( 7 ); F14_PUSH_WING_SUBGRAPH( 8 ); F14_PUSH_WING_SUBGRAPH( 9 ); F14_PUSH_WING_SUBGRAPH( 10 ); F14_PUSH_WING_SUBGRAPH( 11 ); F14_PUSH_WING_SUBGRAPH( 12 ); F14_PUSH_WING_SUBGRAPH( 13 ); F14_PUSH_WING_SUBGRAPH( 14 ); F14_PUSH_WING_SUBGRAPH( 15 ); F14_PUSH_WING_SUBGRAPH( 16 ); F14_PUSH_WING_SUBGRAPH( 17 ); F14_PUSH_WING_SUBGRAPH( 18 ); F14_PUSH_WING_SUBGRAPH( 19 ); F14_PUSH_WING_SUBGRAPH( 20 ); F14_PUSH_WING_SUBGRAPH( 21 ); F14_PUSH_WING_SUBGRAPH( 22 ); F14_PUSH_WING_SUBGRAPH( 23 ); F14_PUSH_WING_SUBGRAPH( 24 ); F14_PUSH_WING_SUBGRAPH( 25 ); F14_PUSH_WING_SUBGRAPH( 26 ); F14_PUSH_WING_SUBGRAPH( 27 ); F14_PUSH_WING_SUBGRAPH( 28 ); F14_PUSH_WING_SUBGRAPH( 29 ); // Exhaust flame shouldn't cast shadows. ShadowSceneGraph::DisableShadows( mSubgraphFlameInner0->GetRootNode() ); ShadowSceneGraph::DisableShadows( mSubgraphFlameInner1->GetRootNode() ); ShadowSceneGraph::DisableShadows( mSubgraphFlameOuter0->GetRootNode() ); ShadowSceneGraph::DisableShadows( mSubgraphFlameOuter1->GetRootNode() ); } F14Aircraft::~F14Aircraft() { // NOP } /***************************************************************************** * Reset. *****************************************************************************/ void F14Aircraft::Reset( void ) { Parent::Reset(); // Swing wings forward. SwingWings( 0.0f ); } /***************************************************************************** * @return Aircraft specifications struct. *****************************************************************************/ const AircraftSpecs& F14Aircraft::GetSpecs( void ) // virtual method { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); return F14Aircraft::ClassGetSpecs(); } const AircraftSpecs& F14Aircraft::ClassGetSpecs( void ) // class method { CODE_CLASS_GET_SPECS( "physics_f14.conf" ) } /***************************************************************************** * Retract/extend landing gear. *****************************************************************************/ void F14Aircraft::SetLandingGear( const bool down ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); if ( IfCanSetLandingGear( down ) ) { Parent::SetLandingGear( down ); for ( uint i = 0; i < mGearSubgraphs.size(); ++i ) mGearSubgraphs[i]->Enable( down ); } } /***************************************************************************** * When throttle is changed, animate jet exhaust flame. *****************************************************************************/ void F14Aircraft::SetThrottle( const fp throttle ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); Parent::SetThrottle( throttle ); const bool flameInner = (throttle >= THROTTLE_FLAME_LOW); const bool flameOuter = (throttle >= THROTTLE_FLAME_HIGH); mSubgraphFlameInner0->Enable( flameInner ); mSubgraphFlameInner1->Enable( flameInner ); mSubgraphFlameOuter0->Enable( flameOuter ); mSubgraphFlameOuter1->Enable( flameOuter ); } /***************************************************************************** * Swing wings { 0.0:forward...1.0:back } *****************************************************************************/ void F14Aircraft::SwingWings( const float fraction ) { ASSERT( mLeftWingSubgraphs.size() == mRightWingSubgraphs.size() ); mSwingWingsFraction = Clamp1( fraction ); // Undo rotation/translation of wing subgraphs from previous call. for ( uint i = 0; i < mLeftWingSubgraphs.size(); ++i ) { mLeftWingSubgraphs[i]->Reset(); mRightWingSubgraphs[i]->Reset(); } // deg = 0 fully forward // deg = 45 fully back const Degree deg = mSwingWingsFraction * 45.0f; const Radian rad = Deg2Rad( deg ); // This particular 3D model requires translating the position // of the subgraphs as a function of swing-wings. // offset_x = 0.00 swing forward // offset_z = 0.00 swing forward // offset_x = -1.40 swing back // offset_z = +-1.75 swing back (+- for left/right wing) const fp offset_x = mSwingWingsFraction * -1.40f; const fp offset_z = mSwingWingsFraction * 1.75f; for ( uint i = 0; i < mLeftWingSubgraphs.size(); ++i ) { mLeftWingSubgraphs[i]->Translate( XX, offset_x ); // move along fuselage mRightWingSubgraphs[i]->Translate( XX, offset_x ); mLeftWingSubgraphs[i]->Translate( ZZ, offset_z ); // move outwards (along wings) mRightWingSubgraphs[i]->Translate( ZZ, -offset_z ); mLeftWingSubgraphs[i]->Rotate( YY, rad ); mRightWingSubgraphs[i]->Rotate( YY, -rad ); } } /***************************************************************************** * Rotate control surfaces (ailerons etc). *****************************************************************************/ void F14Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); ASSERT_AXIS3(axis); const AircraftSpecs& specs = GetSpecs(); switch ( axis ) { case AXIS_PITCH: { RotateElevator( *mSubgraphTaileronLeft, controlFraction ); RotateElevator( *mSubgraphTaileronRight, controlFraction ); } break; case AXIS_ROLL: { // F-14 wings are complex. // Tailerons: RotateAileron( *mSubgraphTaileronLeft, controlFraction, LEFT_AILERON, specs.mElevatorOffset ); RotateAileron( *mSubgraphTaileronRight, controlFraction, RIGHT_AILERON, specs.mElevatorOffset ); // Ailerons (outer flaps) if wings are straight-out. if ( mSwingWingsFraction <= F14_AILERONS_ACTIVE_SWING_WINGS ) { // Specially rotate the F-14 ailerons. #define F14_ROTATE_AILERONS( SUBGRAPH, CONTROL_FRACTION, AILERON ) \ {{ \ (SUBGRAPH).Translate( specs.mAileronOffset ); \ (SUBGRAPH).Rotate( MODEL_AXIS_PITCH, \ specs.mAileronROF * (CONTROL_FRACTION) * int(AILERON) ); \ (SUBGRAPH).Translate( -specs.mAileronOffset ); \ }} // Undo previous rotation. F14_ROTATE_AILERONS( *mSubgraphWingLeft3, -mAileronFraction, LEFT_AILERON ); F14_ROTATE_AILERONS( *mSubgraphWingRight3, -mAileronFraction, RIGHT_AILERON ); // Apply current rotation. F14_ROTATE_AILERONS( *mSubgraphWingLeft3, controlFraction, LEFT_AILERON ); F14_ROTATE_AILERONS( *mSubgraphWingRight3, controlFraction, RIGHT_AILERON ); // Remember for next time. mAileronFraction = controlFraction; } } break; case AXIS_YAW: { RotateRudder( *mSubgraphRudderLeft, controlFraction, LEFT_RUDDER ); RotateRudder( *mSubgraphRudderRight, controlFraction, RIGHT_RUDDER ); } break; } } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// F15Aircraft ////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /***************************************************************************** * ctor/dtor. *****************************************************************************/ F15Aircraft::F15Aircraft( shptr graph, const WorldVertex& pos ) : Parent(graph,pos,F15Aircraft::ClassGetSpecs()), // gear: mSubgraphGear0(new Subgraph(graph,"LeftWheel")), mSubgraphGear1(new Subgraph(graph,"LeftWheelTire")), mSubgraphGear2(new Subgraph(graph,"RightWheel")), mSubgraphGear3(new Subgraph(graph,"RightWheelTire")), mSubgraphGear4(new Subgraph(graph,"FrontWheel")), mSubgraphGear5(new Subgraph(graph,"FrontWheelTire")), // exhaust flame: mSubgraphFlame0(new Subgraph(graph,"InternalFlame")), mSubgraphFlame1(new Subgraph(graph,"ExternalFlame")), // control surfaces: mSubgraphAileronLeft(new Subgraph(graph,"AileronLeft")), mSubgraphAileronRight(new Subgraph(graph,"AileronRight")), mSubgraphElevatorLeft(new Subgraph(graph,"ElevatorLeft")), mSubgraphElevatorRight(new Subgraph(graph,"ElevatorRight")), mSubgraphRudderLeft(new Subgraph(graph,"RudderLeft")), mSubgraphRudderRight(new Subgraph(graph,"RudderRight")) { SetThrottle( 0.0f ); // Exhaust flame shouldn't cast shadows. ShadowSceneGraph::DisableShadows( mSubgraphFlame0->GetRootNode() ); ShadowSceneGraph::DisableShadows( mSubgraphFlame1->GetRootNode() ); } F15Aircraft::~F15Aircraft() { // NOP } /***************************************************************************** * @return Aircraft specifications struct. *****************************************************************************/ const AircraftSpecs& F15Aircraft::GetSpecs( void ) // virtual method { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); return F15Aircraft::ClassGetSpecs(); } const AircraftSpecs& F15Aircraft::ClassGetSpecs( void ) // class method { CODE_CLASS_GET_SPECS( "physics_f15.conf" ) } /***************************************************************************** * Retract/extend landing gear. *****************************************************************************/ void F15Aircraft::SetLandingGear( const bool down ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); if ( IfCanSetLandingGear( down ) ) { Parent::SetLandingGear( down ); mSubgraphGear0->Enable( down ); mSubgraphGear1->Enable( down ); mSubgraphGear2->Enable( down ); mSubgraphGear3->Enable( down ); mSubgraphGear4->Enable( down ); mSubgraphGear5->Enable( down ); } } /***************************************************************************** * When throttle is changed, animate jet exhaust flame. *****************************************************************************/ void F15Aircraft::SetThrottle( const fp throttle ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); Parent::SetThrottle( throttle ); mSubgraphFlame0->Enable( throttle >= THROTTLE_FLAME_LOW ); mSubgraphFlame1->Enable( throttle >= THROTTLE_FLAME_HIGH ); // afterburner } /***************************************************************************** * Rotate control surfaces (ailerons etc). *****************************************************************************/ void F15Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); ASSERT_AXIS3(axis); switch ( axis ) { case AXIS_PITCH: { RotateElevator( *mSubgraphElevatorLeft, controlFraction ); RotateElevator( *mSubgraphElevatorRight, controlFraction ); } break; case AXIS_ROLL: { RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON ); RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON ); } break; case AXIS_YAW: { RotateRudder( *mSubgraphRudderLeft, controlFraction, LEFT_RUDDER ); RotateRudder( *mSubgraphRudderRight, controlFraction, RIGHT_RUDDER ); } break; } } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// F16Aircraft ////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /***************************************************************************** * ctor/dtor. *****************************************************************************/ F16Aircraft::F16Aircraft( shptr graph, const WorldVertex& pos ) : Parent(graph,pos,F16Aircraft::ClassGetSpecs()), // gear: mSubgraphGear0(new Subgraph(graph,"internal_front_gear_door")), mSubgraphGear1(new Subgraph(graph,"internal_right_main_door")), mSubgraphGear2(new Subgraph(graph,"internal_left_main_door")), // mSubgraphGear3(new Subgraph(graph,"front_tire")), mSubgraphGear4(new Subgraph(graph,"front_aft_strut")), mSubgraphGear5(new Subgraph(graph,"front_lower_strut")), mSubgraphGear6(new Subgraph(graph,"front_upper_strut")), // mSubgraphGear7(new Subgraph(graph,"left_main_strut")), mSubgraphGear8(new Subgraph(graph,"left_main_tire")), mSubgraphGear9(new Subgraph(graph,"left_lower_main_strut")), mSubgraphGear10(new Subgraph(graph,"left_upper_main_strut")), // mSubgraphGear11(new Subgraph(graph,"right_main_strut")), mSubgraphGear12(new Subgraph(graph,"right_main_tire")), mSubgraphGear13(new Subgraph(graph,"right_lower_main_strut")), mSubgraphGear14(new Subgraph(graph,"right_upper_main_strut")), // mSubgraphGear15(new Subgraph(graph,"external_front_gear_door")), mSubgraphGear16(new Subgraph(graph,"external_left_main_door")), mSubgraphGear17(new Subgraph(graph,"external_right_main_door")), // exhaust flame: mSubgraphFlame0(new Subgraph(graph,"internal_flame")), mSubgraphFlame1(new Subgraph(graph,"external_flame")), // control surfaces: mSubgraphAileronLeft(new Subgraph(graph,"left_upper_aileron")), mSubgraphAileronRight(new Subgraph(graph,"right_upper_aileron")), mSubgraphFlapLeft(new Subgraph(graph,"left_upper_flap")), mSubgraphFlapRight(new Subgraph(graph,"right_upper_flap")), mSubgraphElevatorLeft(new Subgraph(graph,"left_upper_horizontal_tail")), mSubgraphElevatorRight(new Subgraph(graph,"right_upper_horizontal_tail")), mSubgraphRudder0(new Subgraph(graph,"rudder2")), mSubgraphRudder1(new Subgraph(graph,"rudder3")), mSubgraphRudder2(new Subgraph(graph,"rudder5")), mSubgraphRudder3(new Subgraph(graph,"rudder6")), // junk: mSubgraphJunk0(new Subgraph(graph,"lhocondenscone")), mSubgraphJunk1(new Subgraph(graph,"rhocondenscone")) { SetThrottle( 0.0f ); // Exhaust flame shouldn't cast shadows. ShadowSceneGraph::DisableShadows( mSubgraphFlame0->GetRootNode() ); ShadowSceneGraph::DisableShadows( mSubgraphFlame1->GetRootNode() ); // Disable junk parts of F-16 model. mSubgraphJunk0->Enable( false ); mSubgraphJunk1->Enable( false ); } F16Aircraft::~F16Aircraft() { // NOP } /***************************************************************************** * @return Aircraft specifications struct. *****************************************************************************/ const AircraftSpecs& F16Aircraft::GetSpecs( void ) // virtual method { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); return F16Aircraft::ClassGetSpecs(); } const AircraftSpecs& F16Aircraft::ClassGetSpecs( void ) // class method { CODE_CLASS_GET_SPECS( "physics_f16.conf" ) } /***************************************************************************** * Retract/extend landing gear. *****************************************************************************/ void F16Aircraft::SetLandingGear( const bool down ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); // Known problem: The door for the front wheel should be rotated // into the fuselage but isn't implemented. if ( IfCanSetLandingGear( down ) ) { Parent::SetLandingGear( down ); mSubgraphGear0->Enable( down ); mSubgraphGear1->Enable( down ); mSubgraphGear2->Enable( down ); mSubgraphGear3->Enable( down ); mSubgraphGear4->Enable( down ); mSubgraphGear5->Enable( down ); mSubgraphGear6->Enable( down ); mSubgraphGear7->Enable( down ); mSubgraphGear8->Enable( down ); mSubgraphGear9->Enable( down ); mSubgraphGear10->Enable( down ); mSubgraphGear11->Enable( down ); mSubgraphGear12->Enable( down ); mSubgraphGear13->Enable( down ); mSubgraphGear14->Enable( down ); mSubgraphGear15->Enable( down ); //mSubgraphGear16->Enable( down ); mSubgraphGear17->Enable( down ); } } /***************************************************************************** * When throttle is changed, animate jet exhaust flame. *****************************************************************************/ void F16Aircraft::SetThrottle( const fp throttle ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); Parent::SetThrottle( throttle ); // mSubgraphFlame0->Enable( throttle >= THROTTLE_FLAME_LOW ); // see-thru problem mSubgraphFlame1->Enable( throttle >= THROTTLE_FLAME_HIGH ); // afterburner } /***************************************************************************** * Rotate control surfaces (ailerons etc). *****************************************************************************/ void F16Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); ASSERT_AXIS3(axis); switch ( axis ) { case AXIS_PITCH: { RotateElevator( *mSubgraphElevatorLeft, controlFraction ); RotateElevator( *mSubgraphElevatorRight, controlFraction ); } break; case AXIS_ROLL: { RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON ); RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON ); #if 0 RotateAileron( *mSubgraphFlapLeft, controlFraction, LEFT_AILERON ); RotateAileron( *mSubgraphFlapRight, controlFraction, RIGHT_AILERON ); #endif } break; case AXIS_YAW: { RotateRudder( *mSubgraphRudder0, controlFraction ); RotateRudder( *mSubgraphRudder1, controlFraction ); RotateRudder( *mSubgraphRudder2, controlFraction ); RotateRudder( *mSubgraphRudder3, controlFraction ); } break; } } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// F18Aircraft ////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /***************************************************************************** * ctor/dtor. *****************************************************************************/ F18Aircraft::F18Aircraft( shptr graph, const WorldVertex& pos ) : Parent(graph,pos,F18Aircraft::ClassGetSpecs()), // gear: mSubgraphGear0(new Subgraph(graph,"LeftWheel")), mSubgraphGear1(new Subgraph(graph,"LeftDoor")), mSubgraphGear2(new Subgraph(graph,"RightWheel")), mSubgraphGear3(new Subgraph(graph,"RightDoor")), mSubgraphGear4(new Subgraph(graph,"FrontWheel")), mSubgraphGear5(new Subgraph(graph,"FrontDoor")), // exhaust flame: mSubgraphFlame0(new Subgraph(graph,"InternalFlame")), mSubgraphFlame1(new Subgraph(graph,"ExternalFlame")), // control surfaces: mSubgraphAileronLeft(new Subgraph(graph,"AileronLeft")), mSubgraphAileronRight(new Subgraph(graph,"AileronRight")), mSubgraphElevatorLeft(new Subgraph(graph,"ElevatorLeft")), mSubgraphElevatorRight(new Subgraph(graph,"ElevatorRight")), mSubgraphRudderLeft(new Subgraph(graph,"RudderLeft")), mSubgraphRudderRight(new Subgraph(graph,"RudderRight")) { SetThrottle( 0.0f ); // Exhaust flame shouldn't cast shadows. ShadowSceneGraph::DisableShadows( mSubgraphFlame0->GetRootNode() ); ShadowSceneGraph::DisableShadows( mSubgraphFlame1->GetRootNode() ); } F18Aircraft::~F18Aircraft() { // NOP } /***************************************************************************** * @return Aircraft specifications struct. *****************************************************************************/ const AircraftSpecs& F18Aircraft::GetSpecs( void ) // virtual method { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); return F18Aircraft::ClassGetSpecs(); } const AircraftSpecs& F18Aircraft::ClassGetSpecs( void ) // class method { CODE_CLASS_GET_SPECS( "physics_f18.conf" ) } /***************************************************************************** * Retract/extend landing gear. *****************************************************************************/ void F18Aircraft::SetLandingGear( const bool down ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); if ( IfCanSetLandingGear( down ) ) { Parent::SetLandingGear( down ); mSubgraphGear0->Enable( down ); mSubgraphGear1->Enable( down ); mSubgraphGear2->Enable( down ); mSubgraphGear3->Enable( down ); mSubgraphGear4->Enable( down ); mSubgraphGear5->Enable( down ); } } /***************************************************************************** * When throttle is changed, animate jet exhaust flame. *****************************************************************************/ void F18Aircraft::SetThrottle( const fp throttle ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); Parent::SetThrottle( throttle ); //mSubgraphFlame0->Enable( throttle >= THROTTLE_FLAME_LOW ); // see-thru problem mSubgraphFlame1->Enable( throttle >= THROTTLE_FLAME_HIGH ); // afterburner } /***************************************************************************** * Rotate control surfaces (ailerons etc). *****************************************************************************/ void F18Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); ASSERT_AXIS3(axis); switch ( axis ) { case AXIS_PITCH: { RotateElevator( *mSubgraphElevatorLeft, controlFraction ); RotateElevator( *mSubgraphElevatorRight, controlFraction ); } break; case AXIS_ROLL: { RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON ); RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON ); } break; case AXIS_YAW: { RotateRudder( *mSubgraphRudderLeft, controlFraction, LEFT_RUDDER ); RotateRudder( *mSubgraphRudderRight, controlFraction, RIGHT_RUDDER ); } break; } } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// SR71Aircraft ////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /***************************************************************************** * ctor/dtor. *****************************************************************************/ SR71Aircraft::SR71Aircraft( shptr graph, const WorldVertex& pos ) : Parent(graph,pos,SR71Aircraft::ClassGetSpecs()), // gear: mSubgraphGear0(new Subgraph(graph,"roueA")), // roue means wheel in French mSubgraphGear1(new Subgraph(graph,"roueD")), mSubgraphGear2(new Subgraph(graph,"roueG")), // struts: mSubgraphStrut0(new Subgraph(graph,"axeA")), mSubgraphStrut1(new Subgraph(graph,"axeD")), mSubgraphStrut2(new Subgraph(graph,"axeG")), mSubgraphStrut3(new Subgraph(graph,"barrebasA")), mSubgraphStrut4(new Subgraph(graph,"barrebasD")), mSubgraphStrut5(new Subgraph(graph,"barrebasG")), mSubgraphStrut6(new Subgraph(graph,"barrehautA")), mSubgraphStrut7(new Subgraph(graph,"barrehautD")), mSubgraphStrut8(new Subgraph(graph,"barrehautG")), mSubgraphStrut9(new Subgraph(graph,"porteD1")), mSubgraphStrut10(new Subgraph(graph,"porteD2")), mSubgraphStrut11(new Subgraph(graph,"porteG1")), mSubgraphStrut12(new Subgraph(graph,"porteG2")), mSubgraphStrut13(new Subgraph(graph,"verrinA")), mSubgraphStrut14(new Subgraph(graph,"verrinD")), mSubgraphStrut15(new Subgraph(graph,"verrinG")), // parachute: mSubgraphParachute(new Subgraph(graph,"parachute")), // exhaust flame: mSubgraphFlame0(new Subgraph(graph,"flammeD1")), mSubgraphFlame1(new Subgraph(graph,"flammeD2")), mSubgraphFlame2(new Subgraph(graph,"flammeD3")), mSubgraphFlame3(new Subgraph(graph,"flammeG1")), mSubgraphFlame4(new Subgraph(graph,"flammeG2")), mSubgraphFlame5(new Subgraph(graph,"flammeG3")), // Control surfaces: mSubgraphAileronLeft(new Subgraph(graph,"aileronG")), mSubgraphAileronRight(new Subgraph(graph,"aileronD")), mSubgraphElevatorLeft(new Subgraph(graph,"profondeurG")), mSubgraphElevatorRight(new Subgraph(graph,"profondeurD")) // (rudder omitted) { SetThrottle( 0.0f ); // Exhaust flame shouldn't cast shadows. ShadowSceneGraph::DisableShadows( mSubgraphFlame0->GetRootNode() ); ShadowSceneGraph::DisableShadows( mSubgraphFlame1->GetRootNode() ); ShadowSceneGraph::DisableShadows( mSubgraphFlame2->GetRootNode() ); ShadowSceneGraph::DisableShadows( mSubgraphFlame3->GetRootNode() ); ShadowSceneGraph::DisableShadows( mSubgraphFlame4->GetRootNode() ); ShadowSceneGraph::DisableShadows( mSubgraphFlame5->GetRootNode() ); mSubgraphParachute->Enable( false ); } SR71Aircraft::~SR71Aircraft() { // NOP } /***************************************************************************** * @return Aircraft specifications struct. *****************************************************************************/ const AircraftSpecs& SR71Aircraft::GetSpecs( void ) // virtual method { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); return SR71Aircraft::ClassGetSpecs(); } const AircraftSpecs& SR71Aircraft::ClassGetSpecs( void ) // class method { CODE_CLASS_GET_SPECS( "physics_sr71.conf" ) } /***************************************************************************** * Retract/extend landing gear. *****************************************************************************/ void SR71Aircraft::SetLandingGear( const bool down ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); if ( IfCanSetLandingGear( down )) { Parent::SetLandingGear( down ); mSubgraphGear0->Enable( down ); mSubgraphGear1->Enable( down ); mSubgraphGear2->Enable( down ); mSubgraphStrut0->Enable( down ); mSubgraphStrut1->Enable( down ); mSubgraphStrut2->Enable( down ); mSubgraphStrut3->Enable( down ); mSubgraphStrut4->Enable( down ); mSubgraphStrut5->Enable( down ); mSubgraphStrut6->Enable( down ); mSubgraphStrut7->Enable( down ); mSubgraphStrut8->Enable( down ); mSubgraphStrut9->Enable( down ); mSubgraphStrut10->Enable( down ); mSubgraphStrut11->Enable( down ); mSubgraphStrut12->Enable( down ); mSubgraphStrut13->Enable( down ); mSubgraphStrut14->Enable( down ); mSubgraphStrut15->Enable( down ); } } /***************************************************************************** * When throttle is changed, animate jet exhaust flame. *****************************************************************************/ void SR71Aircraft::SetThrottle( const fp throttle ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); Parent::SetThrottle( throttle ); const bool flame = (throttle >= THROTTLE_FLAME); mSubgraphFlame0->Enable( flame ); mSubgraphFlame1->Enable( flame ); mSubgraphFlame2->Enable( flame ); mSubgraphFlame3->Enable( flame ); mSubgraphFlame4->Enable( flame ); mSubgraphFlame5->Enable( flame ); } /***************************************************************************** * Rotate control surfaces (ailerons etc). *****************************************************************************/ void SR71Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); ASSERT_AXIS3(axis); switch ( axis ) { case AXIS_PITCH: { RotateElevator( *mSubgraphElevatorLeft, controlFraction ); RotateElevator( *mSubgraphElevatorRight, controlFraction ); } break; case AXIS_ROLL: { RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON ); RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON ); } break; #if 0 case AXIS_YAW: { RotateRudder( *mSubgraphRudder, controlFraction ); } break; #endif } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////// Mirage2000Aircraft ////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /***************************************************************************** * ctor/dtor. *****************************************************************************/ Mirage2000Aircraft::Mirage2000Aircraft( shptr graph, const WorldVertex& pos ) : Parent(graph,pos,Mirage2000Aircraft::ClassGetSpecs()), // gear: mSubgraphGear0(new Subgraph(graph,"front_tire")), mSubgraphGear1(new Subgraph(graph,"front_wheel")), mSubgraphGear2(new Subgraph(graph,"front_door_fwd")), mSubgraphGear3(new Subgraph(graph,"left_wheel")), mSubgraphGear4(new Subgraph(graph,"left_tire")), mSubgraphGear5(new Subgraph(graph,"left_door")), mSubgraphGear6(new Subgraph(graph,"right_wheel")), mSubgraphGear7(new Subgraph(graph,"right_tire")), mSubgraphGear8(new Subgraph(graph,"right_door")), // exhaust flame: mSubgraphFlame0(new Subgraph(graph,"internal_flame")), mSubgraphFlame1(new Subgraph(graph,"external_flame")), // Control surfaces: mSubgraphAileronLeft(new Subgraph(graph,"VoletGauche")), // are elevators too mSubgraphAileronRight(new Subgraph(graph,"VoletDroit")), mSubgraphRudder(new Subgraph(graph,"rudder")) { SetThrottle( 0.0f ); // Exhaust flame shouldn't cast shadows. ShadowSceneGraph::DisableShadows( mSubgraphFlame0->GetRootNode() ); ShadowSceneGraph::DisableShadows( mSubgraphFlame1->GetRootNode() ); } Mirage2000Aircraft::~Mirage2000Aircraft() { // NOP } /***************************************************************************** * @return Aircraft specifications struct. *****************************************************************************/ const AircraftSpecs& Mirage2000Aircraft::GetSpecs( void ) // virtual method { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); return Mirage2000Aircraft::ClassGetSpecs(); } const AircraftSpecs& Mirage2000Aircraft::ClassGetSpecs( void ) // class method { CODE_CLASS_GET_SPECS( "physics_mirage2000.conf" ) } /***************************************************************************** * Retract/extend landing gear. *****************************************************************************/ void Mirage2000Aircraft::SetLandingGear( const bool down ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); if ( IfCanSetLandingGear( down )) { Parent::SetLandingGear( down ); mSubgraphGear0->Enable( down ); mSubgraphGear1->Enable( down ); mSubgraphGear2->Enable( down ); mSubgraphGear3->Enable( down ); mSubgraphGear4->Enable( down ); mSubgraphGear5->Enable( down ); mSubgraphGear6->Enable( down ); mSubgraphGear7->Enable( down ); mSubgraphGear8->Enable( down ); } } /***************************************************************************** * When throttle is changed, animate jet exhaust flame. *****************************************************************************/ void Mirage2000Aircraft::SetThrottle( const fp throttle ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); Parent::SetThrottle( throttle ); // mSubgraphFlame0->Enable( throttle >= THROTTLE_FLAME_LOW ); // see-thru problem mSubgraphFlame1->Enable( throttle >= THROTTLE_FLAME ); // afterburner } /***************************************************************************** * Rotate control surfaces (ailerons etc). *****************************************************************************/ void Mirage2000Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); ASSERT_AXIS3(axis); switch ( axis ) { // On Mirage, ailerons are also elevators. case AXIS_PITCH: { RotateElevator( *mSubgraphAileronLeft, controlFraction ); RotateElevator( *mSubgraphAileronRight, controlFraction ); } break; case AXIS_ROLL: { RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON ); RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON ); } break; case AXIS_YAW: { RotateRudder( *mSubgraphRudder, controlFraction ); } break; } } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// SU37Aircraft ///////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /***************************************************************************** * ctor/dtor. *****************************************************************************/ SU37Aircraft::SU37Aircraft( shptr graph, const WorldVertex& pos ) : Parent(graph,pos,SU37Aircraft::ClassGetSpecs()), // gear: mSubgraphGear0(new Subgraph(graph,"UC")), // under carriage // exhaust flame: mSubgraphFlame0(new Subgraph(graph,"L_Reheat")), mSubgraphFlame1(new Subgraph(graph,"R_Reheat")), // control surfaces: mSubgraphAileronLeft(new Subgraph(graph,"WNG_Left_Flaperon")), mSubgraphAileronRight(new Subgraph(graph,"WNG_Right_Flaperon")), mSubgraphElevatorLeft(new Subgraph(graph,"ELV_Elevon_Left")), mSubgraphElevatorRight(new Subgraph(graph,"ELV_Elevon_Right")), mSubgraphRudderLeft(new Subgraph(graph,"TF_Left_Rudder")), mSubgraphRudderRight(new Subgraph(graph,"TF_Right_Rudder")) { SetThrottle( 0.0f ); // Exhaust flame shouldn't cast shadows. ShadowSceneGraph::DisableShadows( mSubgraphFlame0->GetRootNode() ); ShadowSceneGraph::DisableShadows( mSubgraphFlame1->GetRootNode() ); } SU37Aircraft::~SU37Aircraft() { // NOP } /***************************************************************************** * @return Aircraft specifications struct. *****************************************************************************/ const AircraftSpecs& SU37Aircraft::GetSpecs( void ) // virtual method { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); return SU37Aircraft::ClassGetSpecs(); } const AircraftSpecs& SU37Aircraft::ClassGetSpecs( void ) // class method { CODE_CLASS_GET_SPECS( "physics_su37.conf" ) } /***************************************************************************** * Retract/extend landing gear. *****************************************************************************/ void SU37Aircraft::SetLandingGear( const bool down ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); if ( IfCanSetLandingGear( down )) { Parent::SetLandingGear( down ); mSubgraphGear0->Enable( down ); } } /***************************************************************************** * When throttle is changed, animate jet exhaust flame. *****************************************************************************/ void SU37Aircraft::SetThrottle( const fp throttle ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); Parent::SetThrottle( throttle ); const bool flame = (throttle >= THROTTLE_FLAME); mSubgraphFlame0->Enable( flame ); mSubgraphFlame1->Enable( flame ); } /***************************************************************************** * Rotate control surfaces (ailerons etc). *****************************************************************************/ void SU37Aircraft::RotateControlSurfaces( const uint axis, const fp controlFraction ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); ASSERT_AXIS3(axis); switch ( axis ) { case AXIS_PITCH: { RotateElevator( *mSubgraphElevatorLeft, controlFraction ); RotateElevator( *mSubgraphElevatorRight, controlFraction ); } break; case AXIS_ROLL: { RotateAileron( *mSubgraphAileronLeft, controlFraction, LEFT_AILERON ); RotateAileron( *mSubgraphAileronRight, controlFraction, RIGHT_AILERON ); } break; case AXIS_YAW: { RotateRudder( *mSubgraphRudderLeft, controlFraction, LEFT_RUDDER ); RotateRudder( *mSubgraphRudderRight, controlFraction, RIGHT_RUDDER ); } break; } } //////////////////////////////////////////////////////////////////////////////// ////////////////////////// SpaceShuttleAircraft ////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /***************************************************************************** * ctor/dtor. *****************************************************************************/ SpaceShuttleAircraft::SpaceShuttleAircraft( shptr graph, const WorldVertex& pos ) : Parent(graph,pos,SpaceShuttleAircraft::ClassGetSpecs()), mSubgraphBayDoorLeft(new Subgraph(graph,"bay_door_left")), mSubgraphBayDoorRight(new Subgraph(graph,"bay_door_right")), mBayDoorsFraction(0.0f) { // NOP } SpaceShuttleAircraft::~SpaceShuttleAircraft() { // NOP } /***************************************************************************** * Reset. *****************************************************************************/ void SpaceShuttleAircraft::Reset( void ) { Parent::Reset(); // Close bay doors. SwingBayDoors( 0.0f ); } /***************************************************************************** * @return Aircraft specifications struct. *****************************************************************************/ const AircraftSpecs& SpaceShuttleAircraft::GetSpecs( void ) // virtual method { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); return SpaceShuttleAircraft::ClassGetSpecs(); } const AircraftSpecs& SpaceShuttleAircraft::ClassGetSpecs( void ) // class method { CODE_CLASS_GET_SPECS( "physics_spaceShuttle.conf" ) } /***************************************************************************** * Really open bay doors. * Reason for this subterfuge is to reuse keyboard control for swinging wings. *****************************************************************************/ void SpaceShuttleAircraft::SwingWings( const float fraction ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); SwingBayDoors( fraction ); } /***************************************************************************** * Open bay doors { 0.0:closed ... 1.0:open } *****************************************************************************/ void SpaceShuttleAircraft::SwingBayDoors( const float fraction ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); mBayDoorsFraction = Clamp1( fraction ); // Undo rotation/translation of wing subgraphs from previous call. mSubgraphBayDoorLeft->Reset(); mSubgraphBayDoorRight->Reset(); // deg = 0 fully closed // deg = 70 fully open const Degree deg = mBayDoorsFraction * 70.0f; const Radian rad = Deg2Rad( deg ); // Translate to center the pivot at door hinges. fp offset0 = 0.03f; fp offset1 = 0.08f; mSubgraphBayDoorLeft->Translate( YY, offset0 ); // up mSubgraphBayDoorRight->Translate( YY, offset0 ); // up mSubgraphBayDoorLeft->Translate( XX, -offset1 ); // horz mSubgraphBayDoorRight->Translate( XX, offset1 ); // horz mSubgraphBayDoorLeft->Rotate( ZZ, rad ); mSubgraphBayDoorRight->Rotate( ZZ, -rad ); // Undo translation. offset0 = -offset0; offset1 = -offset1; mSubgraphBayDoorLeft->Translate( YY, offset0 ); // up mSubgraphBayDoorRight->Translate( YY, offset0 ); // up mSubgraphBayDoorLeft->Translate( XX, -offset1 ); // horz mSubgraphBayDoorRight->Translate( XX, offset1 ); // horz } //////////////////////////////////////////////////////////////////////////////// //////////////////////////// SikorskyAircraft //////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /***************************************************************************** * ctor/dtor. *****************************************************************************/ SikorskyAircraft::SikorskyAircraft( shptr graph, const WorldVertex& pos ) : Parent(graph,pos,SikorskyAircraft::ClassGetSpecs()), mSubgraphRotor0(new Subgraph(graph,"blade1")), mSubgraphRotor1(new Subgraph(graph,"blade2")), mSubgraphRotor2(new Subgraph(graph,"blade3")), mSubgraphRotor3(new Subgraph(graph,"blade4")), mSubgraphRotor4(new Subgraph(graph,"fastblade1")), // blurred mSubgraphRotor5(new Subgraph(graph,"fastblade2")), // blurred mSubgraphRotor6(new Subgraph(graph,"fastblade3")), // blurred mSubgraphRotor7(new Subgraph(graph,"fastblade4")), // blurred mSubgraphTailRotor(new Subgraph(graph,"TailRotor")) { // NOP } SikorskyAircraft::~SikorskyAircraft() { // NOP } /***************************************************************************** * @return Aircraft specifications struct. *****************************************************************************/ const AircraftSpecs& SikorskyAircraft::GetSpecs( void ) // virtual method { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); return SikorskyAircraft::ClassGetSpecs(); } const AircraftSpecs& SikorskyAircraft::ClassGetSpecs( void ) // class method { CODE_CLASS_GET_SPECS( "physics_sikorsky.conf" ) } /***************************************************************************** * Tick that pulses animation. *****************************************************************************/ void SikorskyAircraft::Tick( const Milliseconds millisecElapsed ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); Parent::Tick( millisecElapsed ); RotateRotors(); } /***************************************************************************** * Rotate propeller. *****************************************************************************/ void SikorskyAircraft::RotateRotors( void ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); const uint axisRotor = YY; // main rotors // const uint axisTailRotor = ZZ; { const Radian radian = Deg2Rad( Degree(10.0f) ); mSubgraphRotor0->Rotate( axisRotor, radian ); mSubgraphRotor1->Rotate( axisRotor, radian ); mSubgraphRotor2->Rotate( axisRotor, radian ); mSubgraphRotor3->Rotate( axisRotor, radian ); } { const Radian radian = Deg2Rad( Degree(5.0f) ); // blurred rotors mSubgraphRotor4->Rotate( axisRotor, radian ); mSubgraphRotor5->Rotate( axisRotor, radian ); mSubgraphRotor6->Rotate( axisRotor, radian ); mSubgraphRotor7->Rotate( axisRotor, radian ); } // The origin of the tail rotor is the center of the helicopter // rather than the rotor's hub, so just toggle enablement. #if 1 mSubgraphTailRotor->Enable( not mSubgraphTailRotor->IfEnabled() ); #else { const Radian radian = Deg2Rad( Degree(30.0f) ); mSubgraphTailRotor->Rotate( axisTailRotor, radian ); } #endif } /***************************************************************************** * Retract/extend landing gear. *****************************************************************************/ void SikorskyAircraft::SetLandingGear( const bool down ) { CHECK_TYPESIG(this,TYPESIG_AIRCRAFT); if ( IfCanSetLandingGear( down ) ) { Parent::SetLandingGear( down ); Parent::mLandingGearDown = true; // override } } } // namespace program