Index: /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/3dc/ReaderWriter3DC.cpp
===================================================================
--- /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/3dc/ReaderWriter3DC.cpp (revision 9343)
+++ /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/3dc/ReaderWriter3DC.cpp (revision 11238)
@@ -12,11 +12,77 @@
 #include <string.h>
 
-
-using namespace osg;
+class Writer3DCNodeVisitor: public osg::NodeVisitor {
+
+    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<osg::Vec3Array*>(geometry->getVertexArray());
+            osg::Vec3Array* normals = dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray());
+            osg::Vec3Array* colours = dynamic_cast<osg::Vec3Array*>(geometry->getColorArray());
+
+            if ( vertices ) {
+                for (unsigned int ii=0;ii<vertices->size();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()
         {
@@ -24,7 +90,7 @@
             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
         {
@@ -34,13 +100,26 @@
             std::string fileName = osgDB::findDataFile( file, options );
             if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
-            
+
             osg::notify(osg::INFO) << "Reading file "<<fileName<<std::endl;
-    
+
             const int LINE_SIZE = 1024;
             char line[LINE_SIZE];
-            
+
+            unsigned int targetNumVertices = 10000;
+
+            osg::Geode* geode = new osg::Geode;
+
+            osg::Geometry* geometry = new osg::Geometry;
+
+            osg::Vec3Array* vertices = new osg::Vec3Array;
+            osg::Vec3Array* normals = new osg::Vec3Array;
+            osg::Vec4ubArray* colours = new osg::Vec4ubArray;
+
+            osg::Vec3 pos;
+            osg::Vec3 normal(0.0,0.0,1.0);
+            int r=255,g=255,b=255,a=255;
+            char sep;
+
             osgDB::ifstream fin(fileName.c_str());
-            
-            unsigned int num = 0;
             while (fin)
             {
@@ -51,55 +130,14 @@
                     osg::notify(osg::INFO) <<"Comment: "<<line<<std::endl;
                 }
-                else
-                {
-                    ++num;
-                }
-            }
-            
-            
-            osg::notify(osg::INFO) << "num="<<num<<std::endl;
-            
-            unsigned int targetNumVertices = 10000;
-           
-    
-            osg::Geode* geode = new osg::Geode;
-
-            osg::Geometry* geometry = new osg::Geometry;
-            
-            osg::Vec3Array* vertices = new osg::Vec3Array;
-            osg::Vec3Array* normals = new osg::Vec3Array;
-            osg::Vec4ubArray* colours = new osg::Vec4ubArray;
-            
-            vertices->reserve(targetNumVertices);
-            normals->reserve(targetNumVertices);
-            colours->reserve(targetNumVertices);
-            
-            fin.close();
-            
-            osgDB::ifstream fin2(fileName.c_str());
-            while (fin2)
-            {
-                fin2.getline(line,LINE_SIZE);
-                if (line[0]=='#')
-                {
-                    // comment line
-                    osg::notify(osg::INFO) <<"Comment: "<<line<<std::endl;
-                }
                 else if (strlen(line)>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)
                         {
@@ -113,8 +151,8 @@
                             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;
 
@@ -128,12 +166,10 @@
 
                         }
-                                                        
+
                         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));
                     }
                 }
-                
             }
 
@@ -149,9 +185,23 @@
 
             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<osg::Node*>(&node))->accept(nv);
+
+            return WriteResult(WriteResult::FILE_SAVED); 
+        }
 };
 
Index: /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/ac/ac3d.cpp
===================================================================
--- /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/ac/ac3d.cpp (revision 9527)
+++ /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/ac/ac3d.cpp (revision 11238)
@@ -166,25 +166,19 @@
         virtual WriteResult writeNode(const osg::Node& node,std::ostream& fout, const Options* opts) const
         {
-            try
-            {
-                // write ac file.
-                if(dynamic_cast<const osg::Group*>(&node)) {
-                    const osg::Group *gp=dynamic_cast<const osg::Group*>(&node);
-                    const unsigned int nch=gp->getNumChildren();
-                    for (unsigned int i=0; i<nch; i++) {
-                        writeNode(*(gp->getChild(i)), fout, opts);
-                    }
-                }
-                else
-                    osg::notify(osg::WARN)<<"File must start with a geode "<<std::endl;
-                fout.flush();
-                return WriteResult::FILE_SAVED;
-            }
-            catch(ac3d::Exception e)
-            {
-                osg::notify(osg::WARN)<<"Error parsing OSG tree: "<< e.getError() << std::endl;            
-            }
-            return WriteResult::FILE_NOT_HANDLED;
-
+            // write ac file.
+            if(dynamic_cast<const osg::Group*>(&node))
+            {
+                const osg::Group *gp=dynamic_cast<const osg::Group*>(&node);
+                const unsigned int nch=gp->getNumChildren();
+                for (unsigned int i=0; i<nch; i++)
+                {
+                    writeNode(*(gp->getChild(i)), fout, opts);
+                }
+            }
+            else
+                osg::notify(osg::WARN)<<"File must start with a geode "<<std::endl;
+            
+            fout.flush();
+            return WriteResult::FILE_SAVED;
         }
 private:
@@ -417,8 +411,23 @@
     TextureData toTextureData(const std::string& texName)
     {
+        // If it is already there, use this
         TextureDataMap::iterator i = mTextureStates.find(texName);
-        if (i == mTextureStates.end())
-            mTextureStates[texName].setTexture(texName, mOptions.get(), mModulateTexEnv.get());
-        return mTextureStates[texName];
+        if (i != mTextureStates.end())
+            return i->second;
+        // Try to load that texture.
+        TextureData textureData;
+        textureData.setTexture(texName, mOptions.get(), mModulateTexEnv.get());
+        if (textureData.valid()) {
+            mTextureStates[texName] = textureData;
+            return textureData;
+        }
+        // still no joy?, try with the stripped filename if this is different
+        // Try the pure file name if it is different
+        std::string simpleTexName = osgDB::getSimpleFileName(texName);
+        if (simpleTexName != texName)
+            return toTextureData(simpleTexName);
+
+        // Nothing that worked, return invalid data
+        return TextureData();
     }
 
@@ -1167,18 +1176,5 @@
         else if (token == "texture") {
             // read the texture name
-            std::string texname = readString(stream);
-
-            // strip absolute paths
-            if (texname[0] == '/' || 
-                (isalpha(texname[0]) && texname[1] == ':')) {
-                std::string::size_type p = texname.rfind('\\');
-                if (p != std::string::npos)
-                    texname = texname.substr(p+1, std::string::npos);
-                p = texname.rfind('/');
-                if (p != std::string::npos)
-                    texname = texname.substr(p+1, std::string::npos);
-            }
-        
-            textureData = fileData.toTextureData(texname);
+            textureData = fileData.toTextureData(readString(stream));
         }
         else if (token == "texrep") {
