1
0
Fork 0

Moved FGAircraftModel subsystem out into its own directory, and

separated out a new class, FG3DModel, that allows any arbitrary 3D
model to be positioned, oriented, and animated (not just the
aircraft).
This commit is contained in:
david 2002-04-05 03:19:34 +00:00
parent 59107c791c
commit 625572663e
11 changed files with 328 additions and 137 deletions

View file

@ -48,7 +48,6 @@ fgfs_SOURCES = \
fgfs.cxx fgfs.hxx \
globals.cxx globals.hxx \
logger.cxx logger.hxx \
model.cxx model.hxx \
options.cxx options.hxx \
splash.cxx splash.hxx \
viewer.cxx viewer.hxx \
@ -68,6 +67,7 @@ fgfs_LDADD = \
$(top_builddir)/src/FDM/LaRCsim/libLaRCsim.a \
$(top_builddir)/src/FDM/UIUCModel/libUIUCModel.a \
$(top_builddir)/src/GUI/libGUI.a \
$(top_builddir)/src/Model/libModel.a \
$(top_builddir)/src/Navaids/libNavaids.a \
$(top_builddir)/src/Scenery/libScenery.a \
$(top_builddir)/src/Sound/libSound.a \

View file

@ -61,11 +61,6 @@ main.cxx
methods; eventually, this will be a short, simple file defining the
top-level flow logic of the program.
model.cxx
model.hxx
This module defines the FGAircraftModel subsystem, which controls
the display and animation of 3D models in FlightGear.
options.cxx
options.hxx
This module defines global functions for parsing command-line

View file

@ -96,6 +96,7 @@ SG_USING_STD(endl);
#include <FDM/UIUCModel/uiuc_aircraftdir.h>
#include <GUI/gui.h>
#include <Model/acmodel.hxx>
#ifdef FG_NETWORK_OLK
#include <NetworkOLK/network.h>
#endif
@ -163,7 +164,6 @@ float scene_farplane = 120000.0f;
#include "viewmgr.hxx"
#include "options.hxx"
#include "logger.hxx"
#include "model.hxx"
#ifdef macintosh
# include <console.h> // -dw- for command line dialog

View file

@ -21,6 +21,7 @@ SUBDIRS = \
FDM \
GUI \
Input \
Model \
Navaids \
$(NETWORK_DIRS) \
Objects \

3
src/Model/.cvsignore Normal file
View file

@ -0,0 +1,3 @@
.deps
Makefile
Makefile.in

10
src/Model/Makefile.am Normal file
View file

@ -0,0 +1,10 @@
noinst_LIBRARIES = libModel.a
libModel_a_SOURCES = model.cxx model.hxx \
acmodel.cxx acmodel.hxx
if OLD_AUTOMAKE
INCLUDES += -I$(top_srcdir) -I$(top_srcdir)/src
else
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
endif

14
src/Model/README Normal file
View file

@ -0,0 +1,14 @@
Last updated $Date$
This directory contains code for loading, positioning, orienting, and
animating 3D models.
acmodel.cxx
acmodel.hxx
This module defines the FGAircraftModel subsystem, which manages the 3D
model representing the aircraft the user is flying.
model.cxx
model.hxx
This module defines the FG3DModel class, which represents any 3D
model in the FlightGear world.

87
src/Model/acmodel.cxx Normal file
View file

