7#include <osg/Transform>
8#include <osg/observer_ptr>
10#include <simgear/math/SGMath.hxx>
11#include <simgear/nasal/cppbind/Ghost.hxx>
12#include <simgear/scene/util/OsgDebug.hxx>
13#include <simgear/scene/util/OsgMath.hxx>
14#include <simgear/debug/logstream.hxx>
32 const nasal::CallContext& ctx )
34 osg::NodePathList parent_paths = node.getParentalNodePaths();
35 for( osg::NodePathList::const_iterator path = parent_paths.begin();
36 path != parent_paths.end();
39 osg::Matrix local_to_world = osg::computeLocalToWorld(*path);
40 if( !local_to_world.valid() )
43 SGGeod coord = SGGeod::fromCart( toSG(local_to_world.getTrans()) );
44 if( !coord.isValid() )
47 osg::Matrix local_frame = makeZUpFrameRelative(coord),
49 inv_local.invert_4x3(local_frame);
50 local_to_world.postMult(inv_local);
52 SGQuatd rotate = toSG(local_to_world.getRotate());
53 double hdg, pitch, roll;
54 rotate.getEulerDeg(hdg, pitch, roll);
56 nasal::Hash pose(ctx.to_nasal(coord), ctx.c_ctx());
57 pose.set(
"heading", hdg);
58 pose.set(
"pitch", pitch);
59 pose.set(
"roll", roll);
60 return pose.get_naRef();
68 const std::string& path,
74 _root(root), _prop(prop),
78 const std::lock_guard<std::mutex> lock(FGNasalModelData::_loaded_models_mutex);
79 _module_id = _max_module_id++;
80 _loaded_models.push_back(
this);
86 "New model with attached script(s) "
87 "(branch = " << branch <<
","
88 " path = " << simgear::getNodePathString(branch) <<
")"
95 const std::lock_guard<std::mutex> lock(FGNasalModelData::_loaded_models_mutex);
96 _loaded_models.remove(
this);
102 "Removed model with script(s) (branch = " << _branch.get() <<
")"
110 m <<
"__model" << _module_id;
113 SG_LOG(SG_NASAL, SG_DEBUG,
"Loading nasal module " << _module.c_str());
115 const std::string s = _load ? _load->getStringValue() :
"";
120 nasal::Hash module =
nasalSys->getGlobals().createHash(_module);
121 module.set("_module_id", _module_id);
123 NasalNode::init(
"osg.Node")
125 module.set("_model", _branch);
128 arg[0] =
nasalSys->propNodeGhost(_root);
129 arg[1] =
nasalSys->propNodeGhost(_prop);
130 nasalSys->createModule(_module.c_str(), _path.c_str(), s.c_str(), s.length(),
142 SG_LOG(SG_NASAL, SG_WARN,
"Trying to run an <unload> script "
143 "without Nasal subsystem present.");
147 SG_LOG(SG_NASAL, SG_DEBUG,
"Unloading nasal module " << _module.c_str());
151 const std::string s = _unload->getStringValue();
152 nasalSys->createModule(_module.c_str(), _module.c_str(), s.c_str(), s.length(), _root);
155 nasalSys->deleteModule(_module.c_str());
161 return _branch.get();
167 const std::lock_guard<std::mutex> lock(FGNasalModelData::_loaded_models_mutex);
168 FGNasalModelDataList::iterator it = std::find_if
170 _loaded_models.begin(),
171 _loaded_models.end(),
173 return data->_module_id == id; });
175 if( it != _loaded_models.end() )
196 SGPropertyNode *prop,
199 if(
fgGetBool(
"/sim/disable-embedded-nasal") )
205 SGPropertyNode *
nasal = prop->getNode(
"nasal");
216 "Can not load model script(s) (Nasal subsystem not available)."
221 SGPropertyNode* load =
nasal->getNode(
"load");
222 SGPropertyNode* unload =
nasal->getNode(
"unload");
224 if ((!load) && (!unload))
osg::ref_ptr< osg::Node > NodeRef
nasal::Ghost< NodeRef > NasalNode
static naRef f_node_getPose(const osg::Node &node, const nasal::CallContext &ctx)
Get position (lat, lon, elevation) and orientation (heading, pitch, roll) of model.
static FGNasalSys * nasalSys
void modelLoaded(const std::string &path, SGPropertyNode *prop, osg::Node *branch)
FGNasalModelDataRef _data
Nasal model data container.
static FGNasalModelData * getByModuleId(unsigned int id)
Get FGNasalModelData for model with the given module id.
void unload()
Unload hook.
FGNasalModelData(SGPropertyNode *root, const std::string &path, SGPropertyNode *prop, SGPropertyNode *load, SGPropertyNode *unload, osg::Node *branch)
Constructor to be run in an arbitrary thread.
osg::Node * getNode()
Get osg scenegraph node of model.
bool fgGetBool(char const *name, bool def)
Get a bool value for a property.