diff --git a/src/osgPlugins/3dc/ReaderWriter3DC.cpp b/src/osgPlugins/3dc/ReaderWriter3DC.cpp index 8ddcbe0b3..c84ae85a9 100644 --- a/src/osgPlugins/3dc/ReaderWriter3DC.cpp +++ b/src/osgPlugins/3dc/ReaderWriter3DC.cpp @@ -11,21 +11,87 @@ #include #include +class Writer3DCNodeVisitor: public osg::NodeVisitor { -using namespace osg; + public: + Writer3DCNodeVisitor(std::ostream& fout) : + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _fout(fout) + { + // _fout << "# file written by OpenSceneGraph" << std::endl << std::endl; + } + + virtual void apply(osg::Geode &node); + + protected: + + Writer3DCNodeVisitor& operator = (const Writer3DCNodeVisitor&) { return *this; } + std::ostream& _fout; + +}; + +void Writer3DCNodeVisitor::apply( osg::Geode &node ) +{ + osg::Matrix matrix = osg::computeLocalToWorld(getNodePath()); + + unsigned int count = node.getNumDrawables(); + for ( unsigned int i = 0; i < count; i++ ) + { + osg::Geometry *geometry = node.getDrawable( i )->asGeometry(); + if ( geometry ) + { + osg::Vec3Array* vertices = dynamic_cast(geometry->getVertexArray()); + osg::Vec3Array* normals = dynamic_cast(geometry->getNormalArray()); + osg::Vec3Array* colours = dynamic_cast(geometry->getColorArray()); + + if ( vertices ) { + for (unsigned int ii=0;iisize();ii++) { + + // update nodes with world coords + osg::Vec3d v = vertices->at(ii) * matrix; + _fout << v[0] << ' ' << v[1] << ' ' << v[2]; + + if ( colours ) + { + v=colours->at(ii); + _fout << ' ' << (int)v[0]*255.0 << ' ' << (int)v[1]*255.0 << ' ' << (int)v[2]*255.0; + } + else + { + _fout << " 255 255 255"; + } + + if ( normals ) + { + v = normals->at(ii); + _fout << ' ' << v[0] << ' ' << v[1] << ' ' << v[2]; + } + else + { + _fout << " 0.0 0.0 1.0"; + } + + + _fout << std::endl; + } + } + + } + } +} class ReaderWriter3DC : public osgDB::ReaderWriter { public: - + ReaderWriter3DC() { supportsExtension("3dc","3DC point cloud format"); supportsExtension("asc","3DC point cloud format"); } - + virtual const char* className() const { return "3DC point cloud reader"; } - + virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); @@ -33,15 +99,28 @@ class ReaderWriter3DC : public osgDB::ReaderWriter std::string fileName = osgDB::findDataFile( file, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; - + osg::notify(osg::INFO) << "Reading file "<0) { - ++num; - - osg::Vec3 pos,normal; - int r,g,b; - - int a = sscanf(line,"%f %f %f %d %d %d %f %f %f", - &pos.x(),&pos.y(),&pos.z(), - &r,&g,&b, - &normal.x(),&normal.y(),&normal.z()); - - - if (a) + int matched = sscanf(line,"%f%c%f%c%f%c%d%c%d%c%d%c%f%c%f%c%f", + &pos.x(),&sep,&pos.y(),&sep,&pos.z(),&sep, + &r,&sep,&g,&sep,&b,&sep, + &normal.x(),&sep,&normal.y(),&sep,&normal.z()); + + if (matched) { - + if (vertices->size()>=targetNumVertices) { // finishing setting up the current geometry and add it to the geode. @@ -112,10 +150,10 @@ class ReaderWriter3DC : public osgDB::ReaderWriter geometry->setColorArray(colours); geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS,0,vertices->size())); - + geode->addDrawable(geometry); - // allocate a new geometry + // allocate a new geometry geometry = new osg::Geometry; vertices = new osg::Vec3Array; @@ -127,14 +165,12 @@ class ReaderWriter3DC : public osgDB::ReaderWriter colours->reserve(targetNumVertices); } - + vertices->push_back(pos); normals->push_back(normal); - colours->push_back(osg::Vec4ub(r,g,b,255)); - + colours->push_back(osg::Vec4ub(r,g,b,a)); } } - } @@ -148,11 +184,25 @@ class ReaderWriter3DC : public osgDB::ReaderWriter geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS,0,vertices->size())); geode->addDrawable(geometry); - + return geode; - + + } + + virtual WriteResult writeNode(const osg::Node& node,const std::string& fileName,const Options* options =NULL) const + { + if (!acceptsExtension(osgDB::getFileExtension(fileName))) + return WriteResult(WriteResult::FILE_NOT_HANDLED); + + osgDB::ofstream f(fileName.c_str()); + + Writer3DCNodeVisitor nv(f); + + // we must cast away constness + (const_cast(&node))->accept(nv); + + return WriteResult(WriteResult::FILE_SAVED); } - }; // now register with Registry to instantiate the above