X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fscene%2Fmodel%2FModelRegistry.cxx;h=861aee432949ac72fc3e28293ff6ca600e351ff0;hb=daa0fbdc6ba4a2c0548d71737953aa0901b5d71d;hp=315f079ea481b1eca6f288375d92fe72e4bec39c;hpb=7151c3fac153fdeb12f4b4f1fd16d55ac6c89107;p=simgear.git diff --git a/simgear/scene/model/ModelRegistry.cxx b/simgear/scene/model/ModelRegistry.cxx index 315f079e..861aee43 100644 --- a/simgear/scene/model/ModelRegistry.cxx +++ b/simgear/scene/model/ModelRegistry.cxx @@ -16,6 +16,11 @@ // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +#ifdef HAVE_CONFIG_H +# include +#endif + #include "ModelRegistry.hxx" #include @@ -50,6 +55,8 @@ #include #include +#include "BoundingVolumeBuildVisitor.hxx" + using namespace std; using namespace osg; using namespace osgUtil; @@ -219,6 +226,28 @@ private: FilePathList _pathList; }; +// Create new userdata structs in a copied model. +// The BVH trees are shared with the original model, but the velocity fields +// should usually be distinct fields for distinct models. +class UserDataCopyVisitor : public osg::NodeVisitor { +public: + UserDataCopyVisitor() : + osg::NodeVisitor(osg::NodeVisitor::NODE_VISITOR, + osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) + { + } + virtual void apply(osg::Node& node) + { + osg::ref_ptr userData; + userData = SGSceneUserData::getSceneUserData(&node); + if (userData.valid()) { + SGSceneUserData* newUserData = new SGSceneUserData(*userData); + newUserData->setVelocity(0); + node.setUserData(newUserData); + } + node.traverse(*this); + } +}; class SGTexCompressionVisitor : public SGTextureStateAttributeVisitor { public: @@ -229,9 +258,13 @@ public: if (!texture) return; - // Hmm, true?? - texture->setDataVariance(osg::Object::STATIC); + // Do not touch dynamically generated textures. + if (texture->getReadPBuffer()) + return; + if (texture->getDataVariance() == osg::Object::DYNAMIC) + return; + // If no image attached, we assume this one is dynamically generated Image* image = texture->getImage(0); if (!image) return; @@ -256,6 +289,16 @@ public: if (!texture) return; + // Cannot be static if this is a render to texture thing + if (texture->getReadPBuffer()) + return; + if (texture->getDataVariance() == osg::Object::DYNAMIC) + return; + // If no image attached, we assume this one is dynamically generated + Image* image = texture->getImage(0); + if (!image) + return; + texture->setDataVariance(Object::STATIC); } @@ -263,20 +306,8 @@ public: { if (!stateSet) return; - SGTextureStateAttributeVisitor::apply(stateSet); stateSet->setDataVariance(Object::STATIC); - } -}; - -class SGAcMaterialCrippleVisitor : public SGStateAttributeVisitor { -public: - virtual void apply(StateSet::RefAttributePair& refAttr) - { - Material* material; - material = dynamic_cast(refAttr.first.get()); - if (!material) - return; - material->setColorMode(Material::AMBIENT_AND_DIFFUSE); + SGTextureStateAttributeVisitor::apply(stateSet); } }; @@ -387,10 +418,10 @@ osg::Node* OptimizeModelPolicy::optimize(osg::Node* node, } osg::Node* DefaultCopyPolicy::copy(osg::Node* model, const string& fileName, - const osgDB::ReaderWriter::Options* opt) + const osgDB::ReaderWriter::Options* opt) { // Add an extra reference to the model stored in the database. - // That it to avoid expiring the object from the cache even if it is still + // That is to avoid expiring the object from the cache even if it is still // in use. Note that the object cache will think that a model is unused // if the reference count is 1. If we clone all structural nodes here // we need that extra reference to the original object @@ -413,6 +444,11 @@ osg::Node* DefaultCopyPolicy::copy(osg::Node* model, const string& fileName, TextureUpdateVisitor liveryUpdate(opt->getDatabasePathList()); res->accept(liveryUpdate); + // Copy the userdata fields, still sharing the boundingvolumes, + // but introducing new data for velocities. + UserDataCopyVisitor userDataCopyVisitor; + res->accept(userDataCopyVisitor); + return res; } @@ -425,6 +461,32 @@ string OSGSubstitutePolicy::substitute(const string& name, return absFileName; } + +void +BuildLeafBVHPolicy::buildBVH(const std::string& fileName, osg::Node* node) +{ + SG_LOG(SG_IO, SG_INFO, "Building leaf attached boundingvolume tree for \"" + << fileName << "\"."); + BoundingVolumeBuildVisitor bvBuilder(true); + node->accept(bvBuilder); +} + +void +BuildGroupBVHPolicy::buildBVH(const std::string& fileName, osg::Node* node) +{ + SG_LOG(SG_IO, SG_INFO, "Building group attached boundingvolume tree for \"" + << fileName << "\"."); + BoundingVolumeBuildVisitor bvBuilder(false); + node->accept(bvBuilder); +} + +void +NoBuildBVHPolicy::buildBVH(const std::string& fileName, osg::Node*) +{ + SG_LOG(SG_IO, SG_INFO, "Omitting boundingvolume tree for \"" + << fileName << "\"."); +} + ModelRegistry::ModelRegistry() : _defaultCallback(new DefaultCallback("")) { @@ -449,15 +511,19 @@ ModelRegistry::readNode(const string& fileName, const ReaderWriter::Options* opt) { ScopedLock lock(readerMutex); + // XXX Workaround for OSG plugin bug. Registry* registry = Registry::instance(); ReaderWriter::ReadResult res; - Node* cached = 0; CallbackMap::iterator iter = nodeCallbackMap.find(getFileExtension(fileName)); + ReaderWriter::ReadResult result; if (iter != nodeCallbackMap.end() && iter->second.valid()) - return iter->second->readNode(fileName, opt); - return _defaultCallback->readNode(fileName, opt); + result = iter->second->readNode(fileName, opt); + else + result = _defaultCallback->readNode(fileName, opt); + + return result; } class SGReadCallbackInstaller { @@ -528,23 +594,15 @@ struct ACProcessPolicy { transform->setDataVariance(Object::STATIC); transform->setMatrix(m); transform->addChild(node); - // Ok, this step is questionable. - // It is there to have the same visual appearance of ac objects for the - // first cut. Osg's ac3d loader will correctly set materials from the - // ac file. But the old plib loader used GL_AMBIENT_AND_DIFFUSE for the - // materials that in effect igored the ambient part specified in the - // file. We emulate that for the first cut here by changing all - // ac models here. But in the long term we should use the - // unchanged model and fix the input files instead ... - SGAcMaterialCrippleVisitor matCriple; - root->accept(matCriple); + return root; } }; typedef ModelRegistryCallback ACCallback; + OSGSubstitutePolicy, BuildLeafBVHPolicy> +ACCallback; namespace {