root/OpenSceneGraph/trunk/src/osgPlugins/ive/DataOutputStream.cpp @ 10819

Revision 10819, 56.9 kB (checked in by robert, 4 years ago)

From Chris Hanson, " Add support for "OutputTextureFiles?" option to IVE plugin to permit creation of external
.dds texture files from internally-embedded textures during IVE writes."

From Robert Osfield, fixed a bug in the above submission, and changed the way that the filename of the file is passed into DataOutputStream? to avoid issues with the .ive's plugins ability to read from istreams.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/**********************************************************************
2 *
3 *    FILE:           DataOutputStream.cpp
4 *
5 *    DESCRIPTION:    Implements methods to write simple datatypes to an
6 *                    output stream.
7 *
8 *    CREATED BY:     Rune Schmidt Jensen
9 *
10 *    HISTORY:        Created 11.03.2003
11 *                    Updated for 1D textures - Don Burns 27.1.2004
12 *                    Updated for light model - Stan Blinov at 25 august 7512 from World Creation (7.09.2004)
13 *
14 *    Copyright 2003 VR-C
15 **********************************************************************/
16
17#include "DataOutputStream.h"
18#include "Exception.h"
19
20#include "StateSet.h"
21#include "AlphaFunc.h"
22#include "BlendColor.h"
23#include "Stencil.h"
24#include "BlendFunc.h"
25#include "BlendEquation.h"
26#include "Material.h"
27#include "CullFace.h"
28#include "ColorMask.h"
29#include "Depth.h"
30#include "ClipPlane.h"
31#include "PolygonOffset.h"
32#include "PolygonMode.h"
33#include "ShadeModel.h"
34#include "Point.h"
35#include "LineWidth.h"
36#include "LineStipple.h"
37#include "Texture1D.h"
38#include "Texture2D.h"
39#include "Texture3D.h"
40#include "TextureCubeMap.h"
41#include "TextureRectangle.h"
42#include "TexEnv.h"
43#include "TexEnvCombine.h"
44#include "TexGen.h"
45#include "TexMat.h"
46#include "FragmentProgram.h"
47#include "VertexProgram.h"
48#include "LightModel.h"
49#include "ProxyNode.h"
50#include "FrontFace.h"
51#include "Program.h"
52#include "Uniform.h"
53#include "Shader.h"
54#include "Viewport.h"
55#include "Scissor.h"
56#include "Image.h"
57#include "ImageSequence.h"
58#include "PointSprite.h"
59#include "Multisample.h"
60#include "Fog.h"
61#include "Light.h"
62#include "PolygonStipple.h"
63
64#include "Group.h"
65#include "MatrixTransform.h"
66#include "Camera.h"
67#include "CameraView.h"
68#include "Geode.h"
69#include "LightSource.h"
70#include "TexGenNode.h"
71#include "ClipNode.h"
72#include "Billboard.h"
73#include "Sequence.h"
74#include "LOD.h"
75#include "PagedLOD.h"
76#include "PositionAttitudeTransform.h"
77#include "AutoTransform.h"
78#include "DOFTransform.h"
79#include "Transform.h"
80#include "Switch.h"
81#include "OccluderNode.h"
82#include "OcclusionQueryNode.h"
83#include "Impostor.h"
84#include "CoordinateSystemNode.h"
85
86#include "LightPointNode.h"
87#include "MultiSwitch.h"
88#include "VisibilityGroup.h"
89
90#include "MultiTextureControl.h"
91#include "ShapeAttributeList.h"
92#include "Effect.h"
93#include "AnisotropicLighting.h"
94#include "BumpMapping.h"
95#include "Cartoon.h"
96#include "Scribe.h"
97#include "SpecularHighlights.h"
98
99#include "Geometry.h"
100#include "ShapeDrawable.h"
101
102#include "Shape.h"
103
104#include "Text.h"
105
106#include "TerrainTile.h"
107#include "Locator.h"
108#include "ImageLayer.h"
109#include "HeightFieldLayer.h"
110#include "CompositeLayer.h"
111#include "SwitchLayer.h"
112
113#include "Volume.h"
114#include "VolumeTile.h"
115#include "VolumeImageLayer.h"
116#include "VolumeCompositeLayer.h"
117#include "VolumeLocator.h"
118#include "VolumeCompositeProperty.h"
119#include "VolumeSwitchProperty.h"
120#include "VolumeScalarProperty.h"
121#include "VolumeTransferFunctionProperty.h"
122
123#include <osg/Notify>
124#include <osg/io_utils>
125#include <osgDB/FileUtils>
126#include <osgDB/FileNameUtils>
127#include <osgDB/fstream>
128#include <osgDB/WriteFile>
129
130#include <stdlib.h>
131#include <sstream>
132
133using namespace ive;
134
135
136DataOutputStream::DataOutputStream(std::ostream * ostream, const osgDB::ReaderWriter::Options* options)
137{
138    _verboseOutput = false;
139
140    _includeImageMode = IMAGE_INCLUDE_DATA;
141
142    _includeExternalReferences     = false;
143    _writeExternalReferenceFiles   = false;
144    _useOriginalExternalReferences = true;
145    _maximumErrorToSizeRatio       = 0.001;
146
147    _outputTextureFiles = false;
148    _textureFileNameNumber = 0;
149
150    _options = options;
151
152    _compressionLevel = 0;
153
154    if (options) _filename = options->getPluginStringData("filename");
155
156    if (_filename.empty())
157    {
158        // initialize _filename to a unique identifier in case a real filename is not supplied
159        std::ostringstream filenameBuilder;
160        filenameBuilder << "file" << ostream; // use address of ostream to formulate unique filename
161        _filename = filenameBuilder.str();
162    }
163
164    if (_options.get())
165    {
166        std::string optionsString = _options->getOptionString();
167   
168        if(optionsString.find("noTexturesInIVEFile")!=std::string::npos) {
169            setIncludeImageMode(IMAGE_REFERENCE_FILE);
170        } else if(optionsString.find("includeImageFileInIVEFile")!=std::string::npos) {
171            setIncludeImageMode(IMAGE_INCLUDE_FILE);
172        } else if(optionsString.find("compressImageData")!=std::string::npos) {
173            setIncludeImageMode(IMAGE_COMPRESS_DATA);
174        }
175        osg::notify(osg::DEBUG_INFO) << "ive::DataOutputStream.setIncludeImageMode()=" << getIncludeImageMode() << std::endl;
176
177        setIncludeExternalReferences(optionsString.find("inlineExternalReferencesInIVEFile")!=std::string::npos);
178        osg::notify(osg::DEBUG_INFO) << "ive::DataOutputStream.setIncludeExternalReferences()=" << getIncludeExternalReferences() << std::endl;
179
180        setWriteExternalReferenceFiles(optionsString.find("noWriteExternalReferenceFiles")==std::string::npos);
181        osg::notify(osg::DEBUG_INFO) << "ive::DataOutputStream.setWriteExternalReferenceFiles()=" << getWriteExternalReferenceFiles() << std::endl;
182
183        setUseOriginalExternalReferences(optionsString.find("useOriginalExternalReferences")!=std::string::npos);
184        osg::notify(osg::DEBUG_INFO) << "ive::DataOutputStream.setUseOriginalExternalReferences()=" << getUseOriginalExternalReferences() << std::endl;
185
186        setOutputTextureFiles(optionsString.find("OutputTextureFiles")!=std::string::npos);
187        osg::notify(osg::DEBUG_INFO) << "ive::DataOutputStream.setOutputTextureFiles()=" << getOutputTextureFiles() << std::endl;
188
189        _compressionLevel =  (optionsString.find("compressed")!=std::string::npos) ? 1 : 0;
190        osg::notify(osg::DEBUG_INFO) << "ive::DataOutputStream._compressionLevel=" << _compressionLevel << std::endl;
191
192        std::string::size_type terrainErrorPos = optionsString.find("TerrainMaximumErrorToSizeRatio=");
193        if (terrainErrorPos!=std::string::npos)
194        {
195            std::string::size_type endOfToken = optionsString.find_first_of('=', terrainErrorPos);
196            std::string::size_type endOfNumber = optionsString.find_first_of(' ', endOfToken);
197            std::string::size_type numOfCharInNumber = (endOfNumber != std::string::npos) ?
198                    endOfNumber-endOfToken-1 :
199                    optionsString.size()-endOfToken-1;
200
201            if (numOfCharInNumber>0)
202            {
203                std::string numberString = optionsString.substr(endOfToken+1, numOfCharInNumber);
204                _maximumErrorToSizeRatio = osg::asciiToDouble(numberString.c_str());
205               
206                osg::notify(osg::DEBUG_INFO)<<"TerrainMaximumErrorToSizeRatio = "<<_maximumErrorToSizeRatio<<std::endl;
207            }
208            else
209            {
210                osg::notify(osg::DEBUG_INFO)<<"Error no value to TerrainMaximumErrorToSizeRatio assigned"<<std::endl;
211            }
212        }
213    }
214
215    #ifndef USE_ZLIB
216    if (_compressionLevel>0)
217    {
218        osg::notify(osg::NOTICE) << "Compression not supported in this .ive version." << std::endl;
219        _compressionLevel = 0;
220    }
221    #endif
222
223    _output_ostream = _ostream = ostream;
224
225    if(!_ostream)
226    {
227        throwException("DataOutputStream::DataOutputStream(): null pointer exception in argument.");
228        return;
229    }
230
231    writeUInt(ENDIAN_TYPE) ;
232    writeUInt(getVersion());
233   
234    writeInt(_compressionLevel);
235
236    if (_compressionLevel>0)
237    {
238   
239        _ostream = &_compressionStream;       
240    }
241}
242
243DataOutputStream::~DataOutputStream()
244{
245    if (_compressionLevel>0)
246    {
247        _ostream = _output_ostream;
248
249        std::string compressionString(_compressionStream.str());
250        writeUInt(compressionString.size());
251       
252        compress(*_output_ostream, compressionString);
253    }
254}
255
256#ifdef USE_ZLIB
257
258#include <zlib.h>
259
260#define CHUNK 16384
261bool DataOutputStream::compress(std::ostream& fout, const std::string& source) const
262{
263    int ret, flush = Z_FINISH;
264    unsigned have;
265    z_stream strm;
266    unsigned char out[CHUNK];
267   
268    int level = 6;
269    int stategy = Z_DEFAULT_STRATEGY; // looks to be the best for .osg/.ive files
270    //int stategy = Z_FILTERED;
271    //int stategy = Z_HUFFMAN_ONLY;
272    //int stategy = Z_RLE;
273
274    /* allocate deflate state */
275    strm.zalloc = Z_NULL;
276    strm.zfree = Z_NULL;
277    strm.opaque = Z_NULL;
278    ret = deflateInit2(&strm,
279                       level,
280                       Z_DEFLATED,
281                       15+16, // +16 to use gzip encoding
282                       8, // default
283                       stategy);
284    if (ret != Z_OK)
285    return false;
286
287    strm.avail_in = source.size();
288    strm.next_in = (Bytef*)(&(*source.begin()));
289
290    /* run deflate() on input until output buffer not full, finish
291       compression if all of source has been read in */
292    do {
293        strm.avail_out = CHUNK;
294        strm.next_out = out;
295        ret = deflate(&strm, flush);    /* no bad return value */
296
297        if (ret == Z_STREAM_ERROR)
298        {
299            osg::notify(osg::NOTICE)<<"Z_STREAM_ERROR"<<std::endl;
300            return false;
301        }
302
303        have = CHUNK - strm.avail_out;
304
305        if (have>0) fout.write((const char*)out, have);
306       
307        if (fout.fail())
308        {
309            (void)deflateEnd(&strm);
310            return false;
311        }
312    } while (strm.avail_out == 0);
313
314    /* clean up and return */
315    (void)deflateEnd(&strm);
316    return true;
317}
318#else
319bool DataOutputStream::compress(std::ostream& fout, const std::string& source) const
320{
321    return false;
322}
323#endif
324
325void DataOutputStream::writeBool(bool b)
326{
327    char c = b?1:0;
328    _ostream->write(&c, CHARSIZE);
329
330    if (_verboseOutput) std::cout<<"read/writeBool() ["<<(int)c<<"]"<<std::endl;
331}
332
333void DataOutputStream::writeChar(char c){
334    _ostream->write(&c, CHARSIZE);
335
336    if (_verboseOutput) std::cout<<"read/writeChar() ["<<(int)c<<"]"<<std::endl;
337}
338
339void DataOutputStream::writeUChar(unsigned char c){
340    _ostream->write((char*)&c, CHARSIZE);
341
342    if (_verboseOutput) std::cout<<"read/writeUChar() ["<<(int)c<<"]"<<std::endl;
343}
344
345void DataOutputStream::writeUShort(unsigned short s){
346    _ostream->write((char*)&s, SHORTSIZE);
347
348    if (_verboseOutput) std::cout<<"read/writeUShort() ["<<s<<"]"<<std::endl;
349}
350
351void DataOutputStream::writeShort(short s){
352    _ostream->write((char*)&s, SHORTSIZE);
353
354    if (_verboseOutput) std::cout<<"read/writeShort() ["<<s<<"]"<<std::endl;
355}
356
357void DataOutputStream::writeUInt(unsigned int s){
358    _ostream->write((char*)&s, INTSIZE);
359
360    if (_verboseOutput) std::cout<<"read/writeUInt() ["<<s<<"]"<<std::endl;
361}
362
363void DataOutputStream::writeInt(int i){
364    _ostream->write((char*)&i, INTSIZE);
365
366    if (_verboseOutput) std::cout<<"read/writeInt() ["<<i<<"]"<<std::endl;
367}
368
369void DataOutputStream::writeFloat(float f){
370    _ostream->write((char*)&f, FLOATSIZE);
371
372    if (_verboseOutput) std::cout<<"read/writeFloat() ["<<f<<"]"<<std::endl;
373}
374
375void DataOutputStream::writeLong(long l){
376    _ostream->write((char*)&l, LONGSIZE);
377
378    if (_verboseOutput) std::cout<<"read/writeLong() ["<<l<<"]"<<std::endl;
379}
380
381void DataOutputStream::writeULong(unsigned long l){
382    _ostream->write((char*)&l, LONGSIZE);
383
384    if (_verboseOutput) std::cout<<"read/writeULong() ["<<l<<"]"<<std::endl;
385}
386
387void DataOutputStream::writeDouble(double d){
388    _ostream->write((char*)&d, DOUBLESIZE);
389
390    if (_verboseOutput) std::cout<<"read/writeDouble() ["<<d<<"]"<<std::endl;
391}
392
393void DataOutputStream::writeString(const std::string& s){
394    writeInt(s.size());
395    _ostream->write(s.c_str(), s.size());
396
397    if (_verboseOutput) std::cout<<"read/writeString() ["<<s<<"]"<<std::endl;
398}
399
400void DataOutputStream::writeCharArray(const char* data, int size){
401    _ostream->write(data, size);
402
403    if (_verboseOutput) std::cout<<"read/writeCharArray() ["<<data<<"]"<<std::endl;
404}
405
406void DataOutputStream::writeVec2(const osg::Vec2& v){
407    writeFloat(v.x());
408    writeFloat(v.y());
409
410    if (_verboseOutput) std::cout<<"read/writeVec2() ["<<v<<"]"<<std::endl;
411}
412
413void DataOutputStream::writeVec3(const osg::Vec3& v){
414    writeFloat(v.x());
415    writeFloat(v.y());
416    writeFloat(v.z());
417
418    if (_verboseOutput) std::cout<<"read/writeVec3() ["<<v<<"]"<<std::endl;
419}
420
421void DataOutputStream::writeVec4(const osg::Vec4& v){
422    writeFloat(v.x());
423    writeFloat(v.y());
424    writeFloat(v.z());
425    writeFloat(v.w());
426
427    if (_verboseOutput) std::cout<<"read/writeVec4() ["<<v<<"]"<<std::endl;
428}
429
430void DataOutputStream::writeVec2d(const osg::Vec2d& v){
431    writeDouble(v.x());
432    writeDouble(v.y());
433
434    if (_verboseOutput) std::cout<<"read/writeVec2() ["<<v<<"]"<<std::endl;
435}
436
437void DataOutputStream::writeVec3d(const osg::Vec3d& v){
438    writeDouble(v.x());
439    writeDouble(v.y());
440    writeDouble(v.z());
441
442    if (_verboseOutput) std::cout<<"read/writeVec3d() ["<<v<<"]"<<std::endl;
443}
444
445void DataOutputStream::writeVec4d(const osg::Vec4d& v){
446    writeDouble(v.x());
447    writeDouble(v.y());
448    writeDouble(v.z());
449    writeDouble(v.w());
450
451    if (_verboseOutput) std::cout<<"read/writeVec4d() ["<<v<<"]"<<std::endl;
452}
453
454void DataOutputStream::writePlane(const osg::Plane& v)
455{
456    writeDouble(v[0]);
457    writeDouble(v[1]);
458    writeDouble(v[2]);
459    writeDouble(v[3]);
460
461    if (_verboseOutput) std::cout<<"read/writePlane() ["<<v<<"]"<<std::endl;
462}
463
464void DataOutputStream::writeVec4ub(const osg::Vec4ub& v){
465    writeChar(v.r());
466    writeChar(v.g());
467    writeChar(v.b());
468    writeChar(v.a());
469
470    if (_verboseOutput) std::cout<<"read/writeVec4ub() ["<<v<<"]"<<std::endl;
471}
472
473void DataOutputStream::writeVec2b(const osg::Vec2b& v){
474    writeChar(v.r());
475    writeChar(v.g());
476
477    if (_verboseOutput) std::cout<<"read/writeVec2b() ["<<v<<"]"<<std::endl;
478}
479
480void DataOutputStream::writeVec3b(const osg::Vec3b& v){
481    writeChar(v.r());
482    writeChar(v.g());
483    writeChar(v.b());
484
485    if (_verboseOutput) std::cout<<"read/writeVec3b() ["<<v<<"]"<<std::endl;
486}
487
488void DataOutputStream::writeVec4b(const osg::Vec4b& v){
489    writeChar(v.r());
490    writeChar(v.g());
491    writeChar(v.b());
492    writeChar(v.a());
493
494    if (_verboseOutput) std::cout<<"read/writeVec4b() ["<<v<<"]"<<std::endl;
495}
496
497void DataOutputStream::writeQuat(const osg::Quat& q){
498    writeFloat(q.x());
499    writeFloat(q.y());
500    writeFloat(q.z());
501    writeFloat(q.w());
502
503    if (_verboseOutput) std::cout<<"read/writeQuat() ["<<q<<"]"<<std::endl;
504}
505
506void DataOutputStream::writeBinding(osg::Geometry::AttributeBinding b){
507    switch(b){
508        case osg::Geometry::BIND_OFF:                writeChar((char) 0); break;
509        case osg::Geometry::BIND_OVERALL:            writeChar((char) 1); break;
510        case osg::Geometry::BIND_PER_PRIMITIVE:        writeChar((char) 2); break;
511        case osg::Geometry::BIND_PER_PRIMITIVE_SET:    writeChar((char) 3); break;
512        case osg::Geometry::BIND_PER_VERTEX:        writeChar((char) 4); break;
513        default: throwException("Unknown binding in DataOutputStream::writeBinding()");
514    }
515
516    if (_verboseOutput) std::cout<<"read/writeBinding() ["<<b<<"]"<<std::endl;
517}
518
519void DataOutputStream::writeArray(const osg::Array* a){
520    switch(a->getType()){
521        case osg::Array::IntArrayType:
522            writeChar((char)0);
523            writeIntArray(static_cast<const osg::IntArray*>(a));
524            break;
525        case osg::Array::UByteArrayType:
526            writeChar((char)1);
527            writeUByteArray(static_cast<const osg::UByteArray*>(a));
528            break;
529        case osg::Array::UShortArrayType:
530            writeChar((char)2);
531            writeUShortArray(static_cast<const osg::UShortArray*>(a));
532            break;
533        case osg::Array::UIntArrayType:
534            writeChar((char)3);
535            writeUIntArray(static_cast<const osg::UIntArray*>(a));
536            break;
537        case osg::Array::Vec4ubArrayType:
538            writeChar((char)4);
539            writeVec4ubArray(static_cast<const osg::Vec4ubArray*>(a));
540            break;
541        case osg::Array::FloatArrayType:
542            writeChar((char)5);
543            writeFloatArray(static_cast<const osg::FloatArray*>(a));
544            break;
545        case osg::Array::Vec2ArrayType:
546            writeChar((char)6);
547            writeVec2Array(static_cast<const osg::Vec2Array*>(a));
548            break;
549        case osg::Array::Vec3ArrayType:
550            writeChar((char)7);
551            writeVec3Array(static_cast<const osg::Vec3Array*>(a));
552            break;
553         case osg::Array::Vec4ArrayType:
554            writeChar((char)8);
555            writeVec4Array(static_cast<const osg::Vec4Array*>(a));
556            break;
557         case osg::Array::Vec2sArrayType:
558             writeChar((char)9);
559             writeVec2sArray(static_cast<const osg::Vec2sArray*>(a));
560             break;
561         case osg::Array::Vec3sArrayType:
562             writeChar((char)10);
563             writeVec3sArray(static_cast<const osg::Vec3sArray*>(a));
564             break;
565         case osg::Array::Vec4sArrayType:
566             writeChar((char)11);
567             writeVec4sArray(static_cast<const osg::Vec4sArray*>(a));
568             break;
569         case osg::Array::Vec2bArrayType:
570             writeChar((char)12);
571             writeVec2bArray(static_cast<const osg::Vec2bArray*>(a));
572             break;
573         case osg::Array::Vec3bArrayType:
574             writeChar((char)13);
575             writeVec3bArray(static_cast<const osg::Vec3bArray*>(a));
576             break;
577         case osg::Array::Vec4bArrayType:
578             writeChar((char)14);
579             writeVec4bArray(static_cast<const osg::Vec4bArray*>(a));
580             break;
581         case osg::Array::Vec2dArrayType:
582             writeChar((char)15);
583             writeVec2dArray(static_cast<const osg::Vec2dArray*>(a));
584             break;
585         case osg::Array::Vec3dArrayType:
586             writeChar((char)16);
587             writeVec3dArray(static_cast<const osg::Vec3dArray*>(a));
588             break;
589          case osg::Array::Vec4dArrayType:
590             writeChar((char)17);
591             writeVec4dArray(static_cast<const osg::Vec4dArray*>(a));
592             break;
593        default: throwException("Unknown array type in DataOutputStream::writeArray()");
594    }
595}
596
597
598void DataOutputStream::writeIntArray(const osg::IntArray* a)
599{
600    int size = a->getNumElements();
601    writeInt(size);
602    for(int i =0; i<size ;i++){
603        writeInt(a->index(i));
604    }
605
606    if (_verboseOutput) std::cout<<"read/writeIntArray() ["<<size<<"]"<<std::endl;
607}
608
609void DataOutputStream::writeUByteArray(const osg::UByteArray* a)
610{
611    int size = a->getNumElements();
612    writeInt(size);
613    for(int i =0; i<size ;i++){
614        writeChar((*a)[i]);
615    }
616
617    if (_verboseOutput) std::cout<<"read/writeUByteArray() ["<<size<<"]"<<std::endl;
618}
619
620void DataOutputStream::writeUShortArray(const osg::UShortArray* a)
621{
622    int size = a->getNumElements();
623    writeInt(size);
624    for(int i =0; i<size ;i++){
625        writeUShort((*a)[i]);
626    }
627
628    if (_verboseOutput) std::cout<<"read/writeUShortArray() ["<<size<<"]"<<std::endl;
629}
630
631void DataOutputStream::writeUIntArray(const osg::UIntArray* a)
632{
633    int size = a->getNumElements();
634    writeInt(size);
635    for(int i =0; i<size ;i++){
636        writeInt((*a)[i]);
637    }
638
639    if (_verboseOutput) std::cout<<"read/writeUIntArray() ["<<size<<"]"<<std::endl;
640}
641
642void DataOutputStream::writeVec4ubArray(const osg::Vec4ubArray* a)
643{
644    int size = a->getNumElements();
645    writeInt(size);
646    for(int i =0; i<size ;i++){
647        writeVec4ub((*a)[i]);
648    }
649
650    if (_verboseOutput) std::cout<<"read/writeVec4ubArray() ["<<size<<"]"<<std::endl;
651}
652
653void DataOutputStream::writePackedFloatArray(const osg::FloatArray* a, float maxError)
654{
655    int size = a->getNumElements();
656    writeInt(size);
657    if (size==0) return;
658   
659    float minValue = (*a)[0];
660    float maxValue = minValue;   
661    for(int i=1; i<size; ++i)
662    {
663        if ((*a)[i]<minValue) minValue = (*a)[i];
664        if ((*a)[i]>maxValue) maxValue = (*a)[i];
665    }
666   
667    if (minValue==maxValue)
668    {
669        osg::notify(osg::DEBUG_INFO)<<"Writing out "<<size<<" same values "<<minValue<<std::endl;
670
671        writeBool(true);
672        writeFloat(minValue);
673        return;
674    }
675
676    writeBool(false);
677   
678    int packingSize = 4;
679    if (maxError>0.0f)
680    {
681   
682        //float byteError = 0.0f;
683        float byteMultiplier = 255.0f/(maxValue-minValue);
684        float byteInvMultiplier = 1.0f/byteMultiplier;
685
686        //float shortError = 0.0f;
687        float shortMultiplier = 65535.0f/(maxValue-minValue);
688        float shortInvMultiplier = 1.0f/shortMultiplier;
689
690        float max_error_byte = 0.0f;
691        float max_error_short = 0.0f;
692
693        for(int i=0; i<size; ++i)
694        {
695            float value = (*a)[i];
696            unsigned char byteValue = (unsigned char)((value-minValue)*byteMultiplier);
697            unsigned short shortValue = (unsigned short)((value-minValue)*shortMultiplier);
698            float value_byte = minValue + float(byteValue)*byteInvMultiplier;
699            float value_short = minValue + float(shortValue)*shortInvMultiplier;
700
701            float error_byte = fabsf(value_byte - value);
702            float error_short = fabsf(value_short - value);
703
704            if (error_byte>max_error_byte) max_error_byte = error_byte;
705            if (error_short>max_error_short) max_error_short = error_short;
706        }
707
708        osg::notify(osg::DEBUG_INFO)<<"maxError "<<maxError<<std::endl;
709        osg::notify(osg::DEBUG_INFO)<<"Values to write "<<size<<" max_error_byte = "<<max_error_byte<<" max_error_short="<<max_error_short<<std::endl;
710
711
712        if (max_error_byte < maxError) packingSize = 1;
713        else if (max_error_short < maxError) packingSize = 2;
714
715        osg::notify(osg::DEBUG_INFO)<<"packingSize "<<packingSize<<std::endl;
716
717    }
718
719    if (packingSize==1)
720    {
721        writeInt(1);
722       
723        writeFloat(minValue);
724        writeFloat(maxValue);
725       
726        float byteMultiplier = 255.0f/(maxValue-minValue);
727
728        for(int i=0; i<size; ++i)
729        {
730            unsigned char currentValue = (unsigned char)(((*a)[i]-minValue)*byteMultiplier);
731            writeUChar(currentValue);
732        }
733    }
734    else if (packingSize==2)
735    {
736        writeInt(2);
737
738        writeFloat(minValue);
739        writeFloat(maxValue);
740       
741        float shortMultiplier = 65535.0f/(maxValue-minValue);
742
743        for(int i=0; i<size; ++i)
744        {
745            unsigned short currentValue = (unsigned short)(((*a)[i]-minValue)*shortMultiplier);
746            writeUShort(currentValue);
747        }
748    }
749    else
750    {           
751        writeInt(4);
752
753        for(int i=0; i<size; ++i)
754        {
755            writeFloat((*a)[i]);
756        }
757       
758    }
759
760    if (_verboseOutput) std::cout<<"read/writePackedFloatArray() ["<<size<<"]"<<std::endl;
761}
762
763
764void DataOutputStream::writeFloatArray(const osg::FloatArray* a)
765{
766    int size = a->getNumElements();
767    writeInt(size);
768    for(int i =0; i<size ;i++){
769        writeFloat((*a)[i]);
770    }
771
772    if (_verboseOutput) std::cout<<"read/writeFloatArray() ["<<size<<"]"<<std::endl;
773}
774
775
776void DataOutputStream::writeVec2Array(const osg::Vec2Array* a)
777{
778    int size = a->size();
779    writeInt(size);
780    for(int i=0;i<size;i++){
781        writeVec2((*a)[i]);
782    }
783
784    if (_verboseOutput) std::cout<<"read/writeVec2Array() ["<<size<<"]"<<std::endl;
785}
786
787void DataOutputStream::writeVec3Array(const osg::Vec3Array* a)
788{
789    int size = a->size();
790    writeInt(size);
791    for(int i = 0; i < size; i++){
792        writeVec3((*a)[i]);
793    }
794
795    if (_verboseOutput) std::cout<<"read/writeVec3Array() ["<<size<<"]"<<std::endl;
796}
797
798void DataOutputStream::writeVec4Array(const osg::Vec4Array* a)
799{
800    int size = a->size();
801    writeInt(size);
802    for(int i=0;i<size;i++){
803        writeVec4((*a)[i]);
804    }
805
806    if (_verboseOutput) std::cout<<"read/writeVec4Array() ["<<size<<"]"<<std::endl;
807}
808
809void DataOutputStream::writeVec2sArray(const osg::Vec2sArray* a)
810{
811    int size = a->getNumElements();
812    writeInt(size);
813    for(int i =0; i<size ;i++){
814        writeShort((*a)[i].x());
815        writeShort((*a)[i].y());
816    }
817
818    if (_verboseOutput) std::cout<<"read/writeVec2sArray() ["<<size<<"]"<<std::endl;
819}
820
821void DataOutputStream::writeVec3sArray(const osg::Vec3sArray* a)
822{
823    int size = a->getNumElements();
824    writeInt(size);
825    for(int i =0; i<size ;i++){
826        writeShort((*a)[i].x());
827        writeShort((*a)[i].y());
828        writeShort((*a)[i].z());
829    }
830
831    if (_verboseOutput) std::cout<<"read/writeVec3sArray() ["<<size<<"]"<<std::endl;
832}
833
834void DataOutputStream::writeVec4sArray(const osg::Vec4sArray* a)
835{
836    int size = a->getNumElements();
837    writeInt(size);
838    for(int i =0; i<size ;i++){
839        writeShort((*a)[i].x());
840        writeShort((*a)[i].y());
841        writeShort((*a)[i].z());
842        writeShort((*a)[i].w());
843    }
844
845    if (_verboseOutput) std::cout<<"read/writeVec4sArray() ["<<size<<"]"<<std::endl;
846}
847
848void DataOutputStream::writeVec2bArray(const osg::Vec2bArray* a)
849{
850    int size = a->getNumElements();
851    writeInt(size);
852    for(int i =0; i<size ;i++){
853        writeVec2b((*a)[i]);
854    }
855
856    if (_verboseOutput) std::cout<<"read/writeVec2bArray() ["<<size<<"]"<<std::endl;
857}
858
859void DataOutputStream::writeVec3bArray(const osg::Vec3bArray* a)
860{
861    int size = a->getNumElements();
862    writeInt(size);
863    for(int i =0; i<size ;i++){
864        writeVec3b((*a)[i]);
865    }
866
867    if (_verboseOutput) std::cout<<"read/writeVec3bArray() ["<<size<<"]"<<std::endl;
868}
869
870void DataOutputStream::writeVec4bArray(const osg::Vec4bArray* a)
871{
872    int size = a->getNumElements();
873    writeInt(size);
874    for(int i =0; i<size ;i++){
875        writeVec4b((*a)[i]);
876    }
877
878    if (_verboseOutput) std::cout<<"read/writeVec4bArray() ["<<size<<"]"<<std::endl;
879}
880
881void DataOutputStream::writeVec2dArray(const osg::Vec2dArray* a)
882{
883    int size = a->size();
884    writeInt(size);
885    for(int i=0;i<size;i++){
886        writeVec2d((*a)[i]);
887    }
888
889    if (_verboseOutput) std::cout<<"read/writeVec2dArray() ["<<size<<"]"<<std::endl;
890}
891
892void DataOutputStream::writeVec3dArray(const osg::Vec3dArray* a)
893{
894    int size = a->size();
895    writeInt(size);
896    for(int i = 0; i < size; i++){
897        writeVec3d((*a)[i]);
898    }
899
900    if (_verboseOutput) std::cout<<"read/writeVec3dArray() ["<<size<<"]"<<std::endl;
901}
902
903void DataOutputStream::writeVec4dArray(const osg::Vec4dArray* a)
904{
905    int size = a->size();
906    writeInt(size);
907    for(int i=0;i<size;i++){
908        writeVec4d((*a)[i]);
909    }
910
911    if (_verboseOutput) std::cout<<"read/writeVec4dArray() ["<<size<<"]"<<std::endl;
912}
913
914void DataOutputStream::writeMatrixf(const osg::Matrixf& mat)
915{
916    for(int r=0;r<4;r++)
917    {
918        for(int c=0;c<4;c++)
919        {
920            writeFloat(mat(r,c));
921        }
922    }
923
924    if (_verboseOutput) std::cout<<"read/writeMatrix() ["<<mat<<"]"<<std::endl;
925}
926
927void DataOutputStream::writeMatrixd(const osg::Matrixd& mat)
928{
929    for(int r=0;r<4;r++)
930    {
931        for(int c=0;c<4;c++)
932        {
933            writeDouble(mat(r,c));
934        }
935    }
936
937    if (_verboseOutput) std::cout<<"read/writeMatrix() ["<<mat<<"]"<<std::endl;
938}
939
940
941void DataOutputStream::writeStateSet(const osg::StateSet* stateset)
942{
943    StateSetMap::iterator itr = _stateSetMap.find(stateset);
944    if (itr!=_stateSetMap.end())
945    {
946        // Id already exists so just write ID.
947        writeInt(itr->second);
948
949        if (_verboseOutput) std::cout<<"read/writeStateSet() ["<<itr->second<<"]"<<std::endl;
950    }
951    else
952    {
953        // id doesn't exist so create a new ID and
954        // register the stateset.
955
956        int id = _stateSetMap.size();
957        _stateSetMap[stateset] = id;
958
959        // write the id.
960        writeInt(id);
961
962        // write the stateset.
963        ((ive::StateSet*)(stateset))->write(this);
964
965        if (_verboseOutput) std::cout<<"read/writeStateSet() ["<<id<<"]"<<std::endl;
966
967    }
968}
969
970void DataOutputStream::writeStateAttribute(const osg::StateAttribute* attribute)
971{
972    StateAttributeMap::iterator itr = _stateAttributeMap.find(attribute);
973    if (itr!=_stateAttributeMap.end())
974    {
975        // Id already exists so just write ID.
976        writeInt(itr->second);
977        if (_verboseOutput) std::cout<<"read/writeStateAttribute() ["<<itr->second<<"]"<<std::endl;
978    }
979    else
980    {
981        // id doesn't exist so create a new ID and
982        // register the stateset.
983
984        int id = _stateAttributeMap.size();
985        _stateAttributeMap[attribute] = id;
986
987        // write the id.
988        writeInt(id);
989
990        // write the stateset.
991        if(dynamic_cast<const osg::AlphaFunc*>(attribute)){
992            ((ive::AlphaFunc*)(attribute))->write(this);
993        }
994        else if(dynamic_cast<const osg::BlendColor*>(attribute)){
995            ((ive::BlendColor*)(attribute))->write(this);
996        }
997        else if(dynamic_cast<const osg::Stencil*>(attribute)){
998            ((ive::Stencil*)(attribute))->write(this);
999        }
1000        else if(dynamic_cast<const osg::BlendFunc*>(attribute)){
1001            ((ive::BlendFunc*)(attribute))->write(this);
1002        }
1003        else if(dynamic_cast<const osg::BlendEquation*>(attribute)){
1004            ((ive::BlendEquation*)(attribute))->write(this);
1005        }
1006        else if(dynamic_cast<const osg::Depth*>(attribute)){
1007            ((ive::Depth*)(attribute))->write(this);
1008        }
1009        else if(dynamic_cast<const osg::Viewport*>(attribute)){
1010            ((ive::Viewport*)(attribute))->write(this);
1011        }
1012        else if(dynamic_cast<const osg::Scissor*>(attribute)){
1013            ((ive::Scissor*)(attribute))->write(this);
1014        }
1015        // This is a Material
1016        else if(dynamic_cast<const osg::Material*>(attribute)){
1017            ((ive::Material*)(attribute))->write(this);
1018        }
1019        // This is a CullFace
1020        else if(dynamic_cast<const osg::CullFace*>(attribute)){
1021            ((ive::CullFace*)(attribute))->write(this);
1022        }
1023        // This is a ColorMask
1024        else if(dynamic_cast<const osg::ColorMask*>(attribute)){
1025            ((ive::ColorMask*)(attribute))->write(this);
1026        }
1027        // this is a Cliplane
1028        else if(dynamic_cast<const osg::ClipPlane*>(attribute)){
1029            ((ive::ClipPlane*)(attribute))->write(this);
1030        }
1031        // This is a PolygonOffset
1032        else if(dynamic_cast<const osg::PolygonOffset*>(attribute)){
1033            ((ive::PolygonOffset*)(attribute))->write(this);
1034        }
1035        // This is a PolygonMode
1036        else if(dynamic_cast<const osg::PolygonMode*>(attribute)){
1037            ((ive::PolygonMode*)(attribute))->write(this);
1038        }
1039        else if(dynamic_cast<const osg::ShadeModel*>(attribute)){
1040            ((ive::ShadeModel*)(attribute))->write(this);
1041        }
1042        else if(dynamic_cast<const osg::Point*>(attribute)){
1043            ((ive::Point*)(attribute))->write(this);
1044        }
1045        else if(dynamic_cast<const osg::LineWidth*>(attribute)){
1046            ((ive::LineWidth*)(attribute))->write(this);
1047        }
1048        // This is a LineStipple
1049        else if(dynamic_cast<const osg::LineStipple*>(attribute)){
1050            ((ive::LineStipple*)(attribute))->write(this);
1051        }
1052        // This is a Texture1D
1053        else if(dynamic_cast<const osg::Texture1D*>(attribute)){
1054            ((ive::Texture1D*)(attribute))->write(this);
1055        }
1056        // This is a Texture2D
1057        else if(dynamic_cast<const osg::Texture2D*>(attribute)){
1058            ((ive::Texture2D*)(attribute))->write(this);
1059        }
1060        // This is a Texture2D
1061        else if(dynamic_cast<const osg::Texture3D*>(attribute)){
1062            ((ive::Texture3D*)(attribute))->write(this);
1063        }
1064        // This is a TextureCubeMap
1065        else if(dynamic_cast<const osg::TextureCubeMap*>(attribute)){
1066            ((ive::TextureCubeMap*)(attribute))->write(this);
1067        }
1068        // This is a TextureRectangle
1069        else if(dynamic_cast<const osg::TextureRectangle*>(attribute)){
1070            ((ive::TextureRectangle*)(attribute))->write(this);
1071        }
1072        // This is a TexEnv
1073        else if(dynamic_cast<const osg::TexEnv*>(attribute)){
1074            ((ive::TexEnv*)(attribute))->write(this);
1075        }
1076        // This is a TexEnvCombine
1077        else if(dynamic_cast<const osg::TexEnvCombine*>(attribute)){
1078            ((ive::TexEnvCombine*)(attribute))->write(this);
1079        }
1080        // This is a TexGen
1081        else if(dynamic_cast<const osg::TexGen*>(attribute)){
1082            ((ive::TexGen*)(attribute))->write(this);
1083        }
1084        // This is a TexMat
1085        else if(dynamic_cast<const osg::TexMat*>(attribute)){
1086            ((ive::TexMat*)(attribute))->write(this);
1087        }
1088        // This is a FragmentProgram
1089        else if(dynamic_cast<const osg::FragmentProgram*>(attribute)){
1090            ((ive::FragmentProgram*)(attribute))->write(this);
1091        }
1092        // This is a VertexProgram
1093        else if(dynamic_cast<const osg::VertexProgram*>(attribute)){
1094            ((ive::VertexProgram*)(attribute))->write(this);
1095        }
1096        // This is a LightModel
1097        else if(dynamic_cast<const osg::LightModel*>(attribute)){
1098            ((ive::LightModel*)(attribute))->write(this);
1099        }
1100        // This is a FrontFace
1101        else if(dynamic_cast<const osg::FrontFace*>(attribute)){
1102            ((ive::FrontFace*)(attribute))->write(this);
1103        }
1104        // This is a Program
1105        else if(dynamic_cast<const osg::Program*>(attribute)){
1106            ((ive::Program*)(attribute))->write(this);
1107        }
1108        // This is a PointSprite
1109        else if(dynamic_cast<const osg::PointSprite*>(attribute)){
1110            ((ive::PointSprite*)(attribute))->write(this);
1111        }
1112        // This is a Multisample
1113        else if(dynamic_cast<const osg::Multisample*>(attribute)){
1114            ((ive::Multisample*)(attribute))->write(this);
1115        }
1116        // This is a Fog
1117        else if(dynamic_cast<const osg::Fog*>(attribute)){
1118            ((ive::Fog*)(attribute))->write(this);
1119        }
1120        // This is a Light
1121        else if(dynamic_cast<const osg::Light*>(attribute)){
1122            ((ive::Light*)(attribute))->write(this);
1123        }
1124        // This is a PolygonStipple
1125        else if(dynamic_cast<const osg::PolygonStipple*>(attribute)){
1126            ((ive::PolygonStipple*)(attribute))->write(this);
1127        }
1128
1129        else{
1130            std::string className = attribute->className();
1131            throwException(std::string("StateSet::write(): Unknown StateAttribute: ").append(className));
1132        }
1133        if (_verboseOutput) std::cout<<"read/writeStateAttribute() ["<<id<<"]"<<std::endl;
1134    }
1135}
1136
1137void DataOutputStream::writeUniform(const osg::Uniform* uniform)
1138{
1139    UniformMap::iterator itr = _uniformMap.find(uniform);
1140    if (itr!=_uniformMap.end())
1141    {
1142        // Id already exists so just write ID.
1143        writeInt(itr->second);
1144
1145        if (_verboseOutput) std::cout<<"read/writeUniform() ["<<itr->second<<"]"<<std::endl;
1146    }
1147    else
1148    {
1149        // id doesn't exist so create a new ID and
1150        // register the uniform.
1151
1152        int id = _uniformMap.size();
1153        _uniformMap[uniform] = id;
1154
1155        // write the id.
1156        writeInt(id);
1157
1158        // write the stateset.
1159        ((ive::Uniform*)(uniform))->write(this);
1160
1161        if (_verboseOutput) std::cout<<"read/writeUniform() ["<<id<<"]"<<std::endl;
1162
1163    }
1164}
1165
1166void DataOutputStream::writeShader(const osg::Shader* shader)
1167{
1168    ShaderMap::iterator itr = _shaderMap.find(shader);
1169    if (itr!=_shaderMap.end())
1170    {
1171        // Id already exists so just write ID.
1172        writeInt(itr->second);
1173
1174        if (_verboseOutput) std::cout<<"read/writeShader() ["<<itr->second<<"]"<<std::endl;
1175    }
1176    else
1177    {
1178        // id doesn't exist so create a new ID and
1179        // register the shader.
1180
1181        int id = _shaderMap.size();
1182        _shaderMap[shader] = id;
1183
1184        // write the id.
1185        writeInt(id);
1186
1187        // write the stateset.
1188        ((ive::Shader*)(shader))->write(this);
1189
1190        if (_verboseOutput) std::cout<<"read/writeShader() ["<<id<<"]"<<std::endl;
1191
1192    }
1193}
1194
1195void DataOutputStream::writeDrawable(const osg::Drawable* drawable)
1196{
1197    DrawableMap::iterator itr = _drawableMap.find(drawable);
1198    if (itr!=_drawableMap.end())
1199    {
1200        // Id already exists so just write ID.
1201        writeInt(itr->second);
1202
1203        if (_verboseOutput) std::cout<<"read/writeDrawable() ["<<itr->second<<"]"<<std::endl;
1204    }
1205    else
1206    {
1207        // id doesn't exist so create a new ID and
1208        // register the stateset.
1209
1210        int id = _drawableMap.size();
1211        _drawableMap[drawable] = id;
1212
1213        // write the id.
1214        writeInt(id);
1215
1216        if(dynamic_cast<const osg::Geometry*>(drawable))
1217            ((ive::Geometry*)(drawable))->write(this);
1218        else if(dynamic_cast<const osg::ShapeDrawable*>(drawable))
1219            ((ive::ShapeDrawable*)(drawable))->write(this);
1220        else if(dynamic_cast<const osgText::Text*>(drawable))
1221            ((ive::Text*)(drawable))->write(this);
1222        else
1223        {
1224            throwException("Unknown drawable in DataOutputStream::writeDrawable()");
1225        }
1226        if (_verboseOutput) std::cout<<"read/writeDrawable() ["<<id<<"]"<<std::endl;
1227    }
1228}
1229
1230void DataOutputStream::writeShape(const osg::Shape* shape)
1231{
1232    ShapeMap::iterator itr = _shapeMap.find(shape);
1233    if (itr!=_shapeMap.end())
1234    {
1235        // Id already exists so just write ID.
1236        writeInt(itr->second);
1237
1238        if (_verboseOutput) std::cout<<"read/writeShape() ["<<itr->second<<"]"<<std::endl;
1239    }
1240    else
1241    {
1242        // id doesn't exist so create a new ID and
1243        // register the stateset.
1244
1245        int id = _shapeMap.size();
1246        _shapeMap[shape] = id;
1247
1248        // write the id.
1249        writeInt(id);
1250
1251        if(dynamic_cast<const osg::Sphere*>(shape))
1252            ((ive::Sphere*)(shape))->write(this);
1253        else if(dynamic_cast<const osg::Box*>(shape))
1254            ((ive::Box*)(shape))->write(this);
1255        else if(dynamic_cast<const osg::Cone*>(shape))
1256            ((ive::Cone*)(shape))->write(this);
1257        else if(dynamic_cast<const osg::Cylinder*>(shape))
1258            ((ive::Cylinder*)(shape))->write(this);
1259        else if(dynamic_cast<const osg::Capsule*>(shape))
1260            ((ive::Capsule*)(shape))->write(this);
1261        else if(dynamic_cast<const osg::HeightField*>(shape))
1262            ((ive::HeightField*)(shape))->write(this);
1263        else
1264        {
1265            throwException("Unknown shape in DataOutputStream::writeShape()");
1266        }
1267        if (_verboseOutput) std::cout<<"read/writeShape() ["<<id<<"]"<<std::endl;
1268    }
1269}
1270
1271void DataOutputStream::writeNode(const osg::Node* node)
1272{
1273    NodeMap::iterator itr = _nodeMap.find(node);
1274    if (itr!=_nodeMap.end())
1275    {
1276        // Id already exists so just write ID.
1277        writeInt(itr->second);
1278
1279        if (_verboseOutput) std::cout<<"read/writeNode() ["<<itr->second<<"]"<<std::endl;
1280    }
1281    else
1282    {
1283        // id doesn't exist so create a new ID and
1284        // register the node.
1285
1286        int id = _nodeMap.size();
1287        _nodeMap[node] = id;
1288
1289        // write the id.
1290        writeInt(id);
1291
1292        // this follow code *really* should use a NodeVisitor... Robert Osfield August 2003.
1293
1294        if(dynamic_cast<const osg::MatrixTransform*>(node)){
1295            ((ive::MatrixTransform*)(node))->write(this);
1296        }
1297        else if(dynamic_cast<const osg::Camera*>(node)){
1298            ((ive::Camera*)(node))->write(this);
1299        }
1300        else if(dynamic_cast<const osg::CameraView*>(node)){
1301            ((ive::CameraView*)(node))->write(this);
1302        }
1303        else if(dynamic_cast<const osg::PositionAttitudeTransform*>(node)){
1304            ((ive::PositionAttitudeTransform*)(node))->write(this);
1305        }
1306        else if(dynamic_cast<const osg::AutoTransform*>(node)){
1307            ((ive::AutoTransform*)(node))->write(this);
1308        }
1309        else if(dynamic_cast<const osgSim::DOFTransform*>(node)){
1310            ((ive::DOFTransform*)(node))->write(this);
1311        }
1312        else if(dynamic_cast<const osg::LightSource*>(node)){
1313            ((ive::LightSource*)(node))->write(this);
1314        }
1315        else if(dynamic_cast<const osg::TexGenNode*>(node)){
1316            ((ive::TexGenNode*)(node))->write(this);
1317        }
1318        else if(dynamic_cast<const osg::ClipNode*>(node)){
1319            ((ive::ClipNode*)(node))->write(this);
1320        }
1321        else if(dynamic_cast<const osg::Sequence*>(node)){
1322            ((ive::Sequence*)(node))->write(this);
1323        }
1324        else if(dynamic_cast<const osgSim::Impostor*>(node)){
1325            ((ive::Impostor*)(node))->write(this);
1326        }
1327        else if(dynamic_cast<const osg::PagedLOD*>(node)){
1328            ((ive::PagedLOD*)(node))->write(this);
1329        }
1330        else if(dynamic_cast<const osg::LOD*>(node)){
1331            ((ive::LOD*)(node))->write(this);
1332        }
1333        else if(dynamic_cast<const osg::Switch*>(node)){
1334            ((ive::Switch*)(node))->write(this);
1335        }
1336        else if(dynamic_cast<const osg::CoordinateSystemNode*>(node)){
1337            ((ive::CoordinateSystemNode*)(node))->write(this);
1338        }
1339        else if(dynamic_cast<const osgSim::MultiSwitch*>(node)){
1340            ((ive::MultiSwitch*)(node))->write(this);
1341        }
1342        else if(dynamic_cast<const osg::OccluderNode*>(node)){
1343            ((ive::OccluderNode*)(node))->write(this);
1344        }
1345        else if(dynamic_cast<const osg::OcclusionQueryNode*>(node)){
1346            ((ive::OcclusionQueryNode*)(node))->write(this);
1347        }
1348        else if(dynamic_cast<const osg::Transform*>(node)){
1349            ((ive::Transform*)(node))->write(this);
1350        }
1351        else if(dynamic_cast<const osgSim::VisibilityGroup*>(node)){
1352            ((ive::VisibilityGroup*)(node))->write(this);
1353        }
1354        else if(dynamic_cast<const osg::ProxyNode*>(node)){
1355            ((ive::ProxyNode*)(node))->write(this);
1356        }
1357        else if(dynamic_cast<const osgFX::MultiTextureControl*>(node)){
1358            ((ive::MultiTextureControl*)(node))->write(this);
1359        }
1360
1361
1362        else if(dynamic_cast<const osgFX::AnisotropicLighting*>(node)){
1363            ((ive::AnisotropicLighting*)(node))->write(this);
1364        }
1365        else if(dynamic_cast<const osgFX::BumpMapping*>(node)){
1366            ((ive::BumpMapping*)(node))->write(this);
1367        }
1368        else if(dynamic_cast<const osgFX::Cartoon*>(node)){
1369            ((ive::Cartoon*)(node))->write(this);
1370        }
1371        else if(dynamic_cast<const osgFX::Scribe*>(node)){
1372            ((ive::Scribe*)(node))->write(this);
1373        }
1374        else if(dynamic_cast<const osgFX::SpecularHighlights*>(node)){
1375            ((ive::SpecularHighlights*)(node))->write(this);
1376        }
1377
1378        else if(dynamic_cast<const osgTerrain::TerrainTile*>(node)){
1379            ((ive::TerrainTile*)(node))->write(this);
1380        }
1381        else if(dynamic_cast<const osgVolume::Volume*>(node)){
1382            ((ive::Volume*)(node))->write(this);
1383        }
1384        else if(dynamic_cast<const osgVolume::VolumeTile*>(node)){
1385            ((ive::VolumeTile*)(node))->write(this);
1386        }
1387
1388        else if(dynamic_cast<const osg::Group*>(node)){
1389            ((ive::Group*)(node))->write(this);
1390        }
1391
1392        else if(dynamic_cast<const osg::Billboard*>(node)){
1393            ((ive::Billboard*)(node))->write(this);
1394        }
1395        else if(dynamic_cast<const osg::Geode*>(node)){
1396            ((ive::Geode*)(node))->write(this);
1397        }
1398        else if(dynamic_cast<const osgSim::LightPointNode*>(node)){
1399            ((ive::LightPointNode*)(node))->write(this);
1400        }
1401        else
1402            throwException("Unknown node in Group::write()");
1403
1404        if (_verboseOutput) std::cout<<"read/writeNode() ["<<id<<"]"<<std::endl;
1405    }
1406}
1407
1408IncludeImageMode DataOutputStream::getIncludeImageMode(const osg::Image* image) const
1409{
1410    if (image)
1411    {
1412        if (image->getWriteHint()==osg::Image::STORE_INLINE)
1413        {
1414            return IMAGE_INCLUDE_DATA;
1415        }
1416        else if (image->getWriteHint()==osg::Image::EXTERNAL_FILE)
1417        {
1418            return IMAGE_REFERENCE_FILE;
1419        }
1420    }
1421    return getIncludeImageMode();
1422}
1423
1424
1425void DataOutputStream::writeImage(osg::Image *image)
1426{
1427    IncludeImageMode mode = getIncludeImageMode(image);
1428   
1429    if ( getVersion() >= VERSION_0029)
1430    {
1431        osg::ImageSequence* is = dynamic_cast<osg::ImageSequence*>(image);
1432        if (is)
1433        {
1434            ((ive::ImageSequence*)(is))->write(this);
1435        }
1436        else
1437        {
1438            writeInt(IVEIMAGE);
1439            writeChar(mode);
1440            writeImage(mode,image);
1441        }
1442    }
1443    else
1444    {
1445        writeChar(mode);
1446        writeImage(mode,image);
1447    }
1448}
1449
1450void DataOutputStream::writeImage(IncludeImageMode mode, osg::Image *image)
1451{
1452    switch(mode) {
1453        case IMAGE_INCLUDE_DATA:
1454            // Include image data in stream
1455            writeBool(image!=0);
1456            if(image)
1457                ((ive::Image*)image)->write(this);
1458            break;
1459        case IMAGE_REFERENCE_FILE:
1460        {
1461            if (image)
1462            {
1463                // Only include image name in stream
1464                std::string fileName = image->getFileName();
1465                // Export an image, if requested
1466                if (getOutputTextureFiles())
1467                {
1468                    if (fileName.empty())
1469                    { // synthesize a new faux filename
1470                        fileName = getTextureFileNameForOutput();
1471                    }
1472                    osgDB::writeImageFile(*image, fileName);
1473                }
1474                writeString(fileName);
1475            }
1476            else
1477            {
1478                writeString("");
1479            }
1480            break;
1481        }
1482        case IMAGE_INCLUDE_FILE:
1483            // Include image file in stream
1484            if(image && !(image->getFileName().empty())) {
1485                std::string fullPath = osgDB::findDataFile(image->getFileName(),_options.get());
1486                osgDB::ifstream infile(fullPath.c_str(), std::ios::in | std::ios::binary);
1487                if(infile) {
1488
1489                    //Write filename
1490                    writeString(image->getFileName());
1491
1492                    //Get size of file
1493                    infile.seekg(0,std::ios::end);
1494                    int size = infile.tellg();
1495                    infile.seekg(0,std::ios::beg);
1496
1497                    //Write file size
1498                    writeInt(size);
1499
1500                    //Read file data
1501                    char *buffer = new char[size];
1502                    infile.read(buffer,size);
1503
1504                    //Write file data
1505                    writeCharArray(buffer,size);
1506
1507                    //Delete buffer
1508                    delete [] buffer;
1509
1510                    //Close file
1511                    infile.close();
1512
1513                } else {
1514                    writeString("");
1515                    writeInt(0);
1516                }
1517            }
1518            else{
1519                writeString("");
1520                writeInt(0);
1521            }
1522            break;
1523        case IMAGE_COMPRESS_DATA:
1524            if(image)
1525            {
1526                //Get ReaderWriter for jpeg images
1527
1528                std::string extension = "png";
1529                if (image->getPixelFormat()==GL_RGB) extension = "jpg";
1530
1531                osgDB::ReaderWriter* writer = osgDB::Registry::instance()->getReaderWriterForExtension(extension);
1532
1533                if(writer)
1534                {
1535                    //Attempt to write the image to an output stream.
1536                    //The reason this isn't performed directly on the internal _ostream
1537                    //is because the writer might perform seek operations which could
1538                    //corrupt the output stream.
1539                    std::stringstream outputStream;
1540                    osgDB::ReaderWriter::WriteResult wr;
1541                    wr = writer->writeImage(*image,outputStream,_options.get());
1542
1543                    if(wr.success()) {
1544
1545                        //Write file format. Do this for two reasons:
1546                        // 1 - Same code can be used to read in as with IMAGE_INCLUDE_FILE mode
1547                        // 2 - Maybe in future version user can specify which format to use
1548                        writeString(std::string(".")+extension); //Need to add dot so osgDB::getFileExtension will work
1549
1550                        //Write size of stream
1551                        int size = outputStream.tellp();
1552                        writeInt(size);
1553
1554                        //Write stream
1555                        writeCharArray(outputStream.str().c_str(),size);
1556
1557                        return;
1558                    }
1559                }
1560            }
1561            //Image compression failed, write blank data
1562            writeString("");
1563            writeInt(0);
1564            break;
1565        default:
1566            throwException("DataOutputStream::writeImage(): Invalid IncludeImageMode value.");
1567            break;
1568    }
1569}
1570
1571
1572void DataOutputStream::writeLayer(const osgTerrain::Layer* layer)
1573{
1574    if (layer==0)
1575    {
1576        writeInt(-1);
1577        return;
1578    }
1579
1580    LayerMap::iterator itr = _layerMap.find(layer);
1581    if (itr!=_layerMap.end())
1582    {
1583        // Id already exists so just write ID.
1584        writeInt(itr->second);
1585
1586        if (_verboseOutput) std::cout<<"read/writeLayer() ["<<itr->second<<"]"<<std::endl;
1587    }
1588    else
1589    {
1590        // id doesn't exist so create a new ID and
1591        // register the stateset.
1592
1593        int id = _layerMap.size();
1594        _layerMap[layer] = id;
1595
1596        // write the id.
1597        writeInt(id);
1598
1599        if (dynamic_cast<const osgTerrain::HeightFieldLayer*>(layer))
1600        {
1601            ((ive::HeightFieldLayer*)(layer))->write(this);
1602        }
1603        else if (dynamic_cast<const osgTerrain::ImageLayer*>(layer))
1604        {
1605            ((ive::ImageLayer*)(layer))->write(this);
1606        }
1607        else if (dynamic_cast<const osgTerrain::SwitchLayer*>(layer))
1608        {
1609            ((ive::SwitchLayer*)(layer))->write(this);
1610        }
1611        else if (dynamic_cast<const osgTerrain::CompositeLayer*>(layer))
1612        {
1613            ((ive::CompositeLayer*)(layer))->write(this);
1614        }
1615        else if (dynamic_cast<const osgTerrain::ProxyLayer*>(layer))
1616        {
1617            writeInt(IVEPROXYLAYER);
1618            writeString(layer->getFileName());
1619
1620            const osgTerrain::Locator* locator = layer->getLocator();
1621            bool writeOutLocator = locator && !locator->getDefinedInFile();
1622            writeLocator(writeOutLocator ? locator : 0 );
1623
1624            writeUInt(layer->getMinLevel());
1625            writeUInt(layer->getMaxLevel());
1626        }
1627        else
1628        {
1629            throwException("Unknown layer in DataOutputStream::writeLayer()");
1630        }
1631        if (_verboseOutput) std::cout<<"read/writeLayer() ["<<id<<"]"<<std::endl;
1632    }
1633}
1634
1635
1636void DataOutputStream::writeLocator(const osgTerrain::Locator* locator)
1637{
1638    if (locator==0)
1639    {
1640        writeInt(-1);
1641        return;
1642    }
1643
1644    LocatorMap::iterator itr = _locatorMap.find(locator);
1645    if (itr!=_locatorMap.end())
1646    {
1647        // Id already exists so just write ID.
1648        writeInt(itr->second);
1649
1650        if (_verboseOutput) std::cout<<"read/writeLocator() ["<<itr->second<<"]"<<std::endl;
1651    }
1652    else
1653    {
1654        // id doesn't exist so create a new ID and
1655        // register the locator.
1656
1657        int id = _locatorMap.size();
1658        _locatorMap[locator] = id;
1659
1660        // write the id.
1661        writeInt(id);
1662
1663        // write the locator.
1664        ((ive::Locator*)(locator))->write(this);
1665
1666        if (_verboseOutput) std::cout<<"read/writeLocator() ["<<id<<"]"<<std::endl;
1667
1668    }
1669}
1670
1671void DataOutputStream::writeVolumeLayer(const osgVolume::Layer* layer)
1672{
1673    if (layer==0)
1674    {
1675        writeInt(-1);
1676        return;
1677    }
1678
1679    VolumeLayerMap::iterator itr = _volumeLayerMap.find(layer);
1680    if (itr!=_volumeLayerMap.end())
1681    {
1682        // Id already exists so just write ID.
1683        writeInt(itr->second);
1684
1685        if (_verboseOutput) std::cout<<"read/writeLayer() ["<<itr->second<<"]"<<std::endl;
1686    }
1687    else
1688    {
1689        // id doesn't exist so create a new ID and
1690        // register the stateset.
1691
1692        int id = _volumeLayerMap.size();
1693        _volumeLayerMap[layer] = id;
1694
1695        // write the id.
1696        writeInt(id);
1697
1698        if (dynamic_cast<const osgVolume::ImageLayer*>(layer))
1699        {
1700            ((ive::VolumeImageLayer*)(layer))->write(this);
1701        }
1702        else if (dynamic_cast<const osgVolume::CompositeLayer*>(layer))
1703        {
1704            ((ive::VolumeCompositeLayer*)(layer))->write(this);
1705        }
1706        else
1707        {
1708            throwException("Unknown layer in DataOutputStream::writeLayer()");
1709        }
1710        if (_verboseOutput) std::cout<<"read/writeLayer() ["<<id<<"]"<<std::endl;
1711    }
1712}
1713
1714
1715void DataOutputStream::writeVolumeLocator(const osgVolume::Locator* locator)
1716{
1717    if (locator==0)
1718    {
1719        writeInt(-1);
1720        return;
1721    }
1722
1723    VolumeLocatorMap::iterator itr = _volumeLocatorMap.find(locator);
1724    if (itr!=_volumeLocatorMap.end())
1725    {
1726        // Id already exists so just write ID.
1727        writeInt(itr->second);
1728
1729        if (_verboseOutput) std::cout<<"read/writeVolumeLocator() ["<<itr->second<<"]"<<std::endl;
1730    }
1731    else
1732    {
1733        // id doesn't exist so create a new ID and
1734        // register the locator.
1735
1736        int id = _volumeLocatorMap.size();
1737        _volumeLocatorMap[locator] = id;
1738
1739        // write the id.
1740        writeInt(id);
1741
1742        // write the locator.
1743        ((ive::VolumeLocator*)(locator))->write(this);
1744
1745        if (_verboseOutput) std::cout<<"read/writeVolumeLocator() ["<<id<<"]"<<std::endl;
1746
1747    }
1748}
1749
1750void DataOutputStream::writeVolumeProperty(const osgVolume::Property* property)
1751{
1752    if (property==0)
1753    {
1754        writeInt(-1);
1755        return;
1756    }
1757
1758    VolumePropertyMap::iterator itr = _volumePropertyMap.find(property);
1759    if (itr!=_volumePropertyMap.end())
1760    {
1761        // Id already exists so just write ID.
1762        writeInt(itr->second);
1763
1764        if (_verboseOutput) std::cout<<"read/writeVolumeLocator() ["<<itr->second<<"]"<<std::endl;
1765    }
1766    else
1767    {
1768        // id doesn't exist so create a new ID and
1769        // register the locator.
1770
1771        int id = _volumePropertyMap.size();
1772        _volumePropertyMap[property] = id;
1773
1774        // write the id.
1775        writeInt(id);
1776
1777        // write the propery
1778         if (dynamic_cast<const osgVolume::SwitchProperty*>(property))
1779        {
1780            ((ive::VolumeSwitchProperty*)(property))->write(this);
1781        }
1782        else if (dynamic_cast<const osgVolume::CompositeProperty*>(property))
1783        {
1784            ((ive::VolumeCompositeProperty*)(property))->write(this);
1785        }
1786        else if (dynamic_cast<const osgVolume::TransferFunctionProperty*>(property))
1787        {
1788            ((ive::VolumeTransferFunctionProperty*)(property))->write(this);
1789        }
1790        else if (dynamic_cast<const osgVolume::MaximumIntensityProjectionProperty*>(property))
1791        {
1792            writeInt(IVEVOLUMEMAXIMUMINTENSITYPROPERTY);
1793        }
1794        else if (dynamic_cast<const osgVolume::LightingProperty*>(property))
1795        {
1796            writeInt(IVEVOLUMELIGHTINGPROPERTY);
1797        }
1798        else if (dynamic_cast<const osgVolume::IsoSurfaceProperty*>(property))
1799        {
1800            writeInt(IVEVOLUMEISOSURFACEPROPERTY);
1801            ((ive::VolumeScalarProperty*)(property))->write(this);
1802        }
1803        else if (dynamic_cast<const osgVolume::AlphaFuncProperty*>(property))
1804        {
1805            writeInt(IVEVOLUMEALPHAFUNCPROPERTY);
1806            ((ive::VolumeScalarProperty*)(property))->write(this);
1807        }
1808        else if (dynamic_cast<const osgVolume::SampleDensityProperty*>(property))
1809        {
1810            writeInt(IVEVOLUMESAMPLEDENSITYPROPERTY);
1811            ((ive::VolumeScalarProperty*)(property))->write(this);
1812        }
1813        else if (dynamic_cast<const osgVolume::TransparencyProperty*>(property))
1814        {
1815            writeInt(IVEVOLUMETRANSPARENCYPROPERTY);
1816            ((ive::VolumeScalarProperty*)(property))->write(this);
1817        }
1818        else
1819        {
1820            throwException("Unknown layer in DataOutputStream::writVolumeProperty()");
1821        }
1822
1823        if (_verboseOutput) std::cout<<"read/writeVolumeProperty() ["<<id<<"]"<<std::endl;
1824
1825    }
1826}
1827
1828void DataOutputStream::writeObject(const osg::Object* object)
1829{
1830    const osg::Node* node = dynamic_cast<const osg::Node*>(object);
1831    if (node)
1832    {
1833        writeInt(IVENODE);
1834        writeNode(node);
1835        return;
1836    }
1837
1838    const osg::StateSet* stateset = dynamic_cast<const osg::StateSet*>(object);
1839    if (stateset)
1840    {
1841        writeInt(IVESTATESET);
1842        writeStateSet(stateset);
1843        return;
1844    }
1845
1846    const osg::StateAttribute* sa = dynamic_cast<const osg::StateAttribute*>(object);
1847    if (sa)
1848    {
1849        writeInt(IVESTATEATTRIBUTE);
1850        writeStateAttribute(sa);
1851        return;
1852    }
1853
1854    const osg::Drawable* drawable = dynamic_cast<const osg::Drawable*>(object);
1855    if (drawable)
1856    {
1857        writeInt(IVEDRAWABLE);
1858        writeDrawable(drawable);
1859        return;
1860    }
1861
1862    const osgSim::ShapeAttributeList* sal = dynamic_cast<const osgSim::ShapeAttributeList*>(object);
1863    if (sal)
1864    {
1865        writeInt(IVESHAPEATTRIBUTELIST);
1866        ((ive::ShapeAttributeList*)sal)->write(this);
1867        return;
1868    }
1869
1870    // fallback, osg::Object type not supported, so can't write out
1871    writeInt(-1);
1872}
1873
1874std::string DataOutputStream::getTextureFileNameForOutput()
1875{
1876    std::string fileName = osgDB::getNameLessExtension(_filename);
1877    if (_textureFileNameNumber>0)
1878    {
1879        std::ostringstream o;
1880        o << '_' << _textureFileNameNumber;
1881        fileName += o.str();
1882    }
1883   
1884    fileName += ".dds";
1885    ++_textureFileNameNumber;
1886   
1887    return fileName;
1888}
1889
1890
1891
1892void DataOutputStream::setExternalFileWritten(const std::string& filename, bool hasBeenWritten)
1893{
1894    _externalFileWritten[filename] = hasBeenWritten;
1895}
1896
1897bool DataOutputStream::getExternalFileWritten(const std::string& filename) const
1898{
1899    ExternalFileWrittenMap::const_iterator itr = _externalFileWritten.find(filename);
1900    if (itr != _externalFileWritten.end()) return itr->second;
1901    return false;
1902}
Note: See TracBrowser for help on using the browser.