Add 'showSceneGraph' command to export the scene or a particular object to .osgt for debugging purposes

coverity_scan^2
scrawl 8 years ago
parent e90941a8b3
commit 34deb6e7b1

@ -505,7 +505,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
// Create the world // Create the world
mEnvironment.setWorld( new MWWorld::World (mViewer, rootNode, mResourceSystem.get(), mEnvironment.setWorld( new MWWorld::World (mViewer, rootNode, mResourceSystem.get(),
mFileCollections, mContentFiles, mEncoder, mFallbackMap, mFileCollections, mContentFiles, mEncoder, mFallbackMap,
mActivationDistanceOverride, mCellName, mStartupScript, mResDir.string())); mActivationDistanceOverride, mCellName, mStartupScript, mResDir.string(), mCfgMgr.getUserDataPath().string()));
mEnvironment.getWorld()->setupPlayer(); mEnvironment.getWorld()->setupPlayer();
input->setPlayer(&mEnvironment.getWorld()->getPlayer()); input->setPlayer(&mEnvironment.getWorld()->getPlayer());

@ -567,6 +567,10 @@ namespace MWBase
/// Return physical or rendering half extents of the given actor. /// Return physical or rendering half extents of the given actor.
virtual osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& actor, bool rendering=false) const = 0; virtual osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& actor, bool rendering=false) const = 0;
/// Export scene graph to a file and return the filename.
/// \param ptr object to export scene graph for (if empty, export entire scene graph)
virtual std::string exportSceneGraph(const MWWorld::Ptr& ptr) = 0;
}; };
} }

@ -28,6 +28,7 @@
#include <components/sceneutil/positionattitudetransform.hpp> #include <components/sceneutil/positionattitudetransform.hpp>
#include <components/sceneutil/workqueue.hpp> #include <components/sceneutil/workqueue.hpp>
#include <components/sceneutil/unrefqueue.hpp> #include <components/sceneutil/unrefqueue.hpp>
#include <components/sceneutil/writescene.hpp>
#include <components/terrain/terraingrid.hpp> #include <components/terrain/terraingrid.hpp>
@ -1002,8 +1003,17 @@ namespace MWRender
if (mFieldOfViewOverridden == true) if (mFieldOfViewOverridden == true)
{ {
mFieldOfViewOverridden = false; mFieldOfViewOverridden = false;
updateProjectionMatrix(); updateProjectionMatrix();
} }
} }
void RenderingManager::exportSceneGraph(const MWWorld::Ptr &ptr, const std::string &filename, const std::string &format)
{
osg::Node* node = mViewer->getSceneData();
if (!ptr.isEmpty())
node = ptr.getRefData().getBaseNode();
SceneUtil::writeScene(node, filename, format);
}
} }

@ -188,6 +188,8 @@ namespace MWRender
/// reset a previous overrideFieldOfView() call, i.e. revert to field of view specified in the settings file. /// reset a previous overrideFieldOfView() call, i.e. revert to field of view specified in the settings file.
void resetFieldOfView(); void resetFieldOfView();
void exportSceneGraph(const MWWorld::Ptr& ptr, const std::string& filename, const std::string& format);
private: private:
void updateProjectionMatrix(); void updateProjectionMatrix();
void updateTextureFiltering(); void updateTextureFiltering();

@ -60,7 +60,9 @@ op 0x2002b: PCJoinFaction, explicit reference
op 0x2002c: MenuTest op 0x2002c: MenuTest
op 0x2002d: BetaComment op 0x2002d: BetaComment
op 0x2002e: BetaComment, explicit reference op 0x2002e: BetaComment, explicit reference
opcodes 0x2002d-0x3ffff unused op 0x2002f: ShowSceneGraph
op 0x20030: ShowSceneGraph, explicit
opcodes 0x20031-0x3ffff unused
Segment 4: Segment 4:
(not implemented yet) (not implemented yet)

