From: david Date: Sat, 23 Feb 2002 21:20:00 +0000 (+0000) Subject: Separated 3D model-handling code from main.cxx out into its own X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=d61ce30c12f2c3f3e1265bfc805304b40a4dd8c5;p=flightgear.git Separated 3D model-handling code from main.cxx out into its own subsystem, FGAircraftModel. --- diff --git a/src/Main/Makefile.am b/src/Main/Makefile.am index 9044087ad..ad7df67ed 100644 --- a/src/Main/Makefile.am +++ b/src/Main/Makefile.am @@ -47,6 +47,7 @@ fgfs_SOURCES = \ fg_props.cxx fg_props.hxx \ fgfs.cxx fgfs.hxx \ globals.cxx globals.hxx \ + model.cxx model.hxx \ options.cxx options.hxx \ splash.cxx splash.hxx \ viewer.cxx viewer.hxx \ diff --git a/src/Main/main.cxx b/src/Main/main.cxx index fdbc4b9eb..cd56e6971 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -151,6 +151,7 @@ sgVec3 rway_ols; #include "splash.hxx" #include "viewmgr.hxx" #include "options.hxx" +#include "model.hxx" #ifdef macintosh # include // -dw- for command line dialog @@ -173,14 +174,6 @@ void fgReshape( int width, int height ); ssgRoot *scene = NULL; ssgBranch *terrain = NULL; -// aircraft model stuff -ssgSelector *acmodel_selector = NULL; -ssgTransform *acmodel_pos = NULL; -ssgSelector *prop_selector = NULL; -ssgSelector *flaps_selector = NULL; -int acmodel_npropsettings; -int acmodel_proprpms[4][2]; // different propeller settings - ssgRoot *lighting = NULL; ssgBranch *ground = NULL; ssgBranch *airport = NULL; @@ -675,57 +668,7 @@ void fgRenderFrame( void ) { ssgSetNearFar( 0.5f, 120000.0f ); } - if ( globals->get_viewmgr()->get_current() == 0 ) { - // disable aircraft model - acmodel_selector->select(0); - } else { - // enable aircraft model and set up its position and orientation - acmodel_selector->select(1); - - FGViewerRPH *pilot_view = - (FGViewerRPH *)globals->get_viewmgr()->get_view( 0 ); - - sgMat4 sgTRANS; - sgMakeTransMat4( sgTRANS, pilot_view->get_view_pos() ); - - sgVec3 ownship_up; - sgSetVec3( ownship_up, 0.0, 0.0, 1.0); - - sgMat4 sgROT; - sgMakeRotMat4( sgROT, -90.0, ownship_up ); - - // sgMat4 sgTMP; - // sgMat4 sgTUX; - // sgMultMat4( sgTMP, sgROT, pilot_view.VIEW_ROT ); - // sgMultMat4( sgTUX, sgTMP, sgTRANS ); - - // sgTUX = ( sgROT * pilot_view.VIEW_ROT ) * sgTRANS - sgMat4 sgTUX; - sgCopyMat4( sgTUX, sgROT ); - sgPostMultMat4( sgTUX, pilot_view->get_VIEW_ROT() ); - sgPostMultMat4( sgTUX, sgTRANS ); - - sgCoord tuxpos; - sgSetCoord( &tuxpos, sgTUX ); - acmodel_pos->setTransform( &tuxpos ); - - // set up moving parts - if (flaps_selector != NULL) { - flaps_selector->select( (globals->get_controls()->get_flaps() > 0.5f) ? 1 : 2 ); - } - - if (prop_selector != NULL) { - int propsel_mask = 0; - double rpm = fgGetDouble("/engines/engine[0]/rpm"); - for (int i = 0; i < acmodel_npropsettings; i++) { - if (rpm >= acmodel_proprpms[i][0] && - rpm <= acmodel_proprpms[i][1]) { - propsel_mask |= 1 << i; - } - } - prop_selector->select(propsel_mask); - } - } + current_model.update(0); // FIXME: use real delta time // $$$ begin - added VS Renganthan 17 Oct 2K fgUpdateDCS(); @@ -1621,92 +1564,7 @@ int mainLoop( int argc, char **argv ) { // ADA // temporary visible aircraft "own ship" - acmodel_selector = new ssgSelector; - acmodel_pos = new ssgTransform; - - ssgEntity *acmodel_obj = NULL; - if (fgGetString("/sim/flight-model") == "ada") { - // ada exteranl aircraft model loading - if( !ship_pos[0]->getKid(0) ) { - // fall back to default - ssgEntity *acmodel_obj = ssgLoad( (char *)"glider.ac" ); - if( !acmodel_obj ) { - SG_LOG( SG_GENERAL, SG_ALERT, "FAILED to LOAD an AC model! ..." ); - exit(-1); - } - acmodel_pos->addKid( acmodel_obj ); - } else { - acmodel_obj = ship_pos[0]->getKid(0); - } - } else { - // default aircraft model loading - - // Get the model location, and load textures from the same - // directory. Use an absolute path for the model to avoid - // incompatibilities in different versions of PLIB. - string acmodel_path = - fgGetString("/sim/model/path", "Models/Geometry/glider.ac"); - SGPath full_model = globals->get_fg_root(); - full_model.append(acmodel_path); - - ssgTexturePath( (char *)full_model.dir().c_str() ); - acmodel_obj = ssgLoad( (char *)full_model.c_str() ); - if( !acmodel_obj ) { - // fall back to default - acmodel_obj = ssgLoad( (char *)"Models/Geometry/glider.ac" ); - if( !acmodel_obj ) { - SG_LOG( SG_GENERAL, SG_ALERT, "FAILED to LOAD an AC model! ..." ); - exit(-1); - } - } - } - - // find moving parts (if this is an MDL model) - flaps_selector = (ssgSelector*)fgFindNode( acmodel_obj, "FLAPS" ); - prop_selector = (ssgSelector*)fgFindNode( acmodel_obj, "PROP" ); - - acmodel_npropsettings = 0; - if (prop_selector != NULL) { - for (ssgEntity* kid = prop_selector->getKid(0); kid != NULL; - kid = prop_selector->getNextKid()) { - int prop_low, prop_high; - if ( sscanf(kid->getName(), "PROP_%d_%d", - &prop_low, &prop_high) == 2 ) { - prop_low = (int)((float)prop_low * (5000.0f / 32767.0f)); - prop_high = (int)((float)prop_high * (5000.0f / 32767.0f)); - acmodel_proprpms[acmodel_npropsettings][0] = prop_low ; - acmodel_proprpms[acmodel_npropsettings][1] = prop_high; - acmodel_npropsettings++; - - SG_LOG( SG_GENERAL, SG_INFO, "PROPELLER SETTING " << prop_low << - " " << prop_high ); - } - } - } - - // align the model properly for FGFS - ssgTransform *acmodel_align = new ssgTransform; - acmodel_align->addKid(acmodel_obj); - sgMat4 rot_matrix; - sgMat4 off_matrix; - sgMat4 res_matrix; - float h_rot = fgGetFloat("/sim/model/heading-offset-deg", 0.0); - float p_rot = fgGetFloat("/sim/model/roll-offset-deg", 0.0); - float r_rot = fgGetFloat("/sim/model/pitch-offset-deg", 0.0); - float x_off = fgGetFloat("/sim/model/x-offset-m", 0.0); - float y_off = fgGetFloat("/sim/model/y-offset-m", 0.0); - float z_off = fgGetFloat("/sim/model/z-offset-m", 0.0); - sgMakeRotMat4(rot_matrix, h_rot, p_rot, r_rot); - sgMakeTransMat4(off_matrix, x_off, y_off, z_off); - sgMultMat4(res_matrix, off_matrix, rot_matrix); - acmodel_align->setTransform(res_matrix); - - acmodel_pos->addKid( acmodel_align ); - acmodel_selector->addKid( acmodel_pos ); - //ssgFlatten( acmodel_obj ); - //ssgStripify( acmodel_selector ); - acmodel_selector->clrTraversalMaskBits( SSGTRAV_HOT ); - scene->addKid( acmodel_selector ); + current_model.init(); #ifdef FG_NETWORK_OLK // Do the network intialization diff --git a/src/Main/model.cxx b/src/Main/model.cxx new file mode 100644 index 000000000..1efb633f9 --- /dev/null +++ b/src/Main/model.cxx @@ -0,0 +1,191 @@ +// model.cxx - manage a 3D aircraft model. +// Written by David Megginson, started 2002. +// +// This file is in the Public Domain, and comes with no warranty. + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#include +#include + +#include "globals.hxx" +#include "fg_props.hxx" +#include "viewmgr.hxx" +#include "model.hxx" + +extern unsigned long int fgSimTime; // FIXME: this is ugly + +extern ssgRoot * scene; // FIXME: from main.cxx + +FGAircraftModel current_model; // FIXME: add to globals + + +static ssgEntity * +find_named_node (ssgEntity * node, const string &name) +{ + char * node_name = node->getName(); + if (node_name != 0 && name == node_name) + return node; + else if (node->isAKindOf(ssgTypeBranch())) { + int nKids = node->getNumKids(); + for (int i = 0; i < nKids; i++) { + ssgEntity * result = + find_named_node(((ssgBranch*)node)->getKid(i), name); + if (result != 0) + return result; + } + return 0; + } +} + +FGAircraftModel::FGAircraftModel () + : _object(0), + _selector(new ssgSelector), + _position(new ssgTransform), + _prop_position(0) +{ +} + +FGAircraftModel::~FGAircraftModel () +{ + // since the nodes are attached to the scene graph, they'll be + // deleted automatically +} + +void +FGAircraftModel::init () +{ + // TODO: optionally load an XML file with a pointer to the 3D object + // and placement and animation info + + // Load the 3D aircraft object itself + SGPath path = globals->get_fg_root(); + path.append(fgGetString("/sim/model/path", "Models/Geometry/glider.ac")); + ssgTexturePath((char *)path.dir().c_str()); + _object = ssgLoad((char *)path.c_str()); + if (_object == 0) { + _object = ssgLoad((char *)"Models/Geometry/glider.ac"); + if (_object == 0) + throw sg_exception("Failed to load an aircraft model"); + } + + // Find the propeller + ssgEntity * prop_node = find_named_node(_object, "Propeller"); + if (prop_node != 0) { + std::cout << "Found propeller node" << std::endl; + std::cout << "User data is " << int(prop_node->getUserData()) << std::endl; + _prop_position = new ssgTransform; + int nParents = prop_node->getNumParents(); + _prop_position->addKid(prop_node); + std::cout << "Found " << nParents << " parent(s)" << std::endl; + for (int i = 0; i < nParents; i++) { + ssgBranch * parent = prop_node->getParent(i); + parent->replaceKid(prop_node, _prop_position); + } + } else { + std::cout << "Did not find propeller node" << std::endl; + } + + // Set up the alignment node + ssgTransform * align = new ssgTransform; + align->addKid(_object); + sgMat4 rot_matrix; + sgMat4 off_matrix; + sgMat4 res_matrix; + float h_rot = fgGetFloat("/sim/model/heading-offset-deg", 0.0); + float p_rot = fgGetFloat("/sim/model/roll-offset-deg", 0.0); + float r_rot = fgGetFloat("/sim/model/pitch-offset-deg", 0.0); + float x_off = fgGetFloat("/sim/model/x-offset-m", 0.0); + float y_off = fgGetFloat("/sim/model/y-offset-m", 0.0); + float z_off = fgGetFloat("/sim/model/z-offset-m", 0.0); + sgMakeRotMat4(rot_matrix, h_rot, p_rot, r_rot); + sgMakeTransMat4(off_matrix, x_off, y_off, z_off); + sgMultMat4(res_matrix, off_matrix, rot_matrix); + align->setTransform(res_matrix); + + // Set up the position node + _position->addKid(align); + + // Set up the selector node + _selector->addKid(_position); + _selector->clrTraversalMaskBits(SSGTRAV_HOT); + scene->addKid(_selector); +} + +void +FGAircraftModel::bind () +{ +} + +void +FGAircraftModel::unbind () +{ +} + +void +FGAircraftModel::update (int dt) +{ + // START TEMPORARY KLUDGE + static float prop_rotation = 0; + static sgMat4 prop_matrix; + + _current_timestamp.stamp(); + long ms = (_current_timestamp - _last_timestamp) / 1000; + _last_timestamp.stamp(); + + double rpms = fgGetDouble("/engines/engine[0]/rpm") / 60000.0; + prop_rotation += (ms * rpms * 360); + while (prop_rotation >= 360) + prop_rotation -= 360; + // END TEMPORARY KLUDGE + + if (globals->get_viewmgr()->get_current() == 0 + && !fgGetBool("/sim/model/enable-interior")) { + _selector->select(false); + } else { + // TODO: use correct alignment in pilot + // view. + _selector->select(true); + FGViewerRPH *pilot_view = + (FGViewerRPH *)globals->get_viewmgr()->get_view( 0 ); + + sgMat4 sgTRANS; + sgMakeTransMat4( sgTRANS, pilot_view->get_view_pos() ); + + sgVec3 ownship_up; + sgSetVec3( ownship_up, 0.0, 0.0, 1.0); + + sgMat4 sgROT; + sgMakeRotMat4( sgROT, -90.0, ownship_up ); + + sgMat4 sgTUX; + sgCopyMat4( sgTUX, sgROT ); + sgPostMultMat4( sgTUX, pilot_view->get_VIEW_ROT() ); + sgPostMultMat4( sgTUX, sgTRANS ); + + sgCoord tuxpos; + sgSetCoord( &tuxpos, sgTUX ); + _position->setTransform( &tuxpos ); + + // START TEMPORARY KLUDGE + if (_prop_position != 0) { + double offset = fgGetDouble("/tmp/offset", -.75); + sgMat4 tmp; + sgMakeTransMat4(prop_matrix, 0, 0, offset); + sgMakeRotMat4(tmp, 0, 0, prop_rotation); + sgPostMultMat4(prop_matrix, tmp); + sgMakeTransMat4(tmp, 0, 0, -offset); + sgPostMultMat4(prop_matrix, tmp); + _prop_position->setTransform(prop_matrix); + } + // END_TEMPORARY KLUDGE + } +} + +// end of model.cxx diff --git a/src/Main/model.hxx b/src/Main/model.hxx new file mode 100644 index 000000000..ab2890585 --- /dev/null +++ b/src/Main/model.hxx @@ -0,0 +1,44 @@ +// model.hxx - manage a 3D aircraft model. +// Written by David Megginson, started 2002. +// +// This file is in the Public Domain, and comes with no warranty. + +#ifndef __MODEL_HXX +#define __MODEL_HXX 1 + +#ifndef __cplusplus +# error This library requires C++ +#endif + +#include "fgfs.hxx" +#include + +class FGAircraftModel : public FGSubsystem +{ +public: + + FGAircraftModel (); + virtual ~FGAircraftModel (); + + virtual void init (); + virtual void bind (); + virtual void unbind (); + virtual void update (int dt); + +private: + + ssgEntity * _object; + ssgSelector * _selector; + ssgTransform * _position; + + SGTimeStamp _last_timestamp; + SGTimeStamp _current_timestamp; + + ssgTransform * _prop_position; + +}; + +extern FGAircraftModel current_model; + +#endif // __MODEL_HXX +