@ -0,0 +1,87 @@
// 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 <string.h> // for strcmp()
#include <plib/sg.h>
#include <plib/ssg.h>
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/exception.hxx>
#include <simgear/misc/sg_path.hxx>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <Main/viewmgr.hxx>
#include "acmodel.hxx"
extern ssgRoot * cockpit; // FIXME: from main.cxx
FGAircraftModel current_model; // FIXME: add to globals
////////////////////////////////////////////////////////////////////////
// Implementation of FGAircraftModel
////////////////////////////////////////////////////////////////////////
FGAircraftModel::FGAircraftModel ()
: _aircraft(0)
{
}
FGAircraftModel::~FGAircraftModel ()
{
delete _aircraft;
}
void
FGAircraftModel::init ()
{
_aircraft = new FG3DModel;
_aircraft->init(fgGetString("/sim/model/path", "Models/Geometry/glider.ac"));
cockpit->addKid(_aircraft->getSceneGraph());
}
void
FGAircraftModel::bind ()
{
// No-op
}
void
FGAircraftModel::unbind ()
{
// No-op
}
void
FGAircraftModel::update (int dt)
{
int view_number = globals->get_viewmgr()->get_current();
if (view_number == 0 && !fgGetBool("/sim/view/internal")) {
_aircraft->setVisible(false);
return;
}
_aircraft->setVisible(true);
_aircraft->setPosition(fgGetDouble("/position/longitude-deg"),
fgGetDouble("/position/latitude-deg"),
fgGetDouble("/position/altitude-ft"));
_aircraft->setOrientation(fgGetDouble("/orientation/roll-deg"),
fgGetDouble("/orientation/pitch-deg"),
fgGetDouble("/orientation/heading-deg"));
_aircraft->update(dt);
}
// end of model.cxx

46
src/Model/acmodel.hxx Normal file
View file

@ -0,0 +1,46 @@
// 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 __ACMODEL_HXX
#define __ACMODEL_HXX 1
#ifndef __cplusplus
# error This library requires C++
#endif
#include <vector>
SG_USING_STD(string);
SG_USING_STD(vector);
#include <simgear/misc/props.hxx>
#include <Main/fgfs.hxx>
#include "model.hxx"
class FGAircraftModel : public FGSubsystem
{
public:
FGAircraftModel ();
virtual ~FGAircraftModel ();
virtual void init ();
virtual void bind ();
virtual void unbind ();
virtual void update (int dt);
private:
FG3DModel * _aircraft;
};
extern FGAircraftModel current_model;
#endif // __ACMODEL_HXX

View file