@ -1252,6 +1252,31 @@ namespace MWScript
} }
}; };
template <class R>
class OpShowSceneGraph : public Interpreter::Opcode1
{
public:
virtual void execute(Interpreter::Runtime &runtime, unsigned int arg0)
{
MWWorld::Ptr ptr = R()(runtime, false);
int confirmed = 0;
if (arg0==1)
{
confirmed = runtime[0].mInteger;
runtime.pop();
}
if (ptr.isEmpty() && !confirmed)
runtime.getContext().report("Exporting the entire scene graph will result in a large file. Confirm this action using 'showscenegraph 1' or select an object instead.");
else
{
const std::string& filename = MWBase::Environment::get().getWorld()->exportSceneGraph(ptr);
runtime.getContext().report("Wrote '" + filename + "'");
}
}
};
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
interpreter.installSegment5 (Compiler::Misc::opcodeXBox, new OpXBox); interpreter.installSegment5 (Compiler::Misc::opcodeXBox, new OpXBox);
@ -1348,6 +1373,8 @@ namespace MWScript
interpreter.installSegment5 (Compiler::Misc::opcodeRemoveFromLevCreature, new OpRemoveFromLevCreature); interpreter.installSegment5 (Compiler::Misc::opcodeRemoveFromLevCreature, new OpRemoveFromLevCreature);
interpreter.installSegment5 (Compiler::Misc::opcodeAddToLevItem, new OpAddToLevItem); interpreter.installSegment5 (Compiler::Misc::opcodeAddToLevItem, new OpAddToLevItem);
interpreter.installSegment5 (Compiler::Misc::opcodeRemoveFromLevItem, new OpRemoveFromLevItem); interpreter.installSegment5 (Compiler::Misc::opcodeRemoveFromLevItem, new OpRemoveFromLevItem);
interpreter.installSegment3 (Compiler::Misc::opcodeShowSceneGraph, new OpShowSceneGraph<ImplicitRef>);
interpreter.installSegment3 (Compiler::Misc::opcodeShowSceneGraphExplicit, new OpShowSceneGraph<ExplicitRef>);
} }
} }
} }

@ -145,10 +145,10 @@ namespace MWWorld
const std::vector<std::string>& contentFiles, const std::vector<std::string>& contentFiles,
ToUTF8::Utf8Encoder* encoder, const std::map<std::string,std::string>& fallbackMap, ToUTF8::Utf8Encoder* encoder, const std::map<std::string,std::string>& fallbackMap,
int activationDistanceOverride, const std::string& startCell, const std::string& startupScript, int activationDistanceOverride, const std::string& startCell, const std::string& startupScript,
const std::string& resourcePath) const std::string& resourcePath, const std::string& userDataPath)
: mResourceSystem(resourceSystem), mFallback(fallbackMap), mPlayer (0), mLocalScripts (mStore), : mResourceSystem(resourceSystem), mFallback(fallbackMap), mPlayer (0), mLocalScripts (mStore),
mSky (true), mCells (mStore, mEsm), mSky (true), mCells (mStore, mEsm),
mGodMode(false), mScriptsEnabled(true), mContentFiles (contentFiles), mGodMode(false), mScriptsEnabled(true), mContentFiles (contentFiles), mUserDataPath(userDataPath),
mActivationDistanceOverride (activationDistanceOverride), mStartupScript(startupScript), mActivationDistanceOverride (activationDistanceOverride), mStartupScript(startupScript),
mStartCell (startCell), mDistanceToFacedObject(-1), mTeleportEnabled(true), mStartCell (startCell), mDistanceToFacedObject(-1), mTeleportEnabled(true),
mLevitationEnabled(true), mGoToJail(false), mDaysInPrison(0) mLevitationEnabled(true), mGoToJail(false), mDaysInPrison(0)
@ -3146,6 +3146,13 @@ namespace MWWorld
return mPhysics->getHalfExtents(actor); return mPhysics->getHalfExtents(actor);
} }
std::string World::exportSceneGraph(const Ptr &ptr)
{
std::string file = mUserDataPath + "/openmw.osgt";
mRendering->exportSceneGraph(ptr, file, "Ascii");
return file;
}
void World::spawnRandomCreature(const std::string &creatureList) void World::spawnRandomCreature(const std::string &creatureList)
{ {
const ESM::CreatureLevList* list = getStore().get<ESM::CreatureLevList>().find(creatureList); const ESM::CreatureLevList* list = getStore().get<ESM::CreatureLevList>().find(creatureList);

@ -101,6 +101,8 @@ namespace MWWorld
bool mScriptsEnabled; bool mScriptsEnabled;
std::vector<std::string> mContentFiles; std::vector<std::string> mContentFiles;
std::string mUserDataPath;
// not implemented // not implemented
World (const World&); World (const World&);
World& operator= (const World&); World& operator= (const World&);
@ -182,7 +184,7 @@ namespace MWWorld
const Files::Collections& fileCollections, const Files::Collections& fileCollections,
const std::vector<std::string>& contentFiles, const std::vector<std::string>& contentFiles,
ToUTF8::Utf8Encoder* encoder, const std::map<std::string,std::string>& fallbackMap, ToUTF8::Utf8Encoder* encoder, const std::map<std::string,std::string>& fallbackMap,
int activationDistanceOverride, const std::string& startCell, const std::string& startupScript, const std::string& resourcePath); int activationDistanceOverride, const std::string& startCell, const std::string& startupScript, const std::string& resourcePath, const std::string& userDataPath);
virtual ~World(); virtual ~World();
@ -668,6 +670,10 @@ namespace MWWorld
/// Return physical or rendering half extents of the given actor. /// Return physical or rendering half extents of the given actor.
virtual osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& actor, bool rendering=false) const; virtual osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& actor, bool rendering=false) const;
/// Export scene graph to a file and return the filename.
/// \param ptr object to export scene graph for (if empty, export entire scene graph)
virtual std::string exportSceneGraph(const MWWorld::Ptr& ptr);
}; };
} }

