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

Revision 9961, 49.8 kB (checked in by robert, 5 years ago)

From Luc Frauciel, You'll find attached a modification in ive plugin for POLYGONSTIPPLE read/write.

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