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

Revision 10762, 55.3 kB (checked in by robert, 5 years ago)

Converted .ive plugin from using C++ exceptions to using a local equivelant, enabling the build on embedded systems.

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