Support preview mode in the model loader.
This makes fgviewer / fgfs --viewer mode useful with models containing Rembrandt light volumes.
This commit is contained in:
parent
4d4e474464
commit
53b9fd2110
@ -160,6 +160,7 @@ void makeEffectAnimations(PropertyList& animation_nodes,
|
|||||||
SGPropertyNode* typeProp = animProp->getChild("type");
|
SGPropertyNode* typeProp = animProp->getChild("type");
|
||||||
if (!typeProp)
|
if (!typeProp)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const char* typeString = typeProp->getStringValue();
|
const char* typeString = typeProp->getStringValue();
|
||||||
if (!strcmp(typeString, "material")) {
|
if (!strcmp(typeString, "material")) {
|
||||||
effectProp
|
effectProp
|
||||||
@ -214,6 +215,43 @@ private:
|
|||||||
osg::Node::NodeMask nodeMaskSet;
|
osg::Node::NodeMask nodeMaskSet;
|
||||||
osg::Node::NodeMask nodeMaskClear;
|
osg::Node::NodeMask nodeMaskClear;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class ExcludeInPreview
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool operator()(SGPropertyNode* aNode) const
|
||||||
|
{
|
||||||
|
string typeString(aNode->getStringValue("type"));
|
||||||
|
// exclude these so we don't show yellow outlines in preview mode
|
||||||
|
return (typeString == "pick") || (typeString == "knob");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool removeNamedNode(osg::Group* aGroup, const std::string& aName)
|
||||||
|
{
|
||||||
|
int nKids = aGroup->getNumChildren();
|
||||||
|
for (int i = 0; i < nKids; i++) {
|
||||||
|
osg::Node* child = aGroup->getChild(i);
|
||||||
|
if (child->getName() == aName) {
|
||||||
|
aGroup->removeChild(child);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < nKids; i++) {
|
||||||
|
osg::Group* childGroup = aGroup->getChild(i)->asGroup();
|
||||||
|
if (!childGroup)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (removeNamedNode(childGroup, aName))
|
||||||
|
return true;
|
||||||
|
} // of child groups traversal
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static osg::Node *
|
static osg::Node *
|
||||||
@ -243,6 +281,7 @@ sgLoad3DModel_internal(const SGPath& path,
|
|||||||
osg::ref_ptr<osg::Node> model;
|
osg::ref_ptr<osg::Node> model;
|
||||||
osg::ref_ptr<osg::Group> group;
|
osg::ref_ptr<osg::Group> group;
|
||||||
SGPropertyNode_ptr props = new SGPropertyNode;
|
SGPropertyNode_ptr props = new SGPropertyNode;
|
||||||
|
bool previewMode = (dbOptions->getPluginStringData("SimGear::PREVIEW") == "ON");
|
||||||
|
|
||||||
// Check for an XML wrapper
|
// Check for an XML wrapper
|
||||||
if (modelpath.extension() == "xml") {
|
if (modelpath.extension() == "xml") {
|
||||||
@ -256,6 +295,10 @@ sgLoad3DModel_internal(const SGPath& path,
|
|||||||
if (overlay)
|
if (overlay)
|
||||||
copyProperties(overlay, props);
|
copyProperties(overlay, props);
|
||||||
|
|
||||||
|
if (previewMode && props->hasChild("nopreview")) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (props->hasValue("/path")) {
|
if (props->hasValue("/path")) {
|
||||||
string modelPathStr = props->getStringValue("/path");
|
string modelPathStr = props->getStringValue("/path");
|
||||||
modelpath = SGModelLib::findDataFile(modelPathStr, NULL, modelDir);
|
modelpath = SGModelLib::findDataFile(modelPathStr, NULL, modelDir);
|
||||||
@ -375,6 +418,9 @@ sgLoad3DModel_internal(const SGPath& path,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!submodel)
|
||||||
|
continue;
|
||||||
|
|
||||||
osg::ref_ptr<osg::Node> submodel_final = submodel;
|
osg::ref_ptr<osg::Node> submodel_final = submodel;
|
||||||
SGPropertyNode *offs = sub_props->getNode("offsets", false);
|
SGPropertyNode *offs = sub_props->getNode("offsets", false);
|
||||||
if (offs) {
|
if (offs) {
|
||||||
@ -454,6 +500,13 @@ sgLoad3DModel_internal(const SGPath& path,
|
|||||||
|
|
||||||
PropertyList effect_nodes = props->getChildren("effect");
|
PropertyList effect_nodes = props->getChildren("effect");
|
||||||
PropertyList animation_nodes = props->getChildren("animation");
|
PropertyList animation_nodes = props->getChildren("animation");
|
||||||
|
|
||||||
|
if (previewMode) {
|
||||||
|
PropertyList::iterator it;
|
||||||
|
it = std::remove_if(animation_nodes.begin(), animation_nodes.end(), ExcludeInPreview());
|
||||||
|
animation_nodes.erase(it, animation_nodes.end());
|
||||||
|
}
|
||||||
|
|
||||||
// Some material animations (eventually all) are actually effects.
|
// Some material animations (eventually all) are actually effects.
|
||||||
makeEffectAnimations(animation_nodes, effect_nodes);
|
makeEffectAnimations(animation_nodes, effect_nodes);
|
||||||
{
|
{
|
||||||
@ -462,10 +515,20 @@ sgLoad3DModel_internal(const SGPath& path,
|
|||||||
group = static_cast<Group*>(modelWithEffects.get());
|
group = static_cast<Group*>(modelWithEffects.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < animation_nodes.size(); ++i)
|
for (unsigned i = 0; i < animation_nodes.size(); ++i) {
|
||||||
|
if (previewMode && animation_nodes[i]->hasChild("nopreview")) {
|
||||||
|
PropertyList names(animation_nodes[i]->getChildren("object-name"));
|
||||||
|
for (unsigned int n=0; n<names.size(); ++n) {
|
||||||
|
std::cout << "remove object name:" << names[n]->getStringValue() << std::endl;
|
||||||
|
removeNamedNode(group, names[n]->getStringValue());
|
||||||
|
} // of object-names in the animation
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/// OSGFIXME: duh, why not only model?????
|
/// OSGFIXME: duh, why not only model?????
|
||||||
SGAnimation::animate(group.get(), animation_nodes[i], prop_root,
|
SGAnimation::animate(group.get(), animation_nodes[i], prop_root,
|
||||||
options.get(), path.str(), i);
|
options.get(), path.str(), i);
|
||||||
|
}
|
||||||
|
|
||||||
if (!needTransform && group->getNumChildren() < 2) {
|
if (!needTransform && group->getNumChildren() < 2) {
|
||||||
model = group->getChild(0);
|
model = group->getChild(0);
|
||||||
|
Loading…
Reference in New Issue
Block a user