#include <plib/sg.h>
#include <plib/ssg.h>
+#include <plib/ul.h>
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
*/
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)
+ double x_off, double y_off, double z_off)
{
sgMat4 rot_matrix;
sgMat4 pos_matrix;
* Read an interpolation table from properties.
*/
static SGInterpTable *
-read_interpolation_table (const SGPropertyNode * props)
+read_interpolation_table (SGPropertyNode_ptr props)
{
- const SGPropertyNode * table_node = props->getNode("interpolation");
+ SGPropertyNode_ptr table_node = props->getNode("interpolation");
if (table_node != 0) {
SGInterpTable * table = new SGInterpTable();
vector<SGPropertyNode_ptr> entries = table_node->getChildren("entry");
for (unsigned int i = 0; i < entries.size(); i++)
table->addEntry(entries[i]->getDoubleValue("ind", 0.0),
- entries[i]->getDoubleValue("dep", 0.0));
+ entries[i]->getDoubleValue("dep", 0.0));
return table;
} else {
return 0;
static void
make_animation (ssgBranch * model,
- const char * object_name,
- SGPropertyNode * node)
+ const char * name,
+ vector<SGPropertyNode_ptr> &name_nodes,
+ SGPropertyNode_ptr node)
{
Animation * animation = 0;
- const char * type = node->getStringValue("type");
+ const char * type = node->getStringValue("type", "none");
if (!strcmp("none", type)) {
animation = new NullAnimation(node);
} else if (!strcmp("range", type)) {
animation = new SelectAnimation(node);
} else if (!strcmp("spin", type)) {
animation = new SpinAnimation(node);
+ } else if (!strcmp("timed", type)) {
+ animation = new TimedAnimation(node);
} else if (!strcmp("rotate", type)) {
animation = new RotateAnimation(node);
} else if (!strcmp("translate", type)) {
SG_LOG(SG_INPUT, SG_WARN, "Unknown animation type " << type);
}
+ if (name != 0)
+ animation->setName((char *)name);
+
ssgEntity * object;
- if (object_name != 0) {
- object = find_named_node(model, object_name);
+ if (name_nodes.size() > 0) {
+ object = find_named_node(model, name_nodes[0]->getStringValue());
if (object == 0) {
- SG_LOG(SG_INPUT, SG_WARN, "Object " << object_name << " not found");
+ SG_LOG(SG_INPUT, SG_WARN, "Object " << name_nodes[0]->getStringValue()
+ << " not found");
delete animation;
animation = 0;
}
ssgBranch * branch = animation->getBranch();
splice_branch(branch, object);
+
+ for (int i = 1; i < name_nodes.size(); i++) {
+ const char * name = name_nodes[i]->getStringValue();
+ object = find_named_node(model, name);
+ if (object == 0) {
+ SG_LOG(SG_INPUT, SG_WARN, "Object " << name << " not found");
+ delete animation;
+ animation = 0;
+ }
+ ssgBranch * oldParent = object->getParent(0);
+ branch->addKid(object);
+ oldParent->removeKid(object);
+ }
+
+ animation->init();
branch->setUserData(animation);
branch->setTravCallback(SSG_CALLBACK_PRETRAV, animation_callback);
}
// Load the 3D aircraft object itself
SGPath xmlpath;
SGPath modelpath = path;
- if ( path[ 0 ] == '/' || path[ 0 ] == '\\' || ( isalpha( path[ 0 ] ) && path[ 1 ] == ':' ) ) {
+ if ( ulIsAbsolutePathName( path.c_str() ) ) {
xmlpath = modelpath;
}
else {
modelpath.append(props.getStringValue("/path"));
} else {
if (model == 0)
- model = new ssgBranch;
+ model = new ssgBranch;
}
}
}
// Set up the alignment node
- ssgTransform * align = new ssgTransform;
- align->addKid(model);
+ ssgTransform * alignmainmodel = new ssgTransform;
+ alignmainmodel->addKid(model);
sgMat4 res_matrix;
make_offsets_matrix(&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));
- align->setTransform(res_matrix);
-
- // Load animations
- vector<SGPropertyNode_ptr> animation_nodes = props.getChildren("animation");
- unsigned int i;
- for (i = 0; i < animation_nodes.size(); i++) {
- vector<SGPropertyNode_ptr> name_nodes =
- animation_nodes[i]->getChildren("object-name");
- if (name_nodes.size() < 1) {
- make_animation(model, 0, animation_nodes[i]);
- } else {
- for (unsigned int j = 0; j < name_nodes.size(); j++) {
- make_animation(model, name_nodes[j]->getStringValue(), animation_nodes[i]);
- }
- }
- }
+ 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);
// Load panels
+ unsigned int i;
vector<SGPropertyNode_ptr> panel_nodes = props.getChildren("panel");
for (i = 0; i < panel_nodes.size(); i++) {
- printf("Reading a panel in model.cxx\n");
+ 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 sub-models
+ // 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");
+ make_animation(model, name, name_nodes, animation_nodes[i]);
+ }
+
+ // 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;
make_offsets_matrix(&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));
+ 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(node->getStringValue("path"));
model->addKid(align);
}
- return model;
+ return alignmainmodel;
}
{
}
+void
+Animation::init ()
+{
+}
+
+void
+Animation::update ()
+{
+}
+
\f
////////////////////////////////////////////////////////////////////////
{
}
-void
-NullAnimation::update ()
-{
-}
-
\f
////////////////////////////////////////////////////////////////////////
{
}
-void
-RangeAnimation::update ()
-{
-}
-
\f
////////////////////////////////////////////////////////////////////////
{
}
-void
-BillboardAnimation::update ()
-{
-}
-
\f
////////////////////////////////////////////////////////////////////////
: Animation(props, new ssgSelector),
_condition(0)
{
- SGPropertyNode * node = props->getChild("condition");
+ SGPropertyNode_ptr node = props->getChild("condition");
if (node != 0)
_condition = fgReadCondition(node);
}
}
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of TimedAnimation
+////////////////////////////////////////////////////////////////////////
+
+TimedAnimation::TimedAnimation (SGPropertyNode_ptr props)
+ : Animation(props, new ssgSelector),
+ _duration_sec(props->getDoubleValue("duration-sec", 1.0)),
+ _last_time_sec(0),
+ _step(-1)
+{
+}
+
+TimedAnimation::~TimedAnimation ()
+{
+}
+
+void
+TimedAnimation::update ()
+{
+ float sim_time_sec = globals->get_sim_time_sec();
+ if ((sim_time_sec - _last_time_sec) >= _duration_sec) {
+ _last_time_sec = sim_time_sec;
+ _step++;
+ if (_step >= getBranch()->getNumKids())
+ _step = 0;
+ ((ssgSelector *)getBranch())->selectStep(_step);
+ }
+}
+
+
\f
////////////////////////////////////////////////////////////////////////
// Implementation of RotateAnimation
RotateAnimation::update ()
{
if (_table == 0) {
- _position_deg = (_prop->getDoubleValue() + _offset_deg) * _factor;
+ _position_deg = _prop->getDoubleValue() * _factor + _offset_deg;
if (_has_min && _position_deg < _min_deg)
_position_deg = _min_deg;
if (_has_max && _position_deg > _max_deg)
void
FGModelPlacement::setOrientation (double roll_deg, double pitch_deg,
- double heading_deg)
+ double heading_deg)
{
_roll_deg = roll_deg;
_pitch_deg = pitch_deg;