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

Revision 9475, 49.6 kB (checked in by robert, 6 years ago)

From Andy Skinner, fixes for Solaris build

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