From 46cbec9a4a406904a80905fe2209c92b15ecb70c Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 25 Mar 2015 15:39:41 +0100 Subject: [PATCH] Add skinning auto-detection in nifosg loader --- apps/nifosgtest/test.cpp | 2 +- apps/opencs/view/render/object.cpp | 2 +- components/nif/niffile.cpp | 11 +++++++++++ components/nif/niffile.hpp | 8 ++++++++ components/nif/node.hpp | 2 ++ components/nifosg/nifloader.cpp | 5 ++++- components/nifosg/nifloader.hpp | 6 ++---- 7 files changed, 29 insertions(+), 7 deletions(-) diff --git a/apps/nifosgtest/test.cpp b/apps/nifosgtest/test.cpp index 253b5f99d..0f2e43a56 100644 --- a/apps/nifosgtest/test.cpp +++ b/apps/nifosgtest/test.cpp @@ -117,7 +117,7 @@ int main(int argc, char** argv) osg::Group* newNode = new osg::Group; NifOsg::Loader loader; loader.resourceManager = &resourceMgr; - newNode->addChild(loader.loadAsSkeleton(nif)); + newNode->addChild(loader.load(nif)); osg::PositionAttitudeTransform* trans = new osg::PositionAttitudeTransform; root->addChild(trans); diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index f48fcc440..bd44ba577 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -60,7 +60,7 @@ void CSVRender::Object::update() Nif::NIFFilePtr file(new Nif::NIFFile(mVFS->get(path), path)); - mBaseNode->addChild(loader.loadAsSkeleton(file)); + mBaseNode->addChild(loader.load(file)); //mObject->setVisibilityFlags (Element_Reference); diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index f7d864198..a73985cfb 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -12,6 +12,7 @@ NIFFile::NIFFile(Files::IStreamPtr stream, const std::string &name) : ver(0) , filename(name) , mStream(stream) + , mUseSkinning(false) { parse(); } @@ -208,4 +209,14 @@ void NIFFile::parse() records[i]->post(this); } +void NIFFile::setUseSkinning(bool skinning) +{ + mUseSkinning = skinning; +} + +bool NIFFile::getUseSkinning() const +{ + return mUseSkinning; +} + } diff --git a/components/nif/niffile.hpp b/components/nif/niffile.hpp index 9f08f3f1d..ae5aca5ac 100644 --- a/components/nif/niffile.hpp +++ b/components/nif/niffile.hpp @@ -32,6 +32,8 @@ class NIFFile /// Root list. This is a select portion of the pointers from records std::vector roots; + bool mUseSkinning; + /// Parse the file void parse(); @@ -83,6 +85,12 @@ public: /// Number of roots size_t numRoots() const { return roots.size(); } + /// Set whether there is skinning contained in this NIF file. + /// @note This is just a hint for users of the NIF file and has no effect on the loading procedure. + void setUseSkinning(bool skinning); + + bool getUseSkinning() const; + /// Get the name of the file std::string getFilename(){ return filename; } }; diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 7f94c0d05..b47c05281 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -166,6 +166,8 @@ struct NiTriShape : Node Node::post(nif); data.post(nif); skin.post(nif); + if (!skin.empty()) + nif->setUseSkinning(true); } }; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index c6927cfad..3c15b57ae 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -297,7 +297,7 @@ namespace void apply(osg::Node &node) { std::map::const_iterator found = mMap.find(node.getName()); - if (found != mMap.end()) + if (node.asTransform() && found != mMap.end()) { const Nif::NiKeyframeController* keyframectrl = found->second; @@ -439,6 +439,9 @@ namespace NifOsg osg::ref_ptr load(Nif::NIFFilePtr nif, TextKeyMap* textKeys) { + if (nif->getUseSkinning()) + return loadAsSkeleton(nif, textKeys); + if (nif->numRoots() < 1) nif->fail("Found no root nodes"); diff --git a/components/nifosg/nifloader.hpp b/components/nifosg/nifloader.hpp index 43eb8da78..87d1a0a99 100644 --- a/components/nifosg/nifloader.hpp +++ b/components/nifosg/nifloader.hpp @@ -24,13 +24,11 @@ namespace NifOsg class Loader { public: - // TODO: add auto-detection for skinning. We will still need a "force skeleton" parameter - // though, when assembling from several files, i.e. equipment parts - /// Create a scene graph for the given NIF. Assumes no skinning is used. + /// Create a scene graph for the given NIF. Auto-detects when skinning is used and calls loadAsSkeleton instead. /// @param node The parent of the new root node for the created scene graph. osg::ref_ptr load(Nif::NIFFilePtr file, TextKeyMap* textKeys = NULL); - /// Create a scene graph for the given NIF. Assumes skinning will be used. + /// Create a scene graph for the given NIF. Always creates a skeleton so that rigs can be attached on the created scene. osg::ref_ptr loadAsSkeleton(Nif::NIFFilePtr file, TextKeyMap* textKeys = NULL); /// Load keyframe controllers from the given kf file onto the given scene graph.