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

Revision 13557, 57.4 kB (checked in by robert, 2 days ago)

Added shaders to support experimental shader based displacement mapping technique osgTerrain::ShaderTerrain?.

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