I split the FGModelPlacement code out into it's own set of source files.
I created two versions of the fgLoad3DModel() routine. One that is
unecumbered by a panelnode dependency and one that is. acmodel.cxx is
the only place that needs to load an aircraft with instrument panels.
model.[ch]xx are now pretty much free to move over into simgear.
loader.[ch]xx should be able to follow closely behind.
This will be a big step towards being able to move the material management
code over into simgear.
#ifndef _FG_AIEntity_HXX
#define _FG_AIEntity_HXX
-#include <Model/model.hxx>
#include <plib/sg.h>
#include <plib/ssg.h>
+
#include <simgear/math/point3d.hxx>
+#include <Model/model.hxx>
+#include <Model/placement.hxx>
+
/*****************************************************************
*
string planepath = "Aircraft/c172/Models/c172-dpm.ac";
SGPath path = globals->get_fg_root();
path.append(planepath);
- aip.init( path.str(), planepath.c_str(), globals->get_props(),
- globals->get_sim_time_sec() );
+ ssgBranch *model = fgLoad3DModel( path.str(),
+ planepath.c_str(),
+ globals->get_props(),
+ globals->get_sim_time_sec() );
+ aip.init( model );
aip.setVisible(false); // This will be set to true once a valid ground elevation has been determined
globals->get_scenery()->get_scene_graph()->addKid(aip.getSceneGraph());
#include <Aircraft/aircraft.hxx>
#include <Controls/controls.hxx>
-#include <Model/model.hxx>
+#include <Model/placement.hxx>
#include <FDM/flight.hxx>
#include <FDM/LaRCsim/ls_cockpit.h>
#include <FDM/LaRCsim/ls_generic.h>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <Model/acmodel.hxx>
-#include <Model/model.hxx>
+#include <Model/placement.hxx>
#include "FGFDM.hpp"
#include "Atmosphere.hpp"
#include <FDM/LaRCsim/ls_interface.h>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
-#include <Model/model.hxx>
+#include <Model/placement.hxx>
#include <Model/acmodel.hxx>
#include "flight.hxx"
#include <simgear/math/vector.hxx>
#include <Main/globals.hxx>
#include <Model/acmodel.hxx>
-#include <Model/model.hxx>
+#include <Model/placement.hxx>
#include "viewer.hxx"
noinst_LIBRARIES = libModel.a
libModel_a_SOURCES = \
+ acmodel.cxx acmodel.hxx \
loader.cxx loader.hxx \
model.cxx model.hxx \
+ model_panel.cxx model_panel.hxx \
modelmgr.cxx modelmgr.hxx \
- acmodel.cxx acmodel.hxx \
- panelnode.cxx panelnode.hxx
+ panelnode.cxx panelnode.hxx \
+ placement.cxx placement.hxx
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
#include <Main/viewmgr.hxx>
#include <Scenery/scenery.hxx>
+#include "model_panel.hxx"
+#include "placement.hxx"
+
#include "acmodel.hxx"
-#include "model.hxx"
\f
_aircraft = new FGModelPlacement;
string path = fgGetString("/sim/model/path", "Models/Geometry/glider.ac");
try {
- _aircraft->init( globals->get_fg_root(),
- path,
- globals->get_props(),
- globals->get_sim_time_sec() );
+ ssgBranch *model = fgLoad3DModelPanel( globals->get_fg_root(),
+ path,
+ globals->get_props(),
+ globals->get_sim_time_sec() );
+ _aircraft->init( model );
} catch (const sg_exception &ex) {
SG_LOG(SG_GENERAL, SG_ALERT, "Failed to load aircraft from " << path);
SG_LOG(SG_GENERAL, SG_ALERT, "(Falling back to glider.ac.)");
- _aircraft->init( globals->get_fg_root(),
- "Models/Geometry/glider.ac",
- globals->get_props(),
- globals->get_sim_time_sec() );
+ ssgBranch *model = fgLoad3DModelPanel( globals->get_fg_root(),
+ "Models/Geometry/glider.ac",
+ globals->get_props(),
+ globals->get_sim_time_sec() );
+ _aircraft->init( model );
}
_scene->addKid(_aircraft->getSceneGraph());
_selector->addKid(_aircraft->getSceneGraph());
# include <config.h>
#endif
+#include <simgear/compiler.h>
+
#include <string.h> // for strcmp()
+#include <vector>
+
#include <plib/sg.h>
#include <plib/ssg.h>
#include <plib/ul.h>
-#include <simgear/compiler.h>
-#include <simgear/debug/logstream.hxx>
-#include <simgear/math/interpolater.hxx>
-#include <simgear/math/point3d.hxx>
-#include <simgear/math/sg_geodesy.hxx>
#include <simgear/misc/exception.hxx>
#include <simgear/misc/sg_path.hxx>
-#include <simgear/props/condition.hxx>
+#include <simgear/props/props.hxx>
#include <simgear/props/props_io.hxx>
#include <simgear/scene/model/animation.hxx>
-#include <simgear/scene/model/location.hxx>
-
-#include "panelnode.hxx"
#include "model.hxx"
+SG_USING_STD(vector);
+
\f
////////////////////////////////////////////////////////////////////////
/**
* Make an offset matrix from rotations and position offset.
*/
-static void
-make_offsets_matrix (sgMat4 * result, double h_rot, double p_rot, double r_rot,
- double x_off, double y_off, double z_off)
+void
+fgMakeOffsetsMatrix( sgMat4 * result, double h_rot, double p_rot, double r_rot,
+ double x_off, double y_off, double z_off )
{
sgMat4 rot_matrix;
sgMat4 pos_matrix;
}
-static void
-make_animation (ssgBranch * model,
- const char * name,
- vector<SGPropertyNode_ptr> &name_nodes,
- SGPropertyNode *prop_root,
- SGPropertyNode_ptr node,
- double sim_time_sec )
+void
+fgMakeAnimation( ssgBranch * model,
+ const char * name,
+ vector<SGPropertyNode_ptr> &name_nodes,
+ SGPropertyNode *prop_root,
+ SGPropertyNode_ptr node,
+ double sim_time_sec )
{
Animation * animation = 0;
const char * type = node->getStringValue("type", "none");
}
+
\f
////////////////////////////////////////////////////////////////////////
// Global functions.
ssgTransform * alignmainmodel = new ssgTransform;
alignmainmodel->addKid(model);
sgMat4 res_matrix;
- make_offsets_matrix(&res_matrix,
+ fgMakeOffsetsMatrix(&res_matrix,
props.getFloatValue("/offsets/heading-deg", 0.0),
props.getFloatValue("/offsets/roll-deg", 0.0),
props.getFloatValue("/offsets/pitch-deg", 0.0),
props.getFloatValue("/offsets/z-m", 0.0));
alignmainmodel->setTransform(res_matrix);
- // Load panels
unsigned int i;
- vector<SGPropertyNode_ptr> panel_nodes = props.getChildren("panel");
- for (i = 0; i < panel_nodes.size(); i++) {
- SG_LOG(SG_INPUT, SG_DEBUG, "Loading a panel");
- FGPanelNode * panel = new FGPanelNode(panel_nodes[i]);
- if (panel_nodes[i]->hasValue("name"))
- panel->setName((char *)panel_nodes[i]->getStringValue("name"));
- model->addKid(panel);
- }
// Load animations
vector<SGPropertyNode_ptr> animation_nodes = props.getChildren("animation");
const char * name = animation_nodes[i]->getStringValue("name", 0);
vector<SGPropertyNode_ptr> name_nodes =
animation_nodes[i]->getChildren("object-name");
- make_animation( model, name, name_nodes, prop_root, animation_nodes[i],
- sim_time_sec);
+ fgMakeAnimation( model, name, name_nodes, prop_root, animation_nodes[i],
+ sim_time_sec);
}
// Load sub-models
SGPropertyNode_ptr node = model_nodes[i];
ssgTransform * align = new ssgTransform;
sgMat4 res_matrix;
- make_offsets_matrix(&res_matrix,
+ fgMakeOffsetsMatrix(&res_matrix,
node->getFloatValue("offsets/heading-deg", 0.0),
node->getFloatValue("offsets/roll-deg", 0.0),
node->getFloatValue("offsets/pitch-deg", 0.0),
}
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of FGModelPlacement.
-////////////////////////////////////////////////////////////////////////
-
-FGModelPlacement::FGModelPlacement ()
- : _lon_deg(0),
- _lat_deg(0),
- _elev_ft(0),
- _roll_deg(0),
- _pitch_deg(0),
- _heading_deg(0),
- _selector(new ssgSelector),
- _position(new ssgTransform),
- _location(new FGLocation)
-{
-}
-
-FGModelPlacement::~FGModelPlacement ()
-{
-}
-
-void
-FGModelPlacement::init( const string &fg_root,
- const string &path,
- SGPropertyNode *prop_root,
- double sim_time_sec )
-{
- ssgBranch * model = fgLoad3DModel( fg_root, path, prop_root, sim_time_sec );
- if (model != 0)
- _position->addKid(model);
- _selector->addKid(_position);
- _selector->clrTraversalMaskBits(SSGTRAV_HOT);
-}
-
-void
-FGModelPlacement::update( const Point3D scenery_center )
-{
- _location->setPosition( _lon_deg, _lat_deg, _elev_ft );
- _location->setOrientation( _roll_deg, _pitch_deg, _heading_deg );
-
- sgCopyMat4( POS, _location->getTransformMatrix(scenery_center) );
-
- sgVec3 trans;
- sgCopyVec3(trans, _location->get_view_pos());
-
- for(int i = 0; i < 4; i++) {
- float tmp = POS[i][3];
- for( int j=0; j<3; j++ ) {
- POS[i][j] += (tmp * trans[j]);
- }
- }
- _position->setTransform(POS);
-}
-
-bool
-FGModelPlacement::getVisible () const
-{
- return (_selector->getSelect() != 0);
-}
-
-void
-FGModelPlacement::setVisible (bool visible)
-{
- _selector->select(visible);
-}
-
-void
-FGModelPlacement::setLongitudeDeg (double lon_deg)
-{
- _lon_deg = lon_deg;
-}
-
-void
-FGModelPlacement::setLatitudeDeg (double lat_deg)
-{
- _lat_deg = lat_deg;
-}
-
-void
-FGModelPlacement::setElevationFt (double elev_ft)
-{
- _elev_ft = elev_ft;
-}
-
-void
-FGModelPlacement::setPosition (double lon_deg, double lat_deg, double elev_ft)
-{
- _lon_deg = lon_deg;
- _lat_deg = lat_deg;
- _elev_ft = elev_ft;
-}
-
-void
-FGModelPlacement::setRollDeg (double roll_deg)
-{
- _roll_deg = roll_deg;
-}
-
-void
-FGModelPlacement::setPitchDeg (double pitch_deg)
-{
- _pitch_deg = pitch_deg;
-}
-
-void
-FGModelPlacement::setHeadingDeg (double heading_deg)
-{
- _heading_deg = heading_deg;
-}
-
-void
-FGModelPlacement::setOrientation (double roll_deg, double pitch_deg,
- double heading_deg)
-{
- _roll_deg = roll_deg;
- _pitch_deg = pitch_deg;
- _heading_deg = heading_deg;
-}
-
// end of model.cxx
#include <plib/sg.h>
#include <plib/ssg.h>
-#include <simgear/math/point3d.hxx>
#include <simgear/props/props.hxx>
-// Don't pull in the headers, since we don't need them here.
-class ssgBranch;
-class ssgCutout;
-class ssgEntity;
-class ssgRangeSelector;
-class ssgSelector;
-class ssgTransform;
-
-class SGInterpTable;
-class FGCondition;
-class FGLocation;
-
-
// Has anyone done anything *really* stupid, like making min and max macros?
#ifdef min
#undef min
/**
- * Load a 3D model with or without XML wrapper.
+ * Load a 3D model with or without XML wrapper. Note, this version
+ * Does not know about or load the panel/cockpit information. Use the
+ * "model_panel.hxx" version if you want to load an aircraft
+ * (i.e. ownship) with a panel.
*
* If the path ends in ".xml", then it will be used as a property-
* list wrapper to add animations to the model.
SGPropertyNode *prop_root, double sim_time_sec );
-////////////////////////////////////////////////////////////////////////
-// Model placement.
-////////////////////////////////////////////////////////////////////////
-
/**
- * A wrapper for a model with a definite placement.
+ * Make an offset matrix from rotations and position offset.
*/
-class FGModelPlacement
-{
-public:
-
- FGModelPlacement ();
- virtual ~FGModelPlacement ();
-
- virtual void init( const string &fg_root,
- const string &path,
- SGPropertyNode *prop_root,
- double sim_time_sec );
- virtual void update( const Point3D scenery_center );
-
- virtual ssgEntity * getSceneGraph () { return (ssgEntity *)_selector; }
-
- virtual FGLocation * getFGLocation () { return _location; }
-
- 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 setLongitudeDeg (double lon_deg);
- virtual void setLatitudeDeg (double lat_deg);
- virtual void setElevationFt (double elev_ft);
- virtual void setPosition (double lon_deg, double lat_deg, double elev_ft);
+void
+fgMakeOffsetsMatrix( sgMat4 * result, double h_rot, double p_rot, double r_rot,
+ double x_off, double y_off, double z_off );
- virtual double getRollDeg () const { return _roll_deg; }
- virtual double getPitchDeg () const { return _pitch_deg; }
- virtual double getHeadingDeg () const { return _heading_deg; }
-
- virtual void setRollDeg (double roll_deg);
- virtual void setPitchDeg (double pitch_deg);
- virtual void setHeadingDeg (double heading_deg);
- virtual void setOrientation (double roll_deg, double pitch_deg,
- double heading_deg);
-
- // Addition by Diarmuid Tyson for Multiplayer Support
- // Allows multiplayer to get players position transform
- virtual const sgVec4 *get_POS() { return POS; }
-
-private:
-
- // Geodetic position
- double _lon_deg;
- double _lat_deg;
- double _elev_ft;
-
- // Orientation
- double _roll_deg;
- double _pitch_deg;
- double _heading_deg;
-
- ssgSelector * _selector;
- ssgTransform * _position;
-
- // Location
- FGLocation * _location;
-
-
- // Addition by Diarmuid Tyson for Multiplayer Support
- // Moved from update method
- // POS for transformation Matrix
- sgMat4 POS;
+/**
+ * Make the animation
+ */
+void
+fgMakeAnimation( ssgBranch * model,
+ const char * name,
+ vector<SGPropertyNode_ptr> &name_nodes,
+ SGPropertyNode *prop_root,
+ SGPropertyNode_ptr node,
+ double sim_time_sec );
-};
#endif // __MODEL_HXX
--- /dev/null
+// 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 <simgear/compiler.h>
+
+#include <string.h> // for strcmp()
+
+#include <vector>
+
+#include <plib/sg.h>
+#include <plib/ssg.h>
+#include <plib/ul.h>
+
+#include <simgear/misc/exception.hxx>
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/props/props.hxx>
+#include <simgear/props/props_io.hxx>
+#include <simgear/scene/model/animation.hxx>
+
+#include "panelnode.hxx"
+
+#include "model.hxx"
+#include "model_panel.hxx"
+
+SG_USING_STD(vector);
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Global functions.
+////////////////////////////////////////////////////////////////////////
+
+// FIXME: should attempt to share more of the code with
+// fgLoad3DModel() since these routines are almost identical with the
+// exception of the panel node section.
+
+ssgBranch *
+fgLoad3DModelPanel( const string &fg_root, const string &path,
+ SGPropertyNode *prop_root,
+ double sim_time_sec )
+{
+ ssgBranch * model = 0;
+ SGPropertyNode props;
+
+ // Load the 3D aircraft object itself
+ SGPath xmlpath;
+ SGPath modelpath = path;
+ if ( ulIsAbsolutePathName( path.c_str() ) ) {
+ xmlpath = modelpath;
+ }
+ else {
+ xmlpath = fg_root;
+ 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 {
+ if (model == 0)
+ model = new ssgBranch;
+ }
+ }
+
+ // Assume that textures are in
+ // the same location as the XML file.
+ if (model == 0) {
+ ssgTexturePath((char *)xmlpath.dir().c_str());
+ model = (ssgBranch *)ssgLoad((char *)modelpath.c_str());
+ if (model == 0)
+ throw sg_exception("Failed to load 3D model");
+ }
+
+ // Set up the alignment node
+ ssgTransform * alignmainmodel = new ssgTransform;
+ alignmainmodel->addKid(model);
+ sgMat4 res_matrix;
+ fgMakeOffsetsMatrix(&res_matrix,
+ props.getFloatValue("/offsets/heading-deg", 0.0),
+ props.getFloatValue("/offsets/roll-deg", 0.0),
+ props.getFloatValue("/offsets/pitch-deg", 0.0),
+ props.getFloatValue("/offsets/x-m", 0.0),
+ props.getFloatValue("/offsets/y-m", 0.0),
+ props.getFloatValue("/offsets/z-m", 0.0));
+ alignmainmodel->setTransform(res_matrix);
+
+ unsigned int i;
+
+ // Load panels
+ vector<SGPropertyNode_ptr> panel_nodes = props.getChildren("panel");
+ for (i = 0; i < panel_nodes.size(); i++) {
+ SG_LOG(SG_INPUT, SG_DEBUG, "Loading a panel");
+ FGPanelNode * panel = new FGPanelNode(panel_nodes[i]);
+ if (panel_nodes[i]->hasValue("name"))
+ panel->setName((char *)panel_nodes[i]->getStringValue("name"));
+ model->addKid(panel);
+ }
+
+ // Load animations
+ vector<SGPropertyNode_ptr> animation_nodes = props.getChildren("animation");
+ for (i = 0; i < animation_nodes.size(); i++) {
+ const char * name = animation_nodes[i]->getStringValue("name", 0);
+ vector<SGPropertyNode_ptr> name_nodes =
+ animation_nodes[i]->getChildren("object-name");
+ fgMakeAnimation( model, name, name_nodes, prop_root, animation_nodes[i],
+ sim_time_sec);
+ }
+
+ // Load sub-models
+ vector<SGPropertyNode_ptr> model_nodes = props.getChildren("model");
+ for (i = 0; i < model_nodes.size(); i++) {
+ SGPropertyNode_ptr node = model_nodes[i];
+ ssgTransform * align = new ssgTransform;
+ sgMat4 res_matrix;
+ fgMakeOffsetsMatrix(&res_matrix,
+ node->getFloatValue("offsets/heading-deg", 0.0),
+ node->getFloatValue("offsets/roll-deg", 0.0),
+ node->getFloatValue("offsets/pitch-deg", 0.0),
+ node->getFloatValue("offsets/x-m", 0.0),
+ node->getFloatValue("offsets/y-m", 0.0),
+ node->getFloatValue("offsets/z-m", 0.0));
+ align->setTransform(res_matrix);
+
+ ssgBranch * kid = fgLoad3DModel( fg_root, node->getStringValue("path"),
+ prop_root, sim_time_sec );
+ align->addKid(kid);
+ model->addKid(align);
+ }
+
+ return alignmainmodel;
+}
+
+
+// end of model_panel.cxx
--- /dev/null
+// 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 <vector>
+
+SG_USING_STD(vector);
+
+#include <plib/sg.h>
+#include <plib/ssg.h>
+
+#include <simgear/math/point3d.hxx>
+#include <simgear/props/props.hxx>
+
+
+// Don't pull in the headers, since we don't need them here.
+class ssgBranch;
+class ssgCutout;
+class ssgEntity;
+class ssgRangeSelector;
+class ssgSelector;
+class ssgTransform;
+
+class SGInterpTable;
+class FGCondition;
+class FGLocation;
+
+
+// Has anyone done anything *really* stupid, like making min and max macros?
+#ifdef min
+#undef min
+#endif
+#ifdef max
+#undef max
+#endif
+
+
+/**
+ * Load a 3D model with or without XML wrapper. This version supports
+ * also loading the instrument panel and is wired in with dependencies
+ * on panelnode.hxx, and thus files in src/Cockpit and also GUI/mouse
+ * input code to support the 3d clickable hotspots.
+ *
+ * If the path ends in ".xml", then it will be used as a property-
+ * list wrapper to add animations to the model.
+ *
+ * Subsystems should not normally invoke this function directly;
+ * instead, they should use the FGModelLoader declared in loader.hxx.
+ */
+ssgBranch *fgLoad3DModelPanel( const string& fg_root, const string &path,
+ SGPropertyNode *prop_root,
+ double sim_time_sec );
+
+
+#endif // __MODEL_HXX
#include <Main/fg_props.hxx>
#include <Scenery/scenery.hxx>
-#include "modelmgr.hxx"
#include "model.hxx"
+#include "placement.hxx"
+
+#include "modelmgr.hxx"
FGModelMgr::FGModelMgr ()
SG_LOG(SG_GENERAL, SG_INFO,
"Adding model " << node->getStringValue("name", "[unnamed]"));
Instance * instance = new Instance;
- FGModelPlacement * model = new FGModelPlacement;
+ FGModelPlacement *model = new FGModelPlacement;
instance->model = model;
- model->init( globals->get_fg_root(),
- node->getStringValue("path", "Models/Geometry/glider.ac"),
- globals->get_props(),
- globals->get_sim_time_sec() );
+ ssgBranch *object
+ = fgLoad3DModel( globals->get_fg_root(),
+ node->getStringValue("path",
+ "Models/Geometry/glider.ac"),
+ globals->get_props(),
+ globals->get_sim_time_sec() );
+ model->init( object );
// Set position and orientation either
// indirectly through property refs
--- /dev/null
+// placement.cxx - manage the placment of a 3D model.
+// Written by David Megginson, started 2002.
+//
+// This file is in the Public Domain, and comes with no warranty.
+
+#include <simgear/compiler.h>
+
+#include <string.h> // for strcmp()
+
+#include <vector>
+
+#include <plib/sg.h>
+#include <plib/ssg.h>
+#include <plib/ul.h>
+
+#include <simgear/scene/model/location.hxx>
+
+#include "model.hxx"
+
+#include "placement.hxx"
+
+SG_USING_STD(vector);
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGModelPlacement.
+////////////////////////////////////////////////////////////////////////
+
+FGModelPlacement::FGModelPlacement ()
+ : _lon_deg(0),
+ _lat_deg(0),
+ _elev_ft(0),
+ _roll_deg(0),
+ _pitch_deg(0),
+ _heading_deg(0),
+ _selector(new ssgSelector),
+ _position(new ssgTransform),
+ _location(new FGLocation)
+{
+}
+
+FGModelPlacement::~FGModelPlacement ()
+{
+}
+
+#if 0
+void
+FGModelPlacement::init( const string &fg_root,
+ const string &path,
+ SGPropertyNode *prop_root,
+ double sim_time_sec, int dummy )
+{
+ ssgBranch * model = fgLoad3DModel( fg_root, path, prop_root, sim_time_sec );
+ if (model != 0)
+ _position->addKid(model);
+ _selector->addKid(_position);
+ _selector->clrTraversalMaskBits(SSGTRAV_HOT);
+}
+#endif
+
+void
+FGModelPlacement::init( ssgBranch * model )
+{
+ if (model != 0) {
+ _position->addKid(model);
+ }
+ _selector->addKid(_position);
+ _selector->clrTraversalMaskBits(SSGTRAV_HOT);
+}
+
+void
+FGModelPlacement::update( const Point3D scenery_center )
+{
+ _location->setPosition( _lon_deg, _lat_deg, _elev_ft );
+ _location->setOrientation( _roll_deg, _pitch_deg, _heading_deg );
+
+ sgCopyMat4( POS, _location->getTransformMatrix(scenery_center) );
+
+ sgVec3 trans;
+ sgCopyVec3(trans, _location->get_view_pos());
+
+ for(int i = 0; i < 4; i++) {
+ float tmp = POS[i][3];
+ for( int j=0; j<3; j++ ) {
+ POS[i][j] += (tmp * trans[j]);
+ }
+ }
+ _position->setTransform(POS);
+}
+
+bool
+FGModelPlacement::getVisible () const
+{
+ return (_selector->getSelect() != 0);
+}
+
+void
+FGModelPlacement::setVisible (bool visible)
+{
+ _selector->select(visible);
+}
+
+void
+FGModelPlacement::setLongitudeDeg (double lon_deg)
+{
+ _lon_deg = lon_deg;
+}
+
+void
+FGModelPlacement::setLatitudeDeg (double lat_deg)
+{
+ _lat_deg = lat_deg;
+}
+
+void
+FGModelPlacement::setElevationFt (double elev_ft)
+{
+ _elev_ft = elev_ft;
+}
+
+void
+FGModelPlacement::setPosition (double lon_deg, double lat_deg, double elev_ft)
+{
+ _lon_deg = lon_deg;
+ _lat_deg = lat_deg;
+ _elev_ft = elev_ft;
+}
+
+void
+FGModelPlacement::setRollDeg (double roll_deg)
+{
+ _roll_deg = roll_deg;
+}
+
+void
+FGModelPlacement::setPitchDeg (double pitch_deg)
+{
+ _pitch_deg = pitch_deg;
+}
+
+void
+FGModelPlacement::setHeadingDeg (double heading_deg)
+{
+ _heading_deg = heading_deg;
+}
+
+void
+FGModelPlacement::setOrientation (double roll_deg, double pitch_deg,
+ double heading_deg)
+{
+ _roll_deg = roll_deg;
+ _pitch_deg = pitch_deg;
+ _heading_deg = heading_deg;
+}
+
+// end of model.cxx
--- /dev/null
+// placement.hxx - manage the placment of a 3D model.
+// Written by David Megginson, started 2002.
+//
+// This file is in the Public Domain, and comes with no warranty.
+
+
+#ifndef _SG_PLACEMENT_HXX
+#define _SG_PLACEMENT_HXX 1
+
+#ifndef __cplusplus
+# error This library requires C++
+#endif
+
+#include <vector>
+
+SG_USING_STD(vector);
+
+#include <plib/sg.h>
+#include <plib/ssg.h>
+
+#include <simgear/math/point3d.hxx>
+#include <simgear/props/props.hxx>
+
+
+// Don't pull in the headers, since we don't need them here.
+class FGLocation;
+
+
+// Has anyone done anything *really* stupid, like making min and max macros?
+#ifdef min
+#undef min
+#endif
+#ifdef max
+#undef max
+#endif
+
+
+////////////////////////////////////////////////////////////////////////
+// Model placement.
+////////////////////////////////////////////////////////////////////////
+
+/**
+ * A wrapper for a model with a definite placement.
+ */
+class FGModelPlacement
+{
+public:
+
+ FGModelPlacement ();
+ virtual ~FGModelPlacement ();
+
+ virtual void FGModelPlacement::init( ssgBranch * model );
+ /* virtual void init( const string &fg_root,
+ const string &path,
+ SGPropertyNode *prop_root,
+ double sim_time_sec, int dummy ); */
+ virtual void update( const Point3D scenery_center );
+
+ virtual ssgEntity * getSceneGraph () { return (ssgEntity *)_selector; }
+
+ virtual FGLocation * getFGLocation () { return _location; }
+
+ 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 setLongitudeDeg (double lon_deg);
+ virtual void setLatitudeDeg (double lat_deg);
+ virtual void setElevationFt (double elev_ft);
+ virtual void setPosition (double lon_deg, double lat_deg, double elev_ft);
+
+ virtual double getRollDeg () const { return _roll_deg; }
+ virtual double getPitchDeg () const { return _pitch_deg; }
+ virtual double getHeadingDeg () const { return _heading_deg; }
+
+ virtual void setRollDeg (double roll_deg);
+ virtual void setPitchDeg (double pitch_deg);
+ virtual void setHeadingDeg (double heading_deg);
+ virtual void setOrientation (double roll_deg, double pitch_deg,
+ double heading_deg);
+
+ // Addition by Diarmuid Tyson for Multiplayer Support
+ // Allows multiplayer to get players position transform
+ virtual const sgVec4 *get_POS() { return POS; }
+
+private:
+
+ // Geodetic position
+ double _lon_deg;
+ double _lat_deg;
+ double _elev_ft;
+
+ // Orientation
+ double _roll_deg;
+ double _pitch_deg;
+ double _heading_deg;
+
+ ssgSelector * _selector;
+ ssgTransform * _position;
+
+ // Location
+ FGLocation * _location;
+
+
+ // Addition by Diarmuid Tyson for Multiplayer Support
+ // Moved from update method
+ // POS for transformation Matrix
+ sgMat4 POS;
+
+};
+
+#endif // _SG_PLACEMENT_HXX
#include <simgear/debug/logstream.hxx>
+#include <Model/placement.hxx>
+
#include "multiplay.hxx"
SG_USING_STD(string);