@ -50,7 +50,7 @@ add_component_dir (shader
add_component_dir (sceneutil add_component_dir (sceneutil
clone attach visitor util statesetupdater controller skeleton riggeometry lightcontroller clone attach visitor util statesetupdater controller skeleton riggeometry lightcontroller
lightmanager lightutil positionattitudetransform workqueue unrefqueue pathgridutil waterutil lightmanager lightutil positionattitudetransform workqueue unrefqueue pathgridutil waterutil writescene serialize
) )
add_component_dir (nif add_component_dir (nif

@ -312,6 +312,8 @@ namespace Compiler
extensions.registerInstruction ("betacomment", "/S", opcodeBetaComment, opcodeBetaCommentExplicit); extensions.registerInstruction ("betacomment", "/S", opcodeBetaComment, opcodeBetaCommentExplicit);
extensions.registerInstruction ("bc", "/S", opcodeBetaComment, opcodeBetaCommentExplicit); extensions.registerInstruction ("bc", "/S", opcodeBetaComment, opcodeBetaCommentExplicit);
extensions.registerInstruction ("ori", "/S", opcodeBetaComment, opcodeBetaCommentExplicit); // 'ori' stands for 'ObjectReferenceInfo' extensions.registerInstruction ("ori", "/S", opcodeBetaComment, opcodeBetaCommentExplicit); // 'ori' stands for 'ObjectReferenceInfo'
extensions.registerInstruction ("showscenegraph", "/l", opcodeShowSceneGraph, opcodeShowSceneGraphExplicit);
extensions.registerInstruction ("ssg", "/l", opcodeShowSceneGraph, opcodeShowSceneGraphExplicit);
extensions.registerInstruction ("addtolevcreature", "ccl", opcodeAddToLevCreature); extensions.registerInstruction ("addtolevcreature", "ccl", opcodeAddToLevCreature);
extensions.registerInstruction ("removefromlevcreature", "ccl", opcodeRemoveFromLevCreature); extensions.registerInstruction ("removefromlevcreature", "ccl", opcodeRemoveFromLevCreature);
extensions.registerInstruction ("addtolevitem", "ccl", opcodeAddToLevItem); extensions.registerInstruction ("addtolevitem", "ccl", opcodeAddToLevItem);

@ -292,6 +292,8 @@ namespace Compiler
const int opcodeRemoveFromLevCreature = 0x20002fc; const int opcodeRemoveFromLevCreature = 0x20002fc;
const int opcodeAddToLevItem = 0x20002fd; const int opcodeAddToLevItem = 0x20002fd;
const int opcodeRemoveFromLevItem = 0x20002fe; const int opcodeRemoveFromLevItem = 0x20002fe;
const int opcodeShowSceneGraph = 0x2002f;
const int opcodeShowSceneGraphExplicit = 0x20030;
} }
namespace Sky namespace Sky

@ -132,7 +132,7 @@ namespace SceneUtil
: osg::NodeCallback(copy, copyop) : osg::NodeCallback(copy, copyop)
{ } { }
META_Object(SceneUtil, SceneUtil::LightManagerUpdateCallback) META_Object(SceneUtil, LightManagerUpdateCallback)
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{ {

@ -32,7 +32,7 @@ namespace SceneUtil
public: public:
META_Node(SceneUtil, SceneUtil::LightSource) META_Node(SceneUtil, LightSource)
LightSource(); LightSource();
@ -79,7 +79,7 @@ namespace SceneUtil
{ {
public: public:
META_Node(SceneUtil, SceneUtil::LightManager) META_Node(SceneUtil, LightManager)
LightManager(); LightManager();

@ -0,0 +1,119 @@
#include "serialize.hpp"
#include <osgDB/ObjectWrapper>
#include <osgDB/Registry>
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/sceneutil/skeleton.hpp>
#include <components/sceneutil/riggeometry.hpp>
namespace SceneUtil
{
template <class Cls>
static osg::Object* createInstanceFunc() { return new Cls; }
class PositionAttitudeTransformSerializer : public osgDB::ObjectWrapper
{
public:
PositionAttitudeTransformSerializer()
: osgDB::ObjectWrapper(createInstanceFunc<SceneUtil::PositionAttitudeTransform>, "SceneUtil::PositionAttitudeTransform", "osg::Object osg::Node osg::Group osg::Transform SceneUtil::PositionAttitudeTransform")
{
addSerializer( new osgDB::PropByRefSerializer< SceneUtil::PositionAttitudeTransform, osg::Vec3f >(
"position", osg::Vec3f(), &SceneUtil::PositionAttitudeTransform::getPosition, &SceneUtil::PositionAttitudeTransform::setPosition), osgDB::BaseSerializer::RW_VEC3F );
addSerializer( new osgDB::PropByRefSerializer< SceneUtil::PositionAttitudeTransform, osg::Quat >(
"attitude", osg::Quat(), &SceneUtil::PositionAttitudeTransform::getAttitude, &SceneUtil::PositionAttitudeTransform::setAttitude), osgDB::BaseSerializer::RW_QUAT );
addSerializer( new osgDB::PropByRefSerializer< SceneUtil::PositionAttitudeTransform, osg::Vec3f >(
"scale", osg::Vec3f(), &SceneUtil::PositionAttitudeTransform::getScale, &SceneUtil::PositionAttitudeTransform::setScale), osgDB::BaseSerializer::RW_VEC3F );
}
};
class SkeletonSerializer : public osgDB::ObjectWrapper
{
public:
SkeletonSerializer()
: osgDB::ObjectWrapper(createInstanceFunc<SceneUtil::Skeleton>, "SceneUtil::Skeleton", "osg::Object osg::Node osg::Group SceneUtil::Skeleton")
{
}
};
class FrameSwitchSerializer : public osgDB::ObjectWrapper
{
public:
FrameSwitchSerializer()
: osgDB::ObjectWrapper(createInstanceFunc<osg::Group>, "NifOsg::FrameSwitch", "osg::Object osg::Node osg::Group NifOsg::FrameSwitch")
{
}
};
class RigGeometrySerializer : public osgDB::ObjectWrapper
{
public:
RigGeometrySerializer()
: osgDB::ObjectWrapper(createInstanceFunc<SceneUtil::RigGeometry>, "SceneUtil::RigGeometry", "osg::Object osg::Node osg::Drawable osg::Geometry SceneUtil::RigGeometry")
{
}
};
class LightManagerSerializer : public osgDB::ObjectWrapper
{
public:
LightManagerSerializer()
: osgDB::ObjectWrapper(createInstanceFunc<osg::Group>, "SceneUtil::LightManager", "osg::Object osg::Node osg::Group SceneUtil::LightManager")
{
}
};
osgDB::ObjectWrapper* makeDummySerializer(const std::string& classname)
{
return new osgDB::ObjectWrapper(createInstanceFunc<osg::DummyObject>, classname, "osg::Object");
}
void registerSerializers()
{
static bool done = false;
if (!done)
{
osgDB::Registry::instance()->getObjectWrapperManager()->addWrapper(new PositionAttitudeTransformSerializer);
osgDB::Registry::instance()->getObjectWrapperManager()->addWrapper(new SkeletonSerializer);
osgDB::Registry::instance()->getObjectWrapperManager()->addWrapper(new FrameSwitchSerializer);
osgDB::Registry::instance()->getObjectWrapperManager()->addWrapper(new RigGeometrySerializer);
osgDB::Registry::instance()->getObjectWrapperManager()->addWrapper(new LightManagerSerializer);
// ignore the below for now to avoid warning spam
const char* ignore[] = {
"MWRender::PtrHolder",
"MWRender::CameraRelativeTransform",
"Resource::TemplateRef",
"SceneUtil::LightListCallback",
"SceneUtil::LightManagerUpdateCallback",
"SceneUtil::UpdateRigBounds",
"SceneUtil::UpdateRigGeometry",
"SceneUtil::LightSource",
"NifOsg::NodeUserData",
"NifOsg::FlipController",
"NifOsg::KeyframeController",
"NifOsg::TextKeyMapHolder",
"NifOsg::Emitter",
"NifOsg::ParticleSystem",
"NifOsg::GrowFadeAffector",
"NifOsg::InverseWorldMatrix",
"NifOsg::StaticBoundingBoxCallback",
"NifOsg::GeomMorpherController",
"NifOsg::UpdateMorphGeometry",
"osgMyGUI::Drawable",
"osg::DrawCallback",
"osg::DummyObject"
};
for (size_t i=0; i<sizeof(ignore)/sizeof(ignore[0]); ++i)
{
osgDB::Registry::instance()->getObjectWrapperManager()->addWrapper(makeDummySerializer(ignore[i]));
}
done = true;
}
}
}

@ -0,0 +1,12 @@
#ifndef OPENMW_COMPONENTS_SCENEUTIL_SERIALIZE_H
#define OPENMW_COMPONENTS_SCENEUTIL_SERIALIZE_H
namespace SceneUtil
{
/// Register osg node serializers for certain SceneUtil classes if not already done so
void registerSerializers();
}
#endif

@ -0,0 +1,26 @@
#include "writescene.hpp"
#include <stdexcept>
#include <osgDB/Registry>
#include <boost/filesystem/fstream.hpp>
#include "serialize.hpp"
void SceneUtil::writeScene(osg::Node *node, const std::string& filename, const std::string& format)
{
registerSerializers();
osgDB::ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension("osgt");
if (!rw)
throw std::runtime_error("can not find readerwriter for " + format);
boost::filesystem::ofstream stream;
stream.open(filename);
osg::ref_ptr<osgDB::Options> options = new osgDB::Options;
options->setPluginStringData("fileType", format);
rw->writeNode(*node, stream, options);
}

@ -0,0 +1,18 @@
#ifndef OPENMW_COMPONENTS_WRITESCENE_H
#define OPENMW_COMPONENTS_WRITESCENE_H
#include <string>
namespace osg
{
class Node;
}
namespace SceneUtil
{
void writeScene(osg::Node* node, const std::string& filename, const std::string& format);
}
#endif
Loading…
Cancel
Save