+unsigned int FGNasalModelData::_max_module_id = 0;
+FGNasalModelDataList FGNasalModelData::_loaded_models;
+
+typedef osg::ref_ptr<osg::Node> NodeRef;
+typedef nasal::Ghost<NodeRef> NasalNode;
+
+/**
+ * Get position (lat, lon, elevation) and orientation (heading, pitch, roll) of
+ * model.
+ */
+static naRef f_node_getPose( const osg::Node& node,
+ const nasal::CallContext& ctx )
+{
+ osg::NodePathList parent_paths = node.getParentalNodePaths();
+ for( osg::NodePathList::const_iterator path = parent_paths.begin();
+ path != parent_paths.end();
+ ++path )
+ {
+ osg::Matrix local_to_world = osg::computeLocalToWorld(*path);
+ if( !local_to_world.valid() )
+ continue;
+
+ SGGeod coord = SGGeod::fromCart( toSG(local_to_world.getTrans()) );
+ if( !coord.isValid() )
+ continue;
+
+ osg::Matrix local_frame = makeZUpFrameRelative(coord),
+ inv_local;
+ inv_local.invert_4x3(local_frame);
+ local_to_world.postMult(inv_local);
+
+ SGQuatd rotate = toSG(local_to_world.getRotate());
+ double hdg, pitch, roll;
+ rotate.getEulerDeg(hdg, pitch, roll);
+
+ nasal::Hash pose(ctx.to_nasal(coord), ctx.c);
+ pose.set("heading", hdg);
+ pose.set("pitch", pitch);
+ pose.set("roll", roll);
+ return pose.get_naRef();
+ }
+
+ return naNil();
+}
+
+//------------------------------------------------------------------------------
+FGNasalModelData::FGNasalModelData( SGPropertyNode *root,
+ const std::string& path,
+ SGPropertyNode *prop,
+ SGPropertyNode* load,
+ SGPropertyNode* unload,
+ osg::Node* branch ):
+ _path(path),
+ _root(root), _prop(prop),
+ _load(load), _unload(unload),
+ _branch(branch),
+ _module_id( _max_module_id++ )
+{
+ _loaded_models.push_back(this);
+
+ SG_LOG
+ (
+ SG_NASAL,
+ SG_INFO,
+ "New model with attached script(s) "
+ "(branch = " << branch << ","
+ " path = " << simgear::getNodePathString(branch) << ")"
+ );
+}
+
+//------------------------------------------------------------------------------
+FGNasalModelData::~FGNasalModelData()
+{
+ _loaded_models.remove(this);
+
+ SG_LOG
+ (
+ SG_NASAL,
+ SG_INFO,
+ "Removed model with script(s) (branch = " << _branch.get() << ")"
+ );
+}