From c84b667fa5dc051c73f58d1f84b9b13ecac4a5a7 Mon Sep 17 00:00:00 2001 From: Marc Helbling Date: Fri, 20 Jan 2017 15:09:26 +0100 Subject: [PATCH] Updates osgjs from sketchfab * updates uservalue serialization (avoid creating multie UserDataContainer for a same object) * removes vec4ubarray specific serialization (serialization should not enforce the previous color transformation) --- src/osgPlugins/osgjs/Animation.cpp | 2 +- src/osgPlugins/osgjs/ReaderWriterJSON.cpp | 2 +- src/osgPlugins/osgjs/WriteVisitor | 34 +++- src/osgPlugins/osgjs/WriteVisitor.cpp | 199 ++++++++++++---------- 4 files changed, 144 insertions(+), 93 deletions(-) diff --git a/src/osgPlugins/osgjs/Animation.cpp b/src/osgPlugins/osgjs/Animation.cpp index 8c384b085..40af1ed47 100644 --- a/src/osgPlugins/osgjs/Animation.cpp +++ b/src/osgPlugins/osgjs/Animation.cpp @@ -45,7 +45,7 @@ bool addJSONChannel(const std::string& channelType, T* channel, bool packByCoord osg::ref_ptr json = new JSONObject; std::string jsonType = channelType + (packByCoords ? "Packed" : ""); - translateObject(json.get(), channel); + writer->translateObject(json.get(), channel); json->getMaps()["Name"] = new JSONValue(channel->getName()); json->getMaps()["TargetName"] = new JSONValue(channel->getTargetName()); diff --git a/src/osgPlugins/osgjs/ReaderWriterJSON.cpp b/src/osgPlugins/osgjs/ReaderWriterJSON.cpp index cdf929d34..c22abb172 100644 --- a/src/osgPlugins/osgjs/ReaderWriterJSON.cpp +++ b/src/osgPlugins/osgjs/ReaderWriterJSON.cpp @@ -125,7 +125,7 @@ public: writer.setBaseName(basename); writer.useExternalBinaryArray(options.useExternalBinaryArray); writer.mergeAllBinaryFiles(options.mergeAllBinaryFiles); - writer.inlineImages(options.inlineImages); + writer.setInlineImages(options.inlineImages); writer.setMaxTextureDimension(options.resizeTextureUpToPowerOf2); writer.setVarint(options.varint); writer.setBaseLodURL(options.baseLodURL); diff --git a/src/osgPlugins/osgjs/WriteVisitor b/src/osgPlugins/osgjs/WriteVisitor index 7f92ca5b7..7cef22551 100644 --- a/src/osgPlugins/osgjs/WriteVisitor +++ b/src/osgPlugins/osgjs/WriteVisitor @@ -29,8 +29,10 @@ #include #include +#include + #include -# + #include #include #include @@ -47,8 +49,9 @@ #define WRITER_VERSION 9 +class WriteVisitor; + osg::Array* getTangentSpaceArray(osg::Geometry& geometry); -void translateObject(JSONObject* json, osg::Object* osg); void getStringifiedUserValue(osg::Object* o, std::string& name, std::string& value); template bool getStringifiedUserValue(osg::Object* o, std::string& name, std::string& value); @@ -59,8 +62,9 @@ class WriteVisitor : public osg::NodeVisitor public: typedef std::vector > StateSetStack; typedef std::pair KeyValue; + typedef std::map, osg::ref_ptr > OsgObjectToJSONObject; - std::map, osg::ref_ptr > _maps; + OsgObjectToJSONObject _maps; std::vector > _parents; osg::ref_ptr _root; StateSetStack _stateset; @@ -74,6 +78,20 @@ public: std::map _specificBuffers; std::map _buffers; + JSONObject* getJSON(osg::Object* object) const { + OsgObjectToJSONObject::const_iterator lookup = _maps.find(object); + if(lookup != _maps.end()) { + return lookup->second->getShadowObject(); + } + return 0; + } + + void setJSON(osg::Object* object, JSONObject* json) { + if(json) { + _maps[object] = json; + } + } + std::ofstream& getBufferFile(const std::string& name) { if(_buffers.find(name) == _buffers.end()) { _buffers[name] = new std::ofstream(name.c_str(), std::ios::binary); @@ -238,6 +256,10 @@ public: return getBinaryFilename(flag); } + void translateObject(JSONObject* json, osg::Object* osg); + JSONObject* createJSONOsgSimUserData(osgSim::ShapeAttributeList*); + JSONObject* createJSONUserDataContainer(osg::UserDataContainer*); + JSONObject* createJSONPagedLOD(osg::PagedLOD* plod); JSONObject* createJSONStateSet(osg::StateSet* ss); JSONObject* createJSONTexture(osg::Texture* sa); @@ -650,10 +672,14 @@ public: _parents.pop_back(); } + std::string getBaseName() const { return _baseName; } + bool getInlineImages() const { return _inlineImages; } + int getMaxTextureDimension() const { return _maxTextureDimension; } + void setBaseName(const std::string& basename) { _baseName = basename; } void useExternalBinaryArray(bool use) { _useExternalBinaryArray = use; } void mergeAllBinaryFiles(bool use) { _mergeAllBinaryFiles = use; } - void inlineImages(bool use) { _inlineImages = use; } + void setInlineImages(bool use) { _inlineImages = use; } void setVarint(bool use) { _varint = use; } void setMaxTextureDimension(int use) { _maxTextureDimension = use; } void addSpecificBuffer(const std::string& bufferFlag) { diff --git a/src/osgPlugins/osgjs/WriteVisitor.cpp b/src/osgPlugins/osgjs/WriteVisitor.cpp index d5bb0b0d7..e062f8bde 100644 --- a/src/osgPlugins/osgjs/WriteVisitor.cpp +++ b/src/osgPlugins/osgjs/WriteVisitor.cpp @@ -11,8 +11,6 @@ #include #include -#include - #include #include @@ -76,82 +74,6 @@ osg::ref_ptr buildRigBoneMap(osgAnimation::RigGeometry& rigGeometry) } -void translateObject(JSONObject* json, osg::Object* osg) -{ - if (!osg->getName().empty()) { - json->getMaps()["Name"] = new JSONValue(osg->getName()); - } - - osgSim::ShapeAttributeList* osgSim_userdata = dynamic_cast(osg->getUserData()); - if (osgSim_userdata) { - JSONObject* jsonUDC = new JSONObject(); - jsonUDC->addUniqueID(); - - JSONArray* jsonUDCArray = new JSONArray(); - jsonUDC->getMaps()["Values"] = jsonUDCArray; - for (unsigned int i = 0; i < osgSim_userdata->size(); i++) { - const osgSim::ShapeAttribute& attr = (*osgSim_userdata)[i]; - JSONObject* jsonEntry = new JSONObject(); - jsonEntry->getMaps()["Name"] = new JSONValue(attr.getName()); - osg::ref_ptr > value; - switch(attr.getType()) { - case osgSim::ShapeAttribute::INTEGER: - { - std::stringstream ss; - ss << attr.getInt(); - value = new JSONValue(ss.str()); - } - break; - case osgSim::ShapeAttribute::DOUBLE: - { - std::stringstream ss; - ss << attr.getDouble(); - value = new JSONValue(ss.str()); - } - break; - case osgSim::ShapeAttribute::STRING: - { - std::stringstream ss; - ss << attr.getString(); - value = new JSONValue(ss.str()); - } - break; - case osgSim::ShapeAttribute::UNKNOWN: - default: - break; - } - jsonEntry->getMaps()["Value"] = value; - jsonUDCArray->getArray().push_back(jsonEntry); - } - json->getMaps()["UserDataContainer"] = jsonUDC; - - } else if (osg->getUserDataContainer()) { - JSONObject* jsonUDC = new JSONObject(); - jsonUDC->addUniqueID(); - - if (!osg->getUserDataContainer()->getName().empty()) { - jsonUDC->getMaps()["Name"] = new JSONValue(osg->getUserDataContainer()->getName()); - } - JSONArray* jsonUDCArray = new JSONArray(); - jsonUDC->getMaps()["Values"] = jsonUDCArray; - for (unsigned int i = 0; i < osg->getUserDataContainer()->getNumUserObjects(); i++) { - osg::Object* o = osg->getUserDataContainer()->getUserObject(i); - std::string name, value; - getStringifiedUserValue(o, name, value); - if(!name.empty() && !value.empty()) - { - JSONObject* jsonEntry = new JSONObject(); - jsonEntry->getMaps()["Name"] = new JSONValue(name); - jsonEntry->getMaps()["Value"] = new JSONValue(value); - jsonUDCArray->getArray().push_back(jsonEntry); - } - - } - json->getMaps()["UserDataContainer"] = jsonUDC; - } -} - - void getStringifiedUserValue(osg::Object* o, std::string& name, std::string& value) { if(getStringifiedUserValue(o, name, value)) return; if(getStringifiedUserValue(o, name, value)) return; @@ -352,6 +274,108 @@ JSONObject* createImage(osg::Image* image, bool inlineImages, int maxTextureDime } + +JSONObject* WriteVisitor::createJSONOsgSimUserData(osgSim::ShapeAttributeList* osgSimData) { + JSONObject* jsonUDC = new JSONObject(); + jsonUDC->addUniqueID(); + + JSONArray* jsonUDCArray = new JSONArray(); + jsonUDC->getMaps()["Values"] = jsonUDCArray; + for (unsigned int i = 0; i < osgSimData->size(); i++) { + const osgSim::ShapeAttribute& attr = (*osgSimData)[i]; + JSONObject* jsonEntry = new JSONObject(); + jsonEntry->getMaps()["Name"] = new JSONValue(attr.getName()); + osg::ref_ptr > value; + switch(attr.getType()) { + case osgSim::ShapeAttribute::INTEGER: + { + std::stringstream ss; + ss << attr.getInt(); + value = new JSONValue(ss.str()); + } + break; + case osgSim::ShapeAttribute::DOUBLE: + { + std::stringstream ss; + ss << attr.getDouble(); + value = new JSONValue(ss.str()); + } + break; + case osgSim::ShapeAttribute::STRING: + { + std::stringstream ss; + ss << attr.getString(); + value = new JSONValue(ss.str()); + } + break; + case osgSim::ShapeAttribute::UNKNOWN: + default: + break; + } + jsonEntry->getMaps()["Value"] = value; + jsonUDCArray->getArray().push_back(jsonEntry); + } + return jsonUDC; +} + + +JSONObject* WriteVisitor::createJSONUserDataContainer(osg::UserDataContainer* container) { + JSONObject* jsonUDC = new JSONObject(); + jsonUDC->addUniqueID(); + + if (!container->getName().empty()) { + jsonUDC->getMaps()["Name"] = new JSONValue(container->getName()); + } + JSONArray* jsonUDCArray = new JSONArray(); + jsonUDC->getMaps()["Values"] = jsonUDCArray; + for (unsigned int i = 0; i < container->getNumUserObjects(); i++) { + osg::Object* o = container->getUserObject(i); + std::string name, value; + getStringifiedUserValue(o, name, value); + if(!name.empty() && !value.empty()) + { + JSONObject* jsonEntry = new JSONObject(); + jsonEntry->getMaps()["Name"] = new JSONValue(name); + jsonEntry->getMaps()["Value"] = new JSONValue(value); + jsonUDCArray->getArray().push_back(jsonEntry); + } + } + return jsonUDC; +} + + +void WriteVisitor::translateObject(JSONObject* json, osg::Object* osg) +{ + if (!osg->getName().empty()) { + json->getMaps()["Name"] = new JSONValue(osg->getName()); + } + + JSONObject* jsonUDC = 0; + + osgSim::ShapeAttributeList* osgSimData = dynamic_cast(osg->getUserData()); + if (osgSimData) { + jsonUDC = this->getJSON(osgSimData); + if(!jsonUDC) { + jsonUDC = createJSONOsgSimUserData(osgSimData); + this->setJSON(osgSimData, jsonUDC); + } + } + else if (osg::UserDataContainer* container = osg->getUserDataContainer()) { + jsonUDC = this->getJSON(container); + if(!jsonUDC) { + jsonUDC = createJSONUserDataContainer(container); + this->setJSON(container, jsonUDC); + } + } + + if(jsonUDC) { + json->getMaps()["UserDataContainer"] = jsonUDC; + } +} + + + + JSONObject* WriteVisitor::createJSONBufferArray(osg::Array* array, osg::Object* parent) { if (_maps.find(array) != _maps.end()) @@ -765,12 +789,16 @@ JSONObject* WriteVisitor::createJSONLight(osg::Light* light) return jsonLight.release(); } -template JSONObject* createImageFromTexture(osg::Texture* texture, JSONObject* jsonTexture, bool inlineImages, - int maxTextureDimension, const std::string &baseName = "") +template +JSONObject* createImageFromTexture(osg::Texture* texture, JSONObject* jsonTexture, WriteVisitor* writer) { + bool inlineImages = writer->getInlineImages(); + int maxTextureDimension = writer->getMaxTextureDimension(); + const std::string baseName = writer->getBaseName(); + T* text = dynamic_cast( texture); if (text) { - translateObject(jsonTexture,text); + writer->translateObject(jsonTexture,text); JSONObject* image = createImage(text->getImage(), inlineImages, maxTextureDimension, baseName); if (image) jsonTexture->getMaps()["File"] = image; @@ -902,24 +930,21 @@ JSONObject* WriteVisitor::createJSONTexture(osg::Texture* texture) { - JSONObject* obj = createImageFromTexture(texture, jsonTexture.get(), this->_inlineImages, - this->_maxTextureDimension, this->_baseName); + JSONObject* obj = createImageFromTexture(texture, jsonTexture.get(), this); if (obj) { return obj; } } { - JSONObject* obj = createImageFromTexture(texture, jsonTexture.get(), this->_inlineImages, - this->_maxTextureDimension, this->_baseName); + JSONObject* obj = createImageFromTexture(texture, jsonTexture.get(), this); if (obj) { return obj; } } { - JSONObject* obj = createImageFromTexture(texture, jsonTexture.get(), this->_inlineImages, - this->_maxTextureDimension, this->_baseName); + JSONObject* obj = createImageFromTexture(texture, jsonTexture.get(), this); if (obj) { return obj; }