@ -14,18 +14,16 @@
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/point3d.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/misc/exception.hxx>
#include <simgear/misc/sg_path.hxx>
#include "globals.hxx"
#include "fg_props.hxx"
#include "viewmgr.hxx"
#include <Main/globals.hxx>
#include <Scenery/scenery.hxx>
#include "model.hxx"
extern ssgRoot * cockpit; // FIXME: from main.cxx
FGAircraftModel current_model; // FIXME: add to globals
////////////////////////////////////////////////////////////////////////
@ -124,19 +122,62 @@ set_translation (sgMat4 &matrix, double position_m, sgVec3 &axis)
}
// TODO: once this is working, look at Norm's optimized version
static void
world_coordinate( sgCoord *obj_pos,
double lat_deg, double lon_deg, double elev_ft,
double roll_deg, double pitch_deg, double hdg_deg)
{
Point3D center = scenery.get_center();
// setup transforms
Point3D geod( lon_deg * SGD_DEGREES_TO_RADIANS,
lat_deg * SGD_DEGREES_TO_RADIANS,
elev_ft * SG_FEET_TO_METER);
Point3D world_pos = sgGeodToCart( geod );
Point3D offset = world_pos - center;
sgMat4 POS;
sgMakeTransMat4( POS, offset.x(), offset.y(), offset.z() );
sgVec3 obj_bk, obj_rt, obj_up;
sgSetVec3( obj_bk, 1.0, 0.0, 0.0); // X axis
sgSetVec3( obj_rt, 0.0, 1.0, 0.0); // Y axis
sgSetVec3( obj_up, 0.0, 0.0, 1.0); // Z axis
sgMat4 ROT_lon, ROT_lat, ROT_hdg, ROT_pitch, ROT_roll;
sgMakeRotMat4( ROT_lon, lon_deg, obj_up );
sgMakeRotMat4( ROT_lat, 90 - lat_deg, obj_rt );
sgMakeRotMat4( ROT_hdg, -hdg_deg, obj_up );
sgMakeRotMat4( ROT_pitch, pitch_deg, obj_rt );
sgMakeRotMat4( ROT_roll, -roll_deg, obj_bk );
sgMat4 TRANS;
sgCopyMat4( TRANS, ROT_roll );
sgPostMultMat4( TRANS, ROT_pitch );
sgPostMultMat4( TRANS, ROT_hdg );
sgPostMultMat4( TRANS, ROT_lat );
sgPostMultMat4( TRANS, ROT_lon );
sgPostMultMat4( TRANS, POS );
sgSetCoord( obj_pos, TRANS );
}
////////////////////////////////////////////////////////////////////////
// Implementation of FGAircraftModel
// Implementation of FG3DModel
////////////////////////////////////////////////////////////////////////
FGAircraftModel::FGAircraftModel ()
FG3DModel::FG3DModel ()
: _model(0),
_selector(new ssgSelector),
_position(new ssgTransform)
{
}
FGAircraftModel::~FGAircraftModel ()
FG3DModel::~FG3DModel ()
{
// since the nodes are attached to the scene graph, they'll be
// deleted automatically
@ -150,39 +191,32 @@ FGAircraftModel::~FGAircraftModel ()
}
void
FGAircraftModel::init ()
FG3DModel::init (const string &path)
{
// TODO: optionally load an XML file with a pointer to the 3D object
// and placement and animation info
SGPropertyNode props;
SG_LOG(SG_INPUT, SG_INFO, "Initializing aircraft 3D model");
// Load the 3D aircraft object itself
// DCL - the xml parser requires the full path but the ssgLoader doesn't
// so lets have two paths.
SGPath xmlpath = globals->get_fg_root();
SGPath modelpath = (string)fgGetString("/sim/model/path", "Models/Geometry/glider.ac");
SGPath modelpath = path;
xmlpath.append(modelpath.str());
// Check for an XML wrapper
if (xmlpath.str().substr(xmlpath.str().size() - 4, 4) == ".xml") {
readProperties(xmlpath.str(), &props);
if (props.hasValue("/path")) {
modelpath = modelpath.dir();
modelpath.append(props.getStringValue("/path"));
} else {
modelpath = "Models/Geometry/glider.ac";
throw sg_exception("No path for model");
}
}
// Assume that textures are in
// the same location as the XML file.
ssgTexturePath((char *)xmlpath.dir().c_str());
_model = ssgLoad((char *)modelpath.c_str());
if (_model == 0) {
_model = ssgLoad((char *)"Models/Geometry/glider.ac");
if (_model == 0)
throw sg_exception("Failed to load an aircraft model");
}
if (_model == 0)
throw sg_exception("Failed to load 3D model");
// Load animations
vector<SGPropertyNode *> animation_nodes = props.getChildren("animation");
@ -224,75 +258,53 @@ FGAircraftModel::init ()
// Set up the selector node
_selector->addKid(_position);
_selector->clrTraversalMaskBits(SSGTRAV_HOT);
cockpit->addKid(_selector);
}
void
FGAircraftModel::bind ()
{
}
void
FGAircraftModel::unbind ()
{
}
void
FGAircraftModel::update (int dt)
FG3DModel::update (int dt)
{
sgMat4 MODEL_ROT, LOCAL;
sgMat4 sgTRANS;
for (unsigned int i = 0; i < _animations.size(); i++)
_animations[i]->update(dt);
int view_number = globals->get_viewmgr()->get_current();
_selector->select(true);
if (view_number == 0 && !fgGetBool("/sim/view/internal")) {
_selector->select(false);
} else {
for (unsigned int i = 0; i < _animations.size(); i++)
_animations[i]->update(dt);
_selector->select(true);
FGViewer *current_view =
(FGViewer *)globals->get_viewmgr()->get_view( view_number );
// FIXME: this class needs to be unlinked from the viewer
// get transform for current position in the world...
sgMakeTransMat4( sgTRANS, current_view->getRelativeViewPos() );
// get a copy of the LOCAL rotation from the current view...
sgCopyMat4( LOCAL, current_view->get_LOCAL_ROT() );
// Make the MODEL Rotation (just reordering the LOCAL matrix
// and flipping the model over on its feet)...
MODEL_ROT[0][0] = -LOCAL[2][0];
MODEL_ROT[0][1] = -LOCAL[2][1];
MODEL_ROT[0][2] = -LOCAL[2][2];
MODEL_ROT[0][3] = SG_ZERO;
MODEL_ROT[1][0] = LOCAL[1][0];
MODEL_ROT[1][1] = LOCAL[1][1];
MODEL_ROT[1][2] = LOCAL[1][2];
MODEL_ROT[1][3] = SG_ZERO;
MODEL_ROT[2][0] = LOCAL[0][0];
MODEL_ROT[2][1] = LOCAL[0][1];
MODEL_ROT[2][2] = LOCAL[0][2];
MODEL_ROT[2][3] = SG_ZERO;
// add the position data to the matrix
MODEL_ROT[3][0] = SG_ZERO;
MODEL_ROT[3][1] = SG_ZERO;
MODEL_ROT[3][2] = SG_ZERO;
MODEL_ROT[3][3] = SG_ONE;
sgPostMultMat4( MODEL_ROT, sgTRANS );
sgCoord tuxpos;
sgSetCoord( &tuxpos, MODEL_ROT );
_position->setTransform( &tuxpos );
}
sgCoord obj_pos;
world_coordinate(&obj_pos, _lat_deg, _lon_deg, _elev_ft,
_roll_deg, _pitch_deg, _heading_deg);
_position->setTransform(&obj_pos);
}
FGAircraftModel::Animation *
FGAircraftModel::make_animation (const char * object_name,
bool
FG3DModel::getVisible () const
{
return _selector->getSelect();
}
void
FG3DModel::setVisible (bool visible)
{
_selector->select(visible);
}
void
FG3DModel::setPosition (double lon_deg, double lat_deg, double elev_ft)
{
_lon_deg = lon_deg;
_lat_deg = lat_deg;
_elev_ft = elev_ft;
}
void
FG3DModel::setOrientation (double roll_deg, double pitch_deg,
double heading_deg)
{
_roll_deg = roll_deg;
_pitch_deg = pitch_deg;
_heading_deg = heading_deg;
}
FG3DModel::Animation *
FG3DModel::make_animation (const char * object_name,
SGPropertyNode * node)
{
Animation * animation = 0;
@ -327,35 +339,35 @@ FGAircraftModel::make_animation (const char * object_name,
////////////////////////////////////////////////////////////////////////
// Implementation of FGAircraftModel::Animation
// Implementation of FG3DModel::Animation
////////////////////////////////////////////////////////////////////////
FGAircraftModel::Animation::Animation ()
FG3DModel::Animation::Animation ()
{
}
FGAircraftModel::Animation::~Animation ()
FG3DModel::Animation::~Animation ()
{
}
////////////////////////////////////////////////////////////////////////
// Implementation of FGAircraftModel::NullAnimation
// Implementation of FG3DModel::NullAnimation
////////////////////////////////////////////////////////////////////////
FGAircraftModel::NullAnimation::NullAnimation ()
FG3DModel::NullAnimation::NullAnimation ()
: _branch(new ssgBranch)
{
}
FGAircraftModel::NullAnimation::~NullAnimation ()
FG3DModel::NullAnimation::~NullAnimation ()
{
_branch = 0;
}
void
FGAircraftModel::NullAnimation::init (ssgEntity * object,
FG3DModel::NullAnimation::init (ssgEntity * object,
SGPropertyNode * props)
{
splice_branch(_branch, object);
@ -363,30 +375,30 @@ FGAircraftModel::NullAnimation::init (ssgEntity * object,
}
void
FGAircraftModel::NullAnimation::update (int dt)
FG3DModel::NullAnimation::update (int dt)
{
}
////////////////////////////////////////////////////////////////////////
// Implementation of FGAircraftModel::SelectAnimation
// Implementation of FG3DModel::SelectAnimation
////////////////////////////////////////////////////////////////////////
FGAircraftModel::SelectAnimation::SelectAnimation ()
FG3DModel::SelectAnimation::SelectAnimation ()
: _condition(0),
_selector(new ssgSelector)
{
}
FGAircraftModel::SelectAnimation::~SelectAnimation ()
FG3DModel::SelectAnimation::~SelectAnimation ()
{
delete _condition;
_selector = 0;
}
void
FGAircraftModel::SelectAnimation::init (ssgEntity * object,
FG3DModel::SelectAnimation::init (ssgEntity * object,
SGPropertyNode * props)
{
splice_branch(_selector, object);
@ -398,7 +410,7 @@ FGAircraftModel::SelectAnimation::init (ssgEntity * object,
}
void
FGAircraftModel::SelectAnimation::update (int dt)
FG3DModel::SelectAnimation::update (int dt)
{
if (_condition != 0 && _condition->test())
_selector->select(0xffff);
@ -409,10 +421,10 @@ FGAircraftModel::SelectAnimation::update (int dt)
////////////////////////////////////////////////////////////////////////
// Implementation of FGAircraftModel::SpinAnimation
// Implementation of FG3DModel::SpinAnimation
////////////////////////////////////////////////////////////////////////
FGAircraftModel::SpinAnimation::SpinAnimation ()
FG3DModel::SpinAnimation::SpinAnimation ()
: _prop(0),
_factor(0),
_position_deg(0),
@ -420,13 +432,13 @@ FGAircraftModel::SpinAnimation::SpinAnimation ()
{
}
FGAircraftModel::SpinAnimation::~SpinAnimation ()
FG3DModel::SpinAnimation::~SpinAnimation ()
{
_transform = 0;
}
void
FGAircraftModel::SpinAnimation::init (ssgEntity * object,
FG3DModel::SpinAnimation::init (ssgEntity * object,
SGPropertyNode * props)
{
// Splice in the new transform node
@ -445,7 +457,7 @@ FGAircraftModel::SpinAnimation::init (ssgEntity * object,
}
void
FGAircraftModel::SpinAnimation::update (int dt)
FG3DModel::SpinAnimation::update (int dt)
{
float velocity_rpms = (_prop->getDoubleValue() * _factor / 60000.0);
_position_deg += (dt * velocity_rpms * 360);
@ -460,10 +472,10 @@ FGAircraftModel::SpinAnimation::update (int dt)
////////////////////////////////////////////////////////////////////////
// Implementation of FGAircraftModel::RotateAnimation
// Implementation of FG3DModel::RotateAnimation
////////////////////////////////////////////////////////////////////////
FGAircraftModel::RotateAnimation::RotateAnimation ()
FG3DModel::RotateAnimation::RotateAnimation ()
: _prop(0),
_offset_deg(0.0),
_factor(1.0),
@ -476,13 +488,13 @@ FGAircraftModel::RotateAnimation::RotateAnimation ()
{
}
FGAircraftModel::RotateAnimation::~RotateAnimation ()
FG3DModel::RotateAnimation::~RotateAnimation ()
{
_transform = 0;
}
void
FGAircraftModel::RotateAnimation::init (ssgEntity * object,
FG3DModel::RotateAnimation::init (ssgEntity * object,
SGPropertyNode * props)
{
// Splice in the new transform node
@ -510,7 +522,7 @@ FGAircraftModel::RotateAnimation::init (ssgEntity * object,
}
void
FGAircraftModel::RotateAnimation::update (int dt)
FG3DModel::RotateAnimation::update (int dt)
{
_position_deg = ((_prop->getDoubleValue() + _offset_deg) * _factor);
if (_has_min && _position_deg < _min_deg)
@ -524,10 +536,10 @@ FGAircraftModel::RotateAnimation::update (int dt)
////////////////////////////////////////////////////////////////////////
// Implementation of FGAircraftModel::TranslateAnimation
// Implementation of FG3DModel::TranslateAnimation
////////////////////////////////////////////////////////////////////////
FGAircraftModel::TranslateAnimation::TranslateAnimation ()
FG3DModel::TranslateAnimation::TranslateAnimation ()
: _prop(0),
_offset_m(0.0),
_factor(1.0),
@ -540,13 +552,13 @@ FGAircraftModel::TranslateAnimation::TranslateAnimation ()
{
}
FGAircraftModel::TranslateAnimation::~TranslateAnimation ()
FG3DModel::TranslateAnimation::~TranslateAnimation ()
{
_transform = 0;
}
void
FGAircraftModel::TranslateAnimation::init (ssgEntity * object,
FG3DModel::TranslateAnimation::init (ssgEntity * object,
SGPropertyNode * props)
{
// Splice in the new transform node
@ -571,7 +583,7 @@ FGAircraftModel::TranslateAnimation::init (ssgEntity * object,
}
void
FGAircraftModel::TranslateAnimation::update (int dt)
FG3DModel::TranslateAnimation::update (int dt)
{
_position_m = ((_prop->getDoubleValue() + _offset_m) * _factor);
if (_has_min && _position_m < _min_m)

View file

@ -10,15 +10,11 @@
# error This library requires C++
#endif
#include <string>
#include <vector>
SG_USING_STD(string);
SG_USING_STD(vector);
#include "fgfs.hxx"
#include <simgear/misc/props.hxx>
#include <simgear/timing/timestamp.hxx>
#include <Main/fg_props.hxx>
// Has anyone done anything *really* stupid, like making min and max macros?
#ifdef min
@ -28,30 +24,59 @@ SG_USING_STD(vector);
#undef max
#endif
class FGAircraftModel : public FGSubsystem
class FG3DModel
{
public:
FGAircraftModel ();
virtual ~FGAircraftModel ();
FG3DModel ();
virtual ~FG3DModel ();
virtual void init ();
virtual void bind ();
virtual void unbind ();
virtual void init (const string &path);
virtual void update (int dt);
virtual bool getVisible () const;
virtual void setVisible (bool visible);
virtual double getLongitudeDeg () const { return _lon_deg; }
virtual double getLatitudeDeg () const { return _lat_deg; }
virtual double getElevationFt () const { return _elev_ft; }
virtual void setPosition (double lon_deg, double lat_deg, double elev_ft);
virtual double getRoll () const { return _roll_deg; }
virtual double getPitch () const { return _pitch_deg; }
virtual double getHeading () const { return _heading_deg; }
virtual void setOrientation (double roll_deg, double pitch_deg,
double heading_deg);
virtual ssgEntity * getSceneGraph () const { return _selector; }
private:
class Animation;
Animation * make_animation (const char * object_name, SGPropertyNode * node);
// Geodetic position
double _lon_deg;
double _lat_deg;
double _elev_ft;
// Orientation
double _roll_deg;
double _pitch_deg;
double _heading_deg;
// Animations
vector <Animation *> _animations;
// Scene graph
ssgEntity * _model;
ssgSelector * _selector;
ssgTransform * _position;
vector <Animation *> _animations;
//////////////////////////////////////////////////////////////////////
@ -196,7 +221,5 @@ private:
};
extern FGAircraftModel current_model;
#endif // __MODEL_HXX