#include "serialize.hpp" #include #include #include #include #include #include #include #include #include #include #include namespace { #define MATERIAL_FUNC(PROP, TYPE) \ static bool check##PROP(const SceneUtil::Material& attr) \ { \ return true; \ } \ static bool read##PROP(osgDB::InputStream& is, SceneUtil::Material& attr) \ { \ TYPE value; \ is >> value; \ attr.set##PROP(value); \ return true; \ } \ static bool write##PROP(osgDB::OutputStream& os, const SceneUtil::Material& attr) \ { \ os << attr.get##PROP(); \ return true; \ } MATERIAL_FUNC(Ambient, osg::Vec4f) MATERIAL_FUNC(Diffuse, osg::Vec4f) MATERIAL_FUNC(Specular, osg::Vec4f) MATERIAL_FUNC(Emission, osg::Vec4f) } namespace SceneUtil { template static osg::Object* createInstanceFunc() { return new Cls; } class PositionAttitudeTransformSerializer : public osgDB::ObjectWrapper { public: PositionAttitudeTransformSerializer() : osgDB::ObjectWrapper(createInstanceFunc, "SceneUtil::PositionAttitudeTransform", "osg::Object osg::Node osg::Group osg::Transform SceneUtil::PositionAttitudeTransform") { addSerializer(new osgDB::PropByRefSerializer("position", osg::Vec3f(), &SceneUtil::PositionAttitudeTransform::getPosition, &SceneUtil::PositionAttitudeTransform::setPosition), osgDB::BaseSerializer::RW_VEC3F); addSerializer(new osgDB::PropByRefSerializer("attitude", osg::Quat(), &SceneUtil::PositionAttitudeTransform::getAttitude, &SceneUtil::PositionAttitudeTransform::setAttitude), osgDB::BaseSerializer::RW_QUAT); addSerializer( new osgDB::PropByRefSerializer("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", "osg::Object osg::Node osg::Group SceneUtil::Skeleton") { } }; class RigGeometrySerializer : public osgDB::ObjectWrapper { public: RigGeometrySerializer() : osgDB::ObjectWrapper(createInstanceFunc, "SceneUtil::RigGeometry", "osg::Object osg::Node osg::Drawable SceneUtil::RigGeometry") { } }; class RigGeometryHolderSerializer : public osgDB::ObjectWrapper { public: RigGeometryHolderSerializer() : osgDB::ObjectWrapper(createInstanceFunc, "SceneUtil::RigGeometryHolder", "osg::Object osg::Node osg::Drawable SceneUtil::RigGeometryHolder") { } }; class OsgaRigGeometrySerializer : public osgDB::ObjectWrapper { public: OsgaRigGeometrySerializer() : osgDB::ObjectWrapper(createInstanceFunc, "SceneUtil::OsgaRigGeometry", "osg::Object osg::Node osg::Geometry osgAnimation::RigGeometry SceneUtil::OsgaRigGeometry") { } }; class MorphGeometrySerializer : public osgDB::ObjectWrapper { public: MorphGeometrySerializer() : osgDB::ObjectWrapper(createInstanceFunc, "SceneUtil::MorphGeometry", "osg::Object osg::Node osg::Drawable SceneUtil::MorphGeometry") { } }; class LightManagerSerializer : public osgDB::ObjectWrapper { public: LightManagerSerializer() : osgDB::ObjectWrapper(createInstanceFunc, "SceneUtil::LightManager", "osg::Object osg::Node osg::Group SceneUtil::LightManager") { } }; class CameraRelativeTransformSerializer : public osgDB::ObjectWrapper { public: CameraRelativeTransformSerializer() : osgDB::ObjectWrapper(createInstanceFunc, "MWRender::CameraRelativeTransform", "osg::Object osg::Node osg::Group MWRender::CameraRelativeTransform") { } }; class MatrixTransformSerializer : public osgDB::ObjectWrapper { public: MatrixTransformSerializer() : osgDB::ObjectWrapper(createInstanceFunc, "NifOsg::MatrixTransform", "osg::Object osg::Node osg::Group osg::Transform osg::MatrixTransform NifOsg::MatrixTransform") { } }; class AutoTransformSerializer : public osgDB::ObjectWrapper { public: AutoTransformSerializer() : osgDB::ObjectWrapper(createInstanceFunc, "NifOsg::AutoTransform", "osg::Object osg::Node osg::Group osg::Transform osg::MatrixTransform NifOsg::MatrixTransform " "NifOsg::AutoTransform") { using ModeSerializer = osgDB::EnumSerializer; osg::ref_ptr serializer = new ModeSerializer("Mode", NifOsg::AutoTransform::Mode::RigidFaceCamera, &NifOsg::AutoTransform::getMode, &NifOsg::AutoTransform::setMode); serializer->add("AlwaysFaceCamera", NifOsg::AutoTransform::Mode::AlwaysFaceCamera); serializer->add("RotateAboutUp", NifOsg::AutoTransform::Mode::RotateAboutUp); serializer->add("RigidFaceCamera", NifOsg::AutoTransform::Mode::RigidFaceCamera); addSerializer(serializer.get(), osgDB::BaseSerializer::RW_ENUM); } }; class TextureTypeSerializer : public osgDB::ObjectWrapper { public: TextureTypeSerializer() : osgDB::ObjectWrapper(createInstanceFunc, "SceneUtil::TextureType", "osg::Object osg::StateAttribute SceneUtil::TextureType") { } }; class MaterialSerializer : public osgDB::ObjectWrapper { public: MaterialSerializer() : osgDB::ObjectWrapper(createInstanceFunc, "SceneUtil::Material", "osg::Object osg::StateAttribute SceneUtil::Material") { addSerializer( new osgDB::UserSerializer("Ambient", &checkAmbient, &readAmbient, &writeAmbient)); addSerializer( new osgDB::UserSerializer("Diffuse", &checkDiffuse, &readDiffuse, &writeDiffuse)); addSerializer(new osgDB::UserSerializer( "Specular", &checkSpecular, &readSpecular, &writeSpecular)); addSerializer(new osgDB::UserSerializer( "Emission", &checkEmission, &readEmission, &writeEmission)); addSerializer(new osgDB::PropByValSerializer( "Shininess", 0.f, &SceneUtil::Material::getShininess, &SceneUtil::Material::setShininess), osgDB::BaseSerializer::RW_FLOAT); addSerializer(new osgDB::PropByValSerializer("EmissiveMultiplier", 1.f, &SceneUtil::Material::getEmissiveMultiplier, &SceneUtil::Material::setEmissiveMultiplier), osgDB::BaseSerializer::RW_FLOAT); addSerializer(new osgDB::PropByValSerializer("SpecularStrength", 1.f, &SceneUtil::Material::getSpecularStrength, &SceneUtil::Material::setSpecularStrength), osgDB::BaseSerializer::RW_FLOAT); using ColorModeSerializer = osgDB::EnumSerializer; osg::ref_ptr colorModeSerializer = new ColorModeSerializer("VertexColorMode", SceneUtil::VertexColorModes::None, &SceneUtil::Material::getVertexColorMode, &SceneUtil::Material::setVertexColorMode); colorModeSerializer->add("None", SceneUtil::VertexColorModes::None); colorModeSerializer->add("Emission", SceneUtil::VertexColorModes::Emission); colorModeSerializer->add("AmbientAndDiffuse", SceneUtil::VertexColorModes::AmbientAndDiffuse); colorModeSerializer->add("Ambient", SceneUtil::VertexColorModes::Ambient); colorModeSerializer->add("Diffuse", SceneUtil::VertexColorModes::Diffuse); colorModeSerializer->add("Specular", SceneUtil::VertexColorModes::Specular); addSerializer(colorModeSerializer); } }; osgDB::ObjectWrapper* makeDummySerializer(const std::string& classname) { return new osgDB::ObjectWrapper(createInstanceFunc, classname, "osg::Object"); } class GeometrySerializer : public osgDB::ObjectWrapper { public: GeometrySerializer() : osgDB::ObjectWrapper( createInstanceFunc, "osg::Geometry", "osg::Object osg::Drawable osg::Geometry") { } }; void registerSerializers(bool skipGeometry) { static bool done = false; if (!done) { osgDB::ObjectWrapperManager* mgr = osgDB::Registry::instance()->getObjectWrapperManager(); mgr->addWrapper(new PositionAttitudeTransformSerializer); mgr->addWrapper(new SkeletonSerializer); mgr->addWrapper(new RigGeometrySerializer); mgr->addWrapper(new RigGeometryHolderSerializer); mgr->addWrapper(new OsgaRigGeometrySerializer); mgr->addWrapper(new MorphGeometrySerializer); mgr->addWrapper(new LightManagerSerializer); mgr->addWrapper(new CameraRelativeTransformSerializer); mgr->addWrapper(new MatrixTransformSerializer); mgr->addWrapper(new AutoTransformSerializer); mgr->addWrapper(new TextureTypeSerializer); mgr->addWrapper(new MaterialSerializer); if (skipGeometry) { // Don't serialize Geometry data as we are more interested in the overall structure rather than tons of // vertex data that would make the file large and hard to read. mgr->removeWrapper(mgr->findWrapper("osg::Geometry")); mgr->addWrapper(new GeometrySerializer); } // ignore the below for now to avoid warning spam const char* ignore[] = { "Debug::DebugDrawer", "MWRender::NifAnimBlendController", "MWRender::BoneAnimBlendController", "MWRender::BoneAnimBlendControllerWrapper", "SceneUtil::CompositeStateSetUpdater", "SceneUtil::TemplateRef", "SceneUtil::UBOManager", "SceneUtil::LightListCallback", "SceneUtil::LightManagerUpdateCallback", "SceneUtil::UpdateRigBounds", "SceneUtil::UpdateRigGeometry", "SceneUtil::LightSource", "SceneUtil::DisableLight", "SceneUtil::MWShadowTechnique", "SceneUtil::UserData", "Shader::AddedState", "Shader::RemovedAlphaFunc", "NifOsg::FlipController", "NifOsg::KeyframeController", "NifOsg::Emitter", "NifOsg::ParticleColorAffector", "NifOsg::ParticleSystem", "NifOsg::GravityAffector", "NifOsg::ParticleBomb", "NifOsg::GrowFadeAffector", "NifOsg::InverseWorldMatrix", "NifOsg::StaticBoundingBoxCallback", "NifOsg::GeomMorpherController", "NifOsg::UpdateMorphGeometry", "NifOsg::LookAtController", "NifOsg::UVController", "NifOsg::VisController", "osgMyGUI::Drawable", "osg::DrawCallback", "osg::UniformBufferObject", "osgOQ::ClearQueriesCallback", "osgOQ::RetrieveQueriesCallback", "osg::DummyObject", }; for (size_t i = 0; i < sizeof(ignore) / sizeof(ignore[0]); ++i) { mgr->addWrapper(makeDummySerializer(ignore[i])); } done = true; } } }