Separated 3D model-handling code from main.cxx out into its own
subsystem, FGAircraftModel.
This commit is contained in:
parent
a9a30bfd80
commit
d61ce30c12
4 changed files with 239 additions and 145 deletions
|
@ -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 \
|
||||
|
|
|
@ -151,6 +151,7 @@ sgVec3 rway_ols;
|
|||
#include "splash.hxx"
|
||||
#include "viewmgr.hxx"
|
||||
#include "options.hxx"
|
||||
#include "model.hxx"
|
||||
|
||||
#ifdef macintosh
|
||||
# include <console.h> // -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
|
||||
|
|
191
src/Main/model.cxx
Normal file
191
src/Main/model.cxx
Normal file
|
@ -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 <config.h>
|
||||
#endif
|
||||
|
||||
#include <plib/sg.h>
|
||||
#include <plib/ssg.h>
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/exception.hxx>
|
||||
|
||||
#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
|
44
src/Main/model.hxx
Normal file
44
src/Main/model.hxx
Normal file
|
@ -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 <simgear/timing/timestamp.hxx>
|
||||
|
||||
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
|
||||
|
Loading…
Add table
Reference in a new issue