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

Revision 10415, 55.3 kB (checked in by robert, 6 years ago)

From Mathias Froehlich, "We are currently getting issues with locale settings and some osg plugins.
Therefore I have changed all the occurances of atof by asciiToFloat or
asciiToDouble.

I believe that it is safe to do so at least for all the plugins.
Included here are also asciiToFloat conversion of environment variables. One
might argue that these should be locale dependent. But IMO these should be
set and interpreted by osg independent of the current locale.
"

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