root/OpenSceneGraph/trunk/src/osgPlugins/vrml/ConvertToVRML.cpp @ 13502

Revision 13502, 42.2 kB (checked in by robert, 2 hours ago)

Added in source shaders

  • Property svn:eol-style set to native
Line 
1/*
2 *
3 * OSG to VRML2 converter for OpenSceneGraph.
4 *
5 * authors :
6 *           Johan Nouvel (johan_nouvel@yahoo.com)
7 *
8 *
9 */
10
11#include "ConvertToVRML.h"
12#include <iostream>
13#include <string.h>
14#include <limits>
15#include <osg/Quat>
16#include <osg/Geometry>
17#include <osg/Material>
18#include <osg/StateSet>
19#include <osg/TexGen>
20#include <osg/TexEnv>
21#include <osg/BoundingSphere>
22#include <osgDB/WriteFile>
23#include <osgDB/ReadFile>
24#include <osgDB/FileNameUtils>
25#include <osgDB/FileUtils>
26
27#include <osg/Image>
28
29using namespace std;
30
31/////////////////////////////////////////////////////////////////////////
32//
33// transformNode
34//
35/////////////////////////////////////////////////////////////////////////
36osg::Node* transformNode(const osg::Node& root) {
37
38  // create a zup to yup OSG Matrix
39  osg::MatrixTransform* ret = new osg::MatrixTransform();
40  osg::Matrix osgToVRMLMat(osg::Matrix(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0));
41
42  ret->setDataVariance(osg::Object::STATIC);
43  ret->setMatrix(osgToVRMLMat);
44
45  if (strcmp(root.className(), "MatrixTransform") == 0) {
46    const osg::MatrixTransform& aMat = static_cast<const osg::MatrixTransform&> (root);
47    osg::MatrixTransform* node = new osg::MatrixTransform(aMat);
48    ret->addChild(node);
49  } else if (strcmp(root.className(), "Group") == 0) {
50    const osg::Group& aGroup = static_cast<const osg::Group&> (root);
51    osg::Group* node = new osg::Group(aGroup);
52    ret->addChild(node);
53  } else if (strcmp(root.className(), "PositionAttitudeTransform") == 0) {
54    const osg::PositionAttitudeTransform& aPAT = static_cast<const osg::PositionAttitudeTransform&> (root);
55    osg::PositionAttitudeTransform* node = new osg::PositionAttitudeTransform(aPAT);
56    ret->addChild(node);
57  } else if (strcmp(root.className(), "Geode") == 0) {
58    const osg::Geode& aGeode = static_cast<const osg::Geode&> (root);
59    osg::Geode* node = new osg::Geode(aGeode);
60    ret->addChild(node);
61  } else {
62    osg::notify(osg::ALWAYS) << root.className() << " unsupported" << endl;
63  }
64  if (ret->getNumChildren() > 0) {
65    return ret;
66  }
67  return (NULL);
68}
69
70/////////////////////////////////////////////////////////////////////////
71//
72// convertToVRML
73//
74/////////////////////////////////////////////////////////////////////////
75osgDB::ReaderWriter::WriteResult convertToVRML(const osg::Node& root, const std::string& filename, const osgDB::ReaderWriter::Options* options) {
76
77  ToVRML toVrml(filename, options);
78
79  //cout << root.className() << endl;
80  osg::Node* aRoot = transformNode(root);
81
82  if (aRoot == NULL) {
83    return (osgDB::ReaderWriter::WriteResult(osgDB::ReaderWriter::WriteResult::FILE_NOT_HANDLED));
84  }
85  aRoot->accept(toVrml);
86
87  return (toVrml.result());
88}
89
90/////////////////////////////////////////////////////////////////////////
91//
92// ToVRML
93//
94/////////////////////////////////////////////////////////////////////////
95ToVRML::ToVRML(const std::string& fileName, const osgDB::ReaderWriter::Options* options) :
96  osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {
97
98  _fout.open(fileName.c_str(), ios::out);
99
100  if (!_fout) {
101    _res = osgDB::ReaderWriter::WriteResult::FILE_NOT_HANDLED;
102    return;
103  }
104  _res = osgDB::ReaderWriter::WriteResult::FILE_SAVED;
105
106  _pathToOutput = osgDB::getFilePath(fileName.c_str());
107  if (_pathToOutput == "") {
108    _pathToOutput = ".";
109  }
110  //std::cout<<" path -"<<_pathToOutput<<"-"<<std::endl;
111
112  _fout.precision(6);
113  _fout.setf(ios::fixed, ios::floatfield);
114
115  _strIndent = (char*) malloc(33);
116  for (int i = 0; i < 33; i++) {
117    _strIndent[i] = ' ';
118  }
119  _indent = 0;
120  _strIndent[0] = '\0';
121
122  //initialize
123  _fout << "#VRML V2.0 utf8\n\n";
124
125  _textureMode = CONVERT_TEXTURE;
126  _txtUnit = 0;
127
128  //_convertTextures = true;
129  _pathRelativeToOutput = ".";
130  if (options != NULL) {
131    std::string opt = options->getOptionString();
132    if (opt.find("convertTextures=0") != std::string::npos) {
133      //std::cout << "Read XML stream" << std::endl;
134      _textureMode = COPY_TEXTURE;
135
136    } else if (opt.find("convertTextures=-1") != std::string::npos) {
137      _textureMode = KEEP_ORIGINAL_TEXTURE;
138
139    } else if (opt.find("convertTextures=-2") != std::string::npos) {
140      _textureMode = NO_TEXTURE;
141
142    } else if (opt.find("convertTextures=-3") != std::string::npos) {
143      _textureMode = CONVERT_TEXTURE;
144    }
145
146    if (opt.find("directoryTextures=") != std::string::npos) {
147      std::string dirOpt = opt;
148      dirOpt.erase(0, dirOpt.find("directoryTextures=") + 18);
149      _pathRelativeToOutput = dirOpt.substr(0, dirOpt.find(' '));
150    }
151
152    if (opt.find("textureUnit=") != std::string::npos) {
153      std::string dirOpt = opt;
154      dirOpt.erase(0, dirOpt.find("textureUnit=") + 12);
155      _txtUnit = atoi(dirOpt.substr(0, dirOpt.find(' ')).c_str());
156    }
157  }
158
159  if (_textureMode != NO_TEXTURE) {
160    _defaultImage = new osg::Image();
161    _defaultImage->setFileName(_pathToOutput + "/" + _pathRelativeToOutput + "/default_texture.png");
162    int s = 1;
163    int t = 1;
164    unsigned char *data = new unsigned char[s * t * 3];
165    data[0] = 255;
166    data[1] = 255;
167    data[2] = 255;
168    _defaultImage->setImage(s, t, 0, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, data, osg::Image::USE_NEW_DELETE);
169    osgDB::writeImageFile(*(_defaultImage.get()), _defaultImage->getFileName());
170  }
171}
172
173/////////////////////////////////////////////////////////////////////////
174//
175// ~ToVRML
176//
177/////////////////////////////////////////////////////////////////////////
178ToVRML::~ToVRML() {
179  if (_fout) {
180    _fout.close();
181  }
182  free( _strIndent);
183
184}
185
186/////////////////////////////////////////////////////////////////////////
187//
188// indent
189//
190/////////////////////////////////////////////////////////////////////////
191char* ToVRML::indent() {
192  return (_strIndent);
193}
194
195/////////////////////////////////////////////////////////////////////////
196//
197// indentM
198//
199/////////////////////////////////////////////////////////////////////////
200char* ToVRML::indentM() {
201  _strIndent[_indent] = ' ';
202  _indent += 2;
203
204  if (_indent > 32) {
205    _indent = 32;
206  }
207  _strIndent[_indent] = '\0';
208
209  return (_strIndent);
210}
211
212/////////////////////////////////////////////////////////////////////////
213//
214// indentL
215//
216/////////////////////////////////////////////////////////////////////////
217char* ToVRML::indentL() {
218  _strIndent[_indent] = ' ';
219  _indent -= 2;
220
221  if (_indent < 0) {
222    _indent = 0;
223  }
224  _strIndent[_indent] = '\0';
225
226  return (_strIndent);
227}
228
229/////////////////////////////////////////////////////////////////////////
230//
231// apply(osg::Geode)
232//
233/////////////////////////////////////////////////////////////////////////
234void ToVRML::apply(osg::Geode& node) {
235  //cout << "Geode" << endl;
236
237  pushStateSetStack(node.getStateSet());
238
239  for (unsigned int i = 0; i < node.getNumDrawables(); i++) {
240    apply(node.getDrawable(i));
241  }
242  popStateSetStack();
243}
244
245/////////////////////////////////////////////////////////////////////////
246//
247// apply
248//
249/////////////////////////////////////////////////////////////////////////
250void ToVRML::apply(osg::Drawable* drawable) {
251  // get the drawable type
252  //cout<<"ICI "<<drawable->className()<<endl;
253  pushStateSetStack(drawable->getStateSet());
254
255  if (strcmp(drawable->className(), "Geometry") == 0) {
256    apply(drawable->asGeometry());
257  } else {
258    osg::notify(osg::ALWAYS) << "Drawable " << drawable->className() << " unsupported" << endl;
259  }
260
261  popStateSetStack();
262}
263
264/////////////////////////////////////////////////////////////////////////
265//
266// apply
267//
268/////////////////////////////////////////////////////////////////////////
269void ToVRML::apply(osg::Geometry* geom) {
270
271  if (geom->containsDeprecatedData()) geom->fixDeprecatedData();
272   
273  // are all primitives faces or line ?
274  GLenum mode;
275  osg::PrimitiveSet::Type type;
276
277  _fout << indent() << "Shape {\n";
278  indentM();
279  writeAppearance( getCurrentStateSet());
280  indentL();
281
282  int modePoints = 0;
283  int modeLines = 0;
284  int modeFaces = 0;
285
286  for (unsigned int p = 0; p < geom->getNumPrimitiveSets(); p++) {
287    mode = geom->getPrimitiveSet(p)->getMode();
288    if (mode == osg::PrimitiveSet::POINTS) {
289      modePoints++;
290
291    } else if ((mode == osg::PrimitiveSet::LINES) || (mode == osg::PrimitiveSet::LINE_STRIP) || (mode == osg::PrimitiveSet::LINE_LOOP)) {
292      modeLines++;
293
294    } else if ((mode == osg::PrimitiveSet::TRIANGLES) || (mode == osg::PrimitiveSet::TRIANGLE_STRIP) || (mode == osg::PrimitiveSet::TRIANGLE_FAN) || (mode
295    == osg::PrimitiveSet::QUADS) || (mode == osg::PrimitiveSet::QUAD_STRIP) || (mode == osg::PrimitiveSet::POLYGON)) {
296      modeFaces++;
297    }
298  }
299
300  //std::cout << "primitives type : Points " << modePoints << " Line " << modeLines << " Face " << modeFaces << std::endl;
301
302  if (modePoints > 0) {
303    _fout << indentM() << "geometry PointSet {\n";
304    for (unsigned int p = 0; p < geom->getNumPrimitiveSets(); p++) {
305      mode = geom->getPrimitiveSet(p)->getMode();
306      type = geom->getPrimitiveSet(p)->getType();
307      if (mode == osg::PrimitiveSet::POINTS) {
308        osg::notify(osg::WARN) << " osg::PrimitiveSetMode = POINTS not supported by VRML Writer" << std::endl;
309      }
310    }
311  }
312
313  if (modeLines > 0) {
314    _fout << indentM() << "geometry IndexedLineSet {\n";
315    for (unsigned int p = 0; p < geom->getNumPrimitiveSets(); p++) {
316      mode = geom->getPrimitiveSet(p)->getMode();
317      type = geom->getPrimitiveSet(p)->getType();
318      if ((mode == osg::PrimitiveSet::LINES) || (mode == osg::PrimitiveSet::LINE_STRIP) || (mode == osg::PrimitiveSet::LINE_LOOP)) {
319        osg::notify(osg::WARN) << " osg::PrimitiveSetMode = LINES, LINE_STRIP or LINE_LOOP not supported by VRML Writer" << std::endl;
320      }
321    }
322  }
323
324  if (modeFaces > 0) {
325    _fout << indentM() << "geometry IndexedFaceSet {\n";
326    _fout << indentM() << "solid FALSE\n";
327    indentL();
328    _fout << indentM() << "coordIndex [\n";
329    indentM();
330
331    std::vector<int> primitiveSetFaces;
332    int primitiveFaces = 0;
333
334    for (unsigned int p = 0; p < geom->getNumPrimitiveSets(); p++) {
335      mode = geom->getPrimitiveSet(p)->getMode();
336      type = geom->getPrimitiveSet(p)->getType();
337      if ((mode == osg::PrimitiveSet::TRIANGLES) || (mode == osg::PrimitiveSet::TRIANGLE_STRIP) || (mode == osg::PrimitiveSet::TRIANGLE_FAN) || (mode == osg::PrimitiveSet::QUADS)
338      || (mode == osg::PrimitiveSet::QUAD_STRIP) || (mode == osg::PrimitiveSet::POLYGON)) {
339        if (type == osg::PrimitiveSet::PrimitiveType) {
340          osg::notify(osg::WARN) << "osg::PrimitiveSet::PrimitiveType not supported by VRML Writer" << std::endl;
341
342        } else if (type == osg::PrimitiveSet::DrawArraysPrimitiveType) {
343          //std::cout << "osg::PrimitiveSet::DrawArraysPrimitiveType" << std::endl;
344          osg::ref_ptr < osg::DrawArrays > dra = dynamic_cast<osg::DrawArrays*> (geom->getPrimitiveSet(p));
345
346          unsigned int* indices = new unsigned int[dra->getCount()];
347          for (int j = 0; j < dra->getCount(); j++) {
348            indices[j] = dra->getFirst() + j;
349          }
350          writeCoordIndex(mode, indices, dra->getCount(), primitiveSetFaces, primitiveFaces);
351          delete[] indices;
352
353        } else if (type == osg::PrimitiveSet::DrawArrayLengthsPrimitiveType) {
354          //osg::notify(osg::WARN) << " osg::PrimitiveSet::DrawArrayLengthsPrimitiveType not supported by VRML Writer" << std::endl;
355          osg::ref_ptr < osg::DrawArrayLengths > dal = dynamic_cast<osg::DrawArrayLengths*> (geom->getPrimitiveSet(p));
356
357          //std::cout<<dal->getFirst()<<" "<<dal->getNumPrimitives()<<" "<<   dal->getNumIndices ()<<" "<< dal->getNumInstances()<<std::endl;
358          int first = 0;
359          for (unsigned int prim = dal->getFirst(); prim < dal->getNumPrimitives(); prim++) {
360            //std::cout<<(*dal)[prim]<<std::endl;
361            unsigned int numIndices = (*dal)[prim];
362            unsigned int * indices = new unsigned int[numIndices];
363            for (unsigned int i = 0; i < numIndices; i++) {
364              indices[i] = first + i;
365            }
366
367            first += (*dal)[prim];
368            // write coorIndex as if wa have an indexed geometry
369            writeCoordIndex(mode, indices, numIndices, primitiveSetFaces, primitiveFaces);
370            delete[] indices;
371          }
372
373        } else if (type == osg::PrimitiveSet::DrawElementsUBytePrimitiveType) {
374          //std::cout << "osg::PrimitiveSet::DrawElementsUBytePrimitiveType" << std::endl;
375
376          osg::ref_ptr < osg::DrawElementsUByte > drui = dynamic_cast<osg::DrawElementsUByte*> (geom->getPrimitiveSet(p));
377          const unsigned char * indices = (const unsigned char*) (drui->getDataPointer());
378          writeCoordIndex(mode, indices, drui->getNumIndices(), primitiveSetFaces, primitiveFaces);
379
380        } else if (type == osg::PrimitiveSet::DrawElementsUShortPrimitiveType) {
381          //std::cout << "osg::PrimitiveSet::DrawElementsUShortPrimitiveType" << std::endl;
382
383          osg::ref_ptr < osg::DrawElementsUShort > drui = dynamic_cast<osg::DrawElementsUShort*> (geom->getPrimitiveSet(p));
384          const unsigned short * indices = (const unsigned short*) (drui->getDataPointer());
385          writeCoordIndex(mode, indices, drui->getNumIndices(), primitiveSetFaces, primitiveFaces);
386
387        } else if (type == osg::PrimitiveSet::DrawElementsUIntPrimitiveType) {
388          //std::cout << "osg::PrimitiveSet::DrawElementsUIntPrimitiveType" << std::endl;
389
390          osg::ref_ptr < osg::DrawElementsUInt > drui = dynamic_cast<osg::DrawElementsUInt*> (geom->getPrimitiveSet(p));
391          const unsigned int * indices = (const unsigned int*) (drui->getDataPointer());
392          writeCoordIndex(mode, indices, drui->getNumIndices(), primitiveSetFaces, primitiveFaces);
393        }
394
395      }
396
397    }
398    _fout << indentL() << "]\n";
399    indentL();
400
401    //write vertex
402    writeCoord((osg::Vec3Array*) (geom->getVertexArray()));
403    //write texture coordinate
404    if (_textureMode != NO_TEXTURE) {
405      writeTexCoord((osg::Vec2Array*) (geom->getTexCoordArray(_txtUnit)), (osg::Vec3Array*) (geom->getVertexArray()));
406    }
407    //write normals
408    writeNormal(geom, primitiveSetFaces, primitiveFaces);
409    //write colors
410    writeColor(geom, primitiveSetFaces, primitiveFaces);
411  }
412
413  _fout << indent() << "}\n";
414  _fout << indentL() << "}\n";
415
416}
417
418/////////////////////////////////////////////////////////////////////////
419//
420// writeAppearance
421//
422/////////////////////////////////////////////////////////////////////////
423void ToVRML::writeAppearance(osg::StateSet* stateset) {
424
425  if (stateset == NULL) {
426    return;
427  }
428
429  osg::ref_ptr < osg::StateSet > ss = stateset;
430
431  _fout << indent() << "appearance Appearance {\n";
432  osg::Material* mat = (osg::Material*) (ss->getAttribute(osg::StateAttribute::MATERIAL));
433  osg::Texture2D* tex;
434  if (_textureMode == NO_TEXTURE) {
435    tex = NULL;
436  } else {
437    tex = (osg::Texture2D*) (ss->getTextureAttribute(_txtUnit, osg::StateAttribute::TEXTURE));
438  }
439
440  if (mat) {
441
442    bool alreadyLoaded;
443    std::string name;
444    osg::Vec4 ambient, diffuse, specular, emission;
445    float shininess;
446
447    ambient = mat->getAmbient(osg::Material::FRONT);
448    diffuse = mat->getDiffuse(osg::Material::FRONT);
449    specular = mat->getSpecular(osg::Material::FRONT);
450    shininess = mat->getShininess(osg::Material::FRONT);
451    emission = mat->getEmission(osg::Material::FRONT);
452
453    float transp = 1 - (ambient[3] + diffuse[3] + specular[3] + emission[3]) / 4.0;
454    if (transp < 0)
455      transp = 0;
456
457    //if (transp == 0 && tex) {
458    //  if (tex->getImage()->isImageTranslucent()) {
459    //    transp = 0.01;
460    //    mat->setTransparency(osg::Material::FRONT,transp);
461    //  }
462    //}
463
464    findMaterialName(mat, name, alreadyLoaded);
465    if (alreadyLoaded) {
466      _fout << indentM() << "material USE " << name << "\n";
467      indentL();
468    } else {
469
470      _fout << indentM() << "material DEF " << name << " Material {\n";
471      //_fout << indentM() << "material Material {\n";
472      _fout << indentM() << "diffuseColor " << diffuse[0] << " " << diffuse[1] << " " << diffuse[2] << "\n";
473      _fout << indent() << "emissiveColor " << emission[0] << " " << emission[1] << " " << emission[2] << "\n";
474
475      _fout << indent() << "specularColor " << specular[0] << " " << specular[1] << " " << specular[2] << "\n";
476      _fout << indent() << "shininess " << shininess << "\n";
477      float ambientI = (ambient[0] + ambient[1] + ambient[2]) / 3.0;
478      if (ambientI > 1)
479        ambientI = 1;
480      _fout << indent() << "ambientIntensity " << ambientI << "\n";
481
482      _fout << indent() << "transparency " << transp << "\n";
483      _fout << indentL() << "}\n";
484      indentL();
485    }
486  }
487
488  if (tex) {
489    bool alreadyLoaded;
490    std::string name;
491    findTextureName(tex, name, alreadyLoaded);
492    if (alreadyLoaded) {
493      _fout << indentM() << "texture USE " << name << "\n";
494      indentL();
495    } else {
496      _fout << indentM() << "texture DEF " << name << " ImageTexture {\n";
497      std::string texName = tex->getImage()->getFileName();
498      if (_textureMode == COPY_TEXTURE || _textureMode == CONVERT_TEXTURE) {
499        texName = _pathRelativeToOutput + "/" + osgDB::getSimpleFileName(texName);
500
501      } else if (_textureMode == KEEP_ORIGINAL_TEXTURE) {
502        texName = _pathRelativeToOutput + "/" + texName;
503      }
504      _fout << indentM() << "url [ \"" << texName << "\" ]\n";
505      //std::cout<<"WRAP "<<tex->getWrap(osg::Texture::WRAP_S)<<std::endl;
506      if (tex->getWrap(osg::Texture::WRAP_S) == osg::Texture::REPEAT) {
507        _fout << indent() << "repeatS TRUE\n";
508      } else {
509        _fout << indent() << "repeatS FALSE\n";
510      }
511      if (tex->getWrap(osg::Texture::WRAP_T) == osg::Texture::REPEAT) {
512        _fout << indent() << "repeatT TRUE\n";
513      } else {
514        _fout << indent() << "repeatT FALSE\n";
515      }
516      _fout << indentL() << "}\n";
517      indentL();
518    }
519  }
520
521  _fout << indent() << "}\n";
522
523}
524
525/////////////////////////////////////////////////////////////////////////
526//
527// apply(osg::Group)
528//
529/////////////////////////////////////////////////////////////////////////
530void ToVRML::apply(osg::Group& node) {
531  //cout << "Group" << endl;
532  _fout << indent() << "Group {\n";
533  _fout << indentM() << "children [\n";
534
535  pushStateSetStack(node.getStateSet());
536
537  indentM();
538  traverse(node);
539  indentL();
540
541  popStateSetStack();
542
543  _fout << indent() << "]\n";
544  _fout << indentL() << "}\n";
545}
546
547/////////////////////////////////////////////////////////////////////////
548//
549// apply(osg::MatrixTransform)
550//
551/////////////////////////////////////////////////////////////////////////
552void ToVRML::apply(osg::MatrixTransform& node) {
553  //cout << "MatrixTransform" << endl;
554  osg::Matrixf mat = node.getMatrix();
555  //   for(int i=0;i<16;i++){
556  //     cout <<mat.ptr()[i]<<" ";
557  //   }
558  //   cout<<endl;
559
560
561  osg::Vec3 trans = mat.getTrans();
562  osg::Vec3 scale = mat.getScale();
563  osg::Quat quat;
564  mat.get(quat);
565  double angle;
566  osg::Vec3 axe;
567  quat.getRotate(angle, axe);
568
569  _fout << indent() << "Transform {\n";
570  _fout << indentM() << "scale " << scale[0] << " " << scale[1] << " " << scale[2] << "\n";
571  //_fout << indentM() << "scale 1 1 1\n";
572  _fout << indent() << "translation " << trans[0] << " " << trans[1] << " " << trans[2] << "\n";
573  _fout << indent() << "rotation " << axe[0] << " " << axe[1] << " " << axe[2] << " " << angle << "\n";
574  _fout << indent() << "children [\n";
575
576  pushStateSetStack(node.getStateSet());
577
578  indentM();
579  traverse(node);
580  indentL();
581
582  popStateSetStack();
583
584  _fout << indent() << "]\n";
585
586  _fout << indentL() << "}\n";
587
588}
589
590/////////////////////////////////////////////////////////////////////////
591//
592// apply(osg::PositionAttitudeTransform)
593//
594/////////////////////////////////////////////////////////////////////////
595void ToVRML::apply(osg::PositionAttitudeTransform& node) {
596
597  osg::Vec3 trans = node.getPosition();
598  osg::Vec3 scale = node.getScale();
599  osg::Quat quat = node.getAttitude();
600  double angle;
601  osg::Vec3 axe;
602  quat.getRotate(angle, axe);
603
604  _fout << indent() << "Transform {\n";
605  _fout << indentM() << "scale " << scale[0] << " " << scale[1] << " " << scale[2] << "\n";
606  //_fout << indentM() << "scale 1 1 1\n";
607  _fout << indent() << "translation " << trans[0] << " " << trans[1] << " " << trans[2] << "\n";
608  _fout << indent() << "rotation " << axe[0] << " " << axe[1] << " " << axe[2] << " " << angle << "\n";
609  _fout << indent() << "children [\n";
610
611  pushStateSetStack(node.getStateSet());
612
613  indentM();
614  traverse(node);
615  indentL();
616
617  popStateSetStack();
618
619  _fout << indent() << "]\n";
620
621  _fout << indentL() << "}\n";
622
623}
624
625////////////////////////////////////////////////////////////////////////
626//
627// apply(osg::Billboard)
628//
629/////////////////////////////////////////////////////////////////////////
630void ToVRML::apply(osg::Billboard& node) {
631  osg::notify(osg::ALWAYS) << "WARNING : Billboard is changed to Group" << endl;
632  _fout << indent() << "Group {\n";
633  indentM();
634
635  //osg::Billboard::Mode mode = node.getMode();
636  //const osg::Vec3 axe = node.getAxis();
637  //const osg::Vec3 normal = node.getNormal();
638
639  //if (mode == osg::Billboard::AXIAL_ROT) {
640  //  _fout << indent() << "axisOfRotation " << axe[0] << " " << axe[1] << " " << axe[2] << "\n";
641  //}
642  //osg::BoundingSphere sph=node.getBound();
643  //_fout << indent() << "bboxCenter "<<sph.center()[0]<<" "<<sph.center()[1]<<" "<<sph.center()[2]<<"\n";
644  //_fout << indent() << "bboxSize "<<sph.radius()<<" "<<sph.radius()<<" "<<sph.radius()<<"\n";
645
646  _fout << indent() << "children [\n";
647
648  pushStateSetStack(node.getStateSet());
649
650  indentM();
651  for (unsigned int i = 0; i < node.getNumDrawables(); i++) {
652    osg::Vec3 trans = node.getPosition(i);
653    _fout << indent() << "Transform {\n";
654    _fout << indentM() << "translation " << trans[0] << " " << trans[1] << " " << trans[2] << "\n";
655    _fout << indent() << "children [\n";
656    indentM();
657    apply(node.getDrawable(i));
658    _fout << indentL() << "]\n";
659    _fout << indentL() << "}\n";
660  }
661
662  popStateSetStack();
663
664  _fout << indentL() << "]\n";
665  _fout << indentL() << "}\n";
666}
667
668////////////////////////////////////////////////////////////////////////
669//
670// apply(osg::LOD)
671//
672/////////////////////////////////////////////////////////////////////////
673void ToVRML::apply(osg::LOD& node) {
674  //std::cout << "LOD" << endl;
675  _fout << indent() << "LOD {\n";
676
677  bool fakeFirst = false;
678  bool fakeLast = false;
679  if (node.getMinRange(0) > 0) {
680    fakeFirst = true;
681  }
682  if (node.getMaxRange(node.getNumRanges() - 1) < std::numeric_limits<float>::max()) {
683    fakeLast = true;
684  }
685
686  _fout << indentM() << "level [\n";
687  if (fakeFirst) {
688    _fout << indentM() << "Shape {\n";
689    _fout << indent() << "}\n";
690    indentL();
691  }
692  pushStateSetStack(node.getStateSet());
693  indentM();
694  traverse(node);
695  indentL();
696  popStateSetStack();
697
698  if (fakeLast) {
699    _fout << indentM() << "Shape {\n";
700    _fout << indent() << "}\n";
701    indentL();
702  }
703
704  _fout << indent() << "]\n";
705
706  osg::Vec3 center;
707  if (node.getCenterMode() == osg::LOD::USER_DEFINED_CENTER) {
708    center = node.getCenter();
709  } else {
710    center = node.getBound().center();
711  }
712  _fout << indent() << "center " << center[0] << " " << center[1] << " " << center[2] << "\n";
713
714  _fout << indentM() << "range [";
715  if (fakeFirst) {
716    _fout << indentM() << node.getMinRange(0) << ",";
717  }
718  for (unsigned int i = 0; i < node.getNumRanges(); i++) {
719
720    _fout << indentM() << node.getMaxRange(i);
721    if (i < node.getNumRanges() - 1) {
722      _fout << ",";
723    }
724  }
725  _fout << "]\n";
726
727  _fout << indentL() << "}\n";
728}
729
730/////////////////////////////////////////////////////////////////////////
731//
732// apply(osg::Node)
733//
734/////////////////////////////////////////////////////////////////////////
735void ToVRML::apply(osg::Node& node) {
736  osg::notify(osg::ALWAYS) << node.className() << " not supported" << endl;
737  pushStateSetStack(node.getStateSet());
738  traverse(node);
739  popStateSetStack();
740}
741
742/////////////////////////////////////////////////////////////////////////
743//
744// pushStateSetStack
745//
746/////////////////////////////////////////////////////////////////////////
747void ToVRML::pushStateSetStack(osg::StateSet* ss) {
748  _stack.push_back(osg::ref_ptr<osg::StateSet>(ss));
749}
750
751/////////////////////////////////////////////////////////////////////////
752//
753// popStateSetStack
754//
755/////////////////////////////////////////////////////////////////////////
756void ToVRML::popStateSetStack() {
757  if (!_stack.empty()) {
758    _stack.pop_back();
759  }
760}
761
762/////////////////////////////////////////////////////////////////////////
763//
764// getCurrentStateSet
765//
766/////////////////////////////////////////////////////////////////////////
767osg::StateSet* ToVRML::getCurrentStateSet() {
768  // return current StateSet by flatten StateSet stack.
769  // until flatten is done, just return top StateSet
770  if (!_stack.empty()) {
771    osg::StateSet* ssFinal = new osg::StateSet();
772    ssFinal->setGlobalDefaults();
773    //std::cout << "StateSet Stack Size " << _stack.size() << std::endl;
774    for (unsigned int i = 0; i < _stack.size(); i++) {
775      osg::StateSet* ssCur = _stack[i].get();
776      if (ssCur != NULL) {
777        ssFinal->merge(*ssCur);
778      }
779    }
780    return (ssFinal);
781  } else
782    return (NULL);
783}
784
785/////////////////////////////////////////////////////////////////////////
786//
787// findMaterialName
788//
789/////////////////////////////////////////////////////////////////////////
790void ToVRML::findMaterialName(osg::Material* mat, std::string& name, bool& alreadyLoaded) {
791
792  osg::Vec4 ambient, diffuse, specular, emission;
793  //float shininess;
794  std::map<osg::ref_ptr<osg::Material>, std::string>::iterator it;// = _matMap.find(obj);
795
796  for (it = _matMap.begin(); it != _matMap.end(); it++) {
797    osg::ref_ptr < osg::Material > matLoaded = it->first;
798    ambient = mat->getAmbient(osg::Material::FRONT);
799    //diffuse = mat->getDiffuse(osg::Material::FRONT);
800    //specular = mat->getSpecular(osg::Material::FRONT);
801    //shininess = mat->getShininess(osg::Material::FRONT);
802    //emission = mat->getEmission(osg::Material::FRONT);
803    //std::cout << "MATERIAL " << ambient[3] << " " << matLoaded->getAmbient(osg::Material::FRONT)[3] << std::endl;
804
805    if ((matLoaded->getAmbient(osg::Material::FRONT) == mat->getAmbient(osg::Material::FRONT)) && (matLoaded->getDiffuse(osg::Material::FRONT)
806    == mat->getDiffuse(osg::Material::FRONT)) && (matLoaded->getSpecular(osg::Material::FRONT) == mat->getSpecular(osg::Material::FRONT))
807    && (matLoaded->getShininess(osg::Material::FRONT) == mat->getShininess(osg::Material::FRONT)) && (matLoaded->getEmission(osg::Material::FRONT)
808    == mat->getEmission(osg::Material::FRONT))) {
809
810      name = it->second;
811      alreadyLoaded = true;
812      return;
813    }
814  }
815  std::stringstream ss;
816  ss << "material_" << _matMap.size();
817  name = ss.str();
818  _matMap[mat] = name;
819  alreadyLoaded = false;
820
821}
822
823/////////////////////////////////////////////////////////////////////////
824//
825// findTextureName
826//
827/////////////////////////////////////////////////////////////////////////
828void ToVRML::findTextureName(osg::Texture2D* tex, std::string& name, bool& alreadyLoaded) {
829
830  //std::cout << "ORI -" << tex->getImage() << "- " << std::endl;
831  if (tex->getImage() == NULL) {
832    tex->setImage(_defaultImage.get());
833  }
834
835  std::string nameOri = osgDB::convertFileNameToNativeStyle(tex->getImage()->getFileName());
836  std::string nameInput = osgDB::findDataFile(nameOri, NULL);
837  if (nameInput == "") {
838    osg::notify(osg::ALWAYS) << "WARNING: couldn't find texture named: -" << nameOri << "- use default one instead -" << _defaultImage->getFileName() << "-" << std::endl;
839    tex->setImage(_defaultImage.get());
840    nameOri = osgDB::convertFileNameToNativeStyle(tex->getImage()->getFileName());
841    nameInput = osgDB::findDataFile(nameOri, NULL);
842  }
843
844  std::string nameOutput;
845  std::string::size_type pos = nameInput.find_last_of(".");
846  std::string ext = nameInput.substr(pos, nameInput.length() - pos);
847
848  osg::ref_ptr < osg::Image > imgIn = osgDB::readImageFile(nameInput);
849  if (!imgIn.valid()) {
850    osg::notify(osg::ALWAYS) << "WARNING: couldn't read texture named: -" << nameOri << "- use default one instead -" << _defaultImage->getFileName() << "-" << std::endl;
851    tex->setImage(_defaultImage.get());
852    nameOri = osgDB::convertFileNameToNativeStyle(tex->getImage()->getFileName());
853    nameInput = osgDB::findDataFile(nameOri, NULL);
854    pos = nameInput.find_last_of(".");
855    nameInput.substr(pos, nameInput.length() - pos);
856    imgIn = _defaultImage.get();
857  }
858
859  //int nbBand = poSrcDS->GetRasterCount();
860  if (_textureMode == KEEP_ORIGINAL_TEXTURE) {
861    nameOutput = nameInput;
862
863  } else if (_textureMode == COPY_TEXTURE) {
864    nameOutput = _pathToOutput + "/" + _pathRelativeToOutput + "/" + osgDB::getSimpleFileName(nameInput);
865
866  } else if (_textureMode == CONVERT_TEXTURE) {
867    nameOutput = _pathToOutput + "/" + _pathRelativeToOutput + "/" + osgDB::getSimpleFileName(nameInput);
868    if (ext != ".png" && ext != ".jpg") {
869      if (imgIn->isImageTranslucent()) {//(nbBand != 1 && nbBand != 3) {
870        nameOutput = _pathToOutput + "/" + _pathRelativeToOutput + "/" + osgDB::getSimpleFileName(nameInput.substr(0, pos) + ".png");
871      } else {
872        nameOutput = _pathToOutput + "/" + _pathRelativeToOutput + "/" + osgDB::getSimpleFileName(nameInput.substr(0, pos) + ".jpg");
873      }
874    }
875  }
876
877  std::map<osg::ref_ptr<osg::Texture2D>, std::string>::iterator it;
878  for (it = _texMap.begin(); it != _texMap.end(); it++) {
879    osg::ref_ptr < osg::Texture2D > texLoaded = it->first;
880
881    if ((nameOutput == texLoaded->getImage()->getFileName()) && (tex->getWrap(osg::Texture::WRAP_S) == texLoaded->getWrap(osg::Texture::WRAP_S))
882    && (tex->getWrap(osg::Texture::WRAP_T) == texLoaded->getWrap(osg::Texture::WRAP_T))) {
883      name = it->second;
884      alreadyLoaded = true;
885      return;
886    }
887  }
888
889  // first time we see these texture
890  // add it to textureMap
891  std::stringstream ss;
892  ss << "texture2D_" << _texMap.size();
893  name = ss.str();
894  _texMap[tex] = name;
895  alreadyLoaded = false;
896
897  tex->getImage()->setFileName(nameOutput);
898
899  if (nameInput == nameOutput) {
900    return;
901  }
902  // else write image file
903
904  if (_textureMode == CONVERT_TEXTURE) {
905    // convert format (from dds to rgb or rgba, or from rgba to rgb)
906    std::string newName;
907    GLenum type = GL_UNSIGNED_BYTE;
908    GLenum pixelFormat;
909    GLint internalFormat;
910    int nbC;
911    if (imgIn->isImageTranslucent()) {
912      // convert to png if transparency
913      pixelFormat = GL_RGBA;
914      internalFormat = GL_RGBA;
915      nbC = 4;
916    } else {
917      // convert to jpeg if no transparency
918      pixelFormat = GL_RGB;
919      internalFormat = GL_RGB;
920      nbC = 3;
921    }
922    osg::ref_ptr < osg::Image > curImg = tex->getImage();
923    osg::ref_ptr < osg::Image > mmImg = new osg::Image();
924    unsigned char* data = new unsigned char[curImg->s() * curImg->t() * nbC];
925    for (int j = 0; j < curImg->t(); j++) {
926      for (int i = 0; i < curImg->s(); i++) {
927        osg::Vec4 c = curImg->getColor(i, j);
928        data[(i + j * curImg->s()) * nbC] = c[0] * 255;
929        data[(i + j * curImg->s()) * nbC + 1] = c[1] * 255;
930        data[(i + j * curImg->s()) * nbC + 2] = c[2] * 255;
931        if (nbC == 4) {
932          data[(i + j * curImg->s()) * nbC + 3] = c[3] * 255;
933        }
934      }
935    }
936    mmImg->setImage(curImg->s(), curImg->t(), 1, internalFormat, pixelFormat, type, data, osg::Image::USE_NEW_DELETE, 1);
937    osgDB::writeImageFile(*(mmImg.get()), nameOutput);
938
939  } else {
940    // no conversion needed, input and output have the same format, but path to image has changed
941    osgDB::writeImageFile(*(tex->getImage()), nameOutput);
942  }
943
944}
945
946/////////////////////////////////////////////////////////////////////////
947//
948// writeCoordIndex
949//
950/////////////////////////////////////////////////////////////////////////
951template<typename T> void ToVRML::writeCoordIndex(GLenum mode, T* indices, unsigned int number, std::vector<int>& primitiveSetFaces, int& primitiveFaces) {
952
953  int currentFaces = 0;
954  if (mode == osg::PrimitiveSet::TRIANGLES) {
955    //std::cout << "TRIANGLES" << std::endl;
956    for (unsigned int j = 0; j < number; j += 3) {
957      _fout << indent() << indices[j] << "," << indices[j + 1] << "," << indices[j + 2] << ",-1,\n";
958      currentFaces++;
959    }
960    primitiveSetFaces.push_back(currentFaces);
961    primitiveFaces += currentFaces;
962
963  } else if (mode == osg::PrimitiveSet::TRIANGLE_FAN) {
964    //std::cout << "TRIANGLE FAN" << std::endl;
965    int firstPoint = indices[0];
966    int secondPoint = indices[1];
967    for (unsigned int j = 2; j < number; j++) {
968      _fout << indent() << firstPoint << "," << secondPoint << "," << indices[j] << ",-1,\n";
969      secondPoint = indices[j];
970      currentFaces++;
971    }
972    primitiveSetFaces.push_back(currentFaces);
973    primitiveFaces += currentFaces;
974
975  } else if (mode == osg::PrimitiveSet::TRIANGLE_STRIP) {
976    //std::cout << "TRIANGLE STRIP" << std::endl;
977    int firstPoint = indices[0];
978    int secondPoint = indices[1];
979    bool changeSecond = false;
980    for (unsigned int j = 2; j < number; j++) {
981      _fout << indent() << firstPoint << "," << secondPoint << "," << indices[j] << ",-1,\n";
982      if (!changeSecond) {
983        firstPoint = indices[j];
984        changeSecond = true;
985      } else {
986        secondPoint = indices[j];
987        changeSecond = false;
988      }
989      currentFaces++;
990    }
991    primitiveSetFaces.push_back(currentFaces);
992    primitiveFaces += currentFaces;
993
994  } else if (mode == osg::PrimitiveSet::QUADS) {
995    //std::cout << "QUADS" << std::endl;
996    for (unsigned int j = 0; j < number; j += 4) {
997      _fout << indent() << indices[j] << "," << indices[j + 1] << "," << indices[j + 2] << "," << indices[j + 3] << ",-1,\n";
998      currentFaces++;
999    }
1000    primitiveSetFaces.push_back(currentFaces);
1001    primitiveFaces += currentFaces;
1002
1003  } else if (mode == osg::PrimitiveSet::QUAD_STRIP) {
1004    //std::cout << "QUADS STRIP" << std::endl;
1005    int firstPoint = indices[0];
1006    int secondPoint = indices[1];
1007    for (unsigned int j = 2; j < number; j += 2) {
1008      _fout << indent() << firstPoint << "," << secondPoint << "," << indices[j + 1] << " " << indices[j] << ",-1,\n";
1009      firstPoint = indices[j];
1010      secondPoint = indices[j + 1];
1011      currentFaces++;
1012    }
1013    primitiveSetFaces.push_back(currentFaces);
1014    primitiveFaces += currentFaces;
1015
1016  } else if (mode == osg::PrimitiveSet::POLYGON) {
1017    //std::cout << "POLYGON" << std::endl;
1018    _fout << indent();
1019    for (unsigned int j = 0; j < number; j++) {
1020      _fout << indices[j] << ",";
1021    }
1022    currentFaces++;
1023    _fout << "-1,\n";
1024    primitiveSetFaces.push_back(currentFaces);
1025    primitiveFaces += currentFaces;
1026
1027  } else {
1028    osg::notify(osg::ALWAYS) << "Unknown Primitive Set Type : " << mode << std::endl;
1029  }
1030
1031}
1032
1033/////////////////////////////////////////////////////////////////////////
1034//
1035// writeCoord
1036//
1037/////////////////////////////////////////////////////////////////////////
1038void ToVRML::writeCoord(osg::Vec3Array* array) {
1039
1040  if (array == NULL) {
1041    std::cerr << "Vec3Array is NULL" << std::endl;
1042    return;
1043  }
1044  osg::ref_ptr < osg::Vec3Array > vArray = array;
1045
1046  _fout << indentM() << "coord Coordinate {\n";
1047  _fout << indentM() << "point [\n";
1048  indentM();
1049  osg::Vec3 xyz;
1050  for (unsigned int j = 0; j < vArray->size(); j++) {
1051    xyz = (*vArray)[j];
1052    _fout << indent() << xyz[0] << " " << xyz[1] << " " << xyz[2] << ",\n";
1053  }
1054  _fout << indentL() << "]\n";
1055  _fout << indentL() << "}\n";
1056  indentL();
1057}
1058
1059/////////////////////////////////////////////////////////////////////////
1060//
1061// writeTexCoord
1062//
1063/////////////////////////////////////////////////////////////////////////
1064void ToVRML::writeTexCoord(osg::Vec2Array* array, osg::Vec3Array* array2) {
1065
1066  osg::ref_ptr < osg::StateSet > ss = getCurrentStateSet();
1067  osg::Texture2D* tex = (osg::Texture2D*) (ss->getTextureAttribute(_txtUnit, osg::StateAttribute::TEXTURE));
1068  if (tex == NULL) {
1069    return;
1070  }
1071
1072  osg::ref_ptr < osg::TexGen > texGen = dynamic_cast<osg::TexGen*> (ss->getTextureAttribute(_txtUnit, osg::StateAttribute::TEXGEN));
1073  osg::ref_ptr < osg::TexEnv > texEnv = dynamic_cast<osg::TexEnv*> (ss->getTextureAttribute(_txtUnit, osg::StateAttribute::TEXENV));
1074
1075  osg::Texture::WrapMode wrap_s = tex->getWrap(osg::Texture::WRAP_S);//osg::Texture::REPEAT;
1076  osg::Texture::WrapMode wrap_t = tex->getWrap(osg::Texture::WRAP_T);//osg::Texture::REPEAT;
1077
1078  if (array != NULL) {
1079    writeUVArray(array, wrap_s, wrap_t);
1080
1081  } else if (texGen.valid()) {
1082    //std::cout << "TEXGEN" << std::endl;
1083    osg::ref_ptr < osg::Vec2Array > uvArray = buildUVArray(texGen.get(), array2);
1084    if (uvArray.valid()) {
1085      writeUVArray(uvArray.get(), wrap_s, wrap_t);
1086    }
1087
1088  } else if (texEnv.valid()) {
1089    //std::cout << "TEXENV" << std::endl;
1090    osg::ref_ptr < osg::Vec2Array > uvArray = buildUVArray(texEnv.get(), array2);
1091    if (uvArray.valid()) {
1092      writeUVArray(uvArray.get(), wrap_s, wrap_t);
1093    }
1094  }
1095}
1096
1097/////////////////////////////////////////////////////////////////////////
1098//
1099// writeNormal
1100//
1101/////////////////////////////////////////////////////////////////////////
1102void ToVRML::writeNormal(osg::Geometry* geom, std::vector<int>& primitiveSetFaces, int nbFaces) {
1103
1104  osg::ref_ptr < osg::Vec3Array > nArray = (osg::Vec3Array*) (geom->getNormalArray());
1105  if (!nArray.valid()) {
1106    return;
1107  }
1108
1109  if (geom->getNormalBinding() == osg::Geometry::BIND_PER_VERTEX || geom->getNormalBinding() == osg::Geometry::BIND_OVERALL) {
1110    _fout << indentM() << "normalPerVertex TRUE \n";
1111  } else {
1112    _fout << indentM() << "normalPerVertex FALSE \n";
1113  }
1114
1115  _fout << indent() << "normal Normal {\n";
1116  _fout << indentM() << "vector [\n";
1117  indentM();
1118  osg::Vec3 n;
1119
1120  if (geom->getNormalBinding() == osg::Geometry::BIND_PER_VERTEX) {
1121    for (unsigned int j = 0; j < (*nArray).size(); j++) {
1122      n = (*nArray)[j];
1123      _fout << indent() << n[0] << " " << n[1] << " " << n[2] << ",\n";
1124    }
1125
1126  } else if (geom->getNormalBinding() == osg::Geometry::BIND_OVERALL) {
1127    n = (*nArray)[0];
1128    int size = ((osg::Vec3Array*) (geom->getVertexArray()))->size();
1129    for (int j = 0; j < size; j++) {
1130      _fout << indent() << n[0] << " " << n[1] << " " << n[2] << ",\n";
1131    }
1132
1133  } else if (geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE_SET) {
1134    for (unsigned int j = 0; j < (*nArray).size(); j++) {
1135      n = (*nArray)[j];
1136      for (int k = 0; k < primitiveSetFaces[j]; k++) {
1137        _fout << indent() << n[0] << " " << n[1] << " " << n[2] << ",\n";
1138      }
1139    }
1140  }
1141
1142  _fout << indentL() << "]\n";
1143  _fout << indentL() << "}\n";
1144  indentL();
1145}
1146
1147/////////////////////////////////////////////////////////////////////////
1148//
1149// writeUVArray
1150//
1151/////////////////////////////////////////////////////////////////////////
1152void ToVRML::writeUVArray(osg::Vec2Array* uvArray, osg::Texture::WrapMode wrap_s, osg::Texture::WrapMode wrap_t) {
1153
1154  _fout << indentM() << "texCoord TextureCoordinate {\n";
1155  _fout << indentM() << "point [\n";
1156  indentM();
1157  osg::Vec2 uv;
1158
1159  for (unsigned int j = 0; j < (*uvArray).size(); j++) {
1160    uv = (*uvArray)[j];
1161    if (wrap_s != osg::Texture::REPEAT) {
1162      // clamp to 0-1
1163      if (uv[0] < 0) {
1164        uv[0] = 0;
1165      } else if (uv[0] > 1) {
1166        uv[0] = 1;
1167      }
1168    }
1169    if (wrap_t != osg::Texture::REPEAT) {
1170      // clamp to 0-1
1171      if (uv[1] < 0) {
1172        uv[1] = 0;
1173      } else if (uv[1] > 1) {
1174        uv[1] = 1;
1175      }
1176    }
1177    _fout << indent() << uv[0] << " " << uv[1] << ",\n";
1178  }
1179  _fout << indentL() << "]\n";
1180  _fout << indentL() << "}\n";
1181  indentL();
1182}
1183
1184/////////////////////////////////////////////////////////////////////////
1185//
1186// buildUVArray
1187//
1188/////////////////////////////////////////////////////////////////////////
1189osg::Vec2Array* ToVRML::buildUVArray(osg::TexGen* tGen, osg::Vec3Array* array) {
1190  osg::ref_ptr < osg::TexGen > texGen = tGen;
1191  osg::ref_ptr < osg::Vec3Array > vArray = array;
1192  osg::Vec2Array* uvRet = NULL;
1193
1194  osg::TexGen::Mode mode = texGen->getMode();
1195  if (mode == osg::TexGen::OBJECT_LINEAR) {
1196    //std::cout << "I know" << std::endl;
1197
1198    uvRet = new osg::Vec2Array();
1199    osg::Plane planS = texGen->getPlane(osg::TexGen::S);//, osg::Vec4(1 / rangeS, 0, 0, -(adfGeoTransform[0] / rangeS)));
1200    osg::Plane planT = texGen->getPlane(osg::TexGen::T);//, osg::Vec4(0, 1 / rangeT, 0, -(adfGeoTransform[3] + sy * adfGeoTransform[5]) / rangeT));
1201    osg::Vec4 pS = planS.asVec4();
1202    osg::Vec4 pT = planT.asVec4();
1203    double width, height, xmin, ymin;
1204    width = 1.0 / pS[0];
1205    height = 1.0 / pT[1];
1206    xmin = -width * pS[3];
1207    ymin = -height * pT[3];
1208
1209    for (unsigned int j = 0; j < vArray->size(); j++) {
1210      osg::Vec3d p = (*vArray)[j];
1211      double x, y;
1212      osg::Vec2 uv;
1213      x = p[0];
1214      y = p[1];
1215      uv[0] = (x - xmin) / width;
1216      uv[1] = (y - ymin) / height;
1217      (*uvRet).push_back(uv);
1218
1219    }
1220  } else {
1221    osg::notify(osg::ALWAYS) << "Unknown TexGen mode" << std::endl;
1222  }
1223
1224  return (uvRet);
1225}
1226
1227/////////////////////////////////////////////////////////////////////////
1228//
1229// buildUVArray
1230//
1231/////////////////////////////////////////////////////////////////////////
1232osg::Vec2Array* ToVRML::buildUVArray(osg::TexEnv* tEnv, osg::Vec3Array* array) {
1233  osg::ref_ptr < osg::TexEnv > texEnv = tEnv;
1234  osg::Vec2Array* uvRet = NULL;
1235
1236 // osg::TexEnv::Mode mode = texEnv->getMode();
1237  //if (mode == osg::TexEnv::MODULATE) {
1238  //  std::cout << "I know" << std::endl;
1239  //} else {
1240  osg::notify(osg::ALWAYS) << "Unknown TexEnv mode" << std::endl;
1241  //}
1242  return (uvRet);
1243}
1244
1245/////////////////////////////////////////////////////////////////////////
1246//
1247// writeColor
1248//
1249/////////////////////////////////////////////////////////////////////////
1250void ToVRML::writeColor(osg::Geometry* geom, std::vector<int>& primitiveSetFaces, int nbFaces) {
1251
1252  osg::ref_ptr < osg::Vec4Array > cArray = (osg::Vec4Array*) (geom->getColorArray());
1253  if (!cArray.valid()) {
1254    return;
1255  }
1256
1257  if (geom->getColorBinding() == osg::Geometry::BIND_PER_VERTEX || geom->getColorBinding() == osg::Geometry::BIND_OVERALL) {
1258    _fout << indentM() << "colorPerVertex TRUE \n";
1259  } else {
1260    _fout << indentM() << "colorPerVertex FALSE \n";
1261  }
1262
1263  _fout << indent() << "color Color {\n";
1264  _fout << indentM() << "color [\n";
1265  indentM();
1266  osg::Vec4 c;
1267
1268  if (geom->getColorBinding() == osg::Geometry::BIND_PER_VERTEX) {
1269    for (unsigned int j = 0; j < (*cArray).size(); j++) {
1270      c = (*cArray)[j];
1271      _fout << indent() << c[0] << " " << c[1] << " " << c[2] << ",\n";
1272    }
1273
1274  } else if (geom->getColorBinding() == osg::Geometry::BIND_OVERALL) {
1275    c = (*cArray)[0];
1276    int size = ((osg::Vec3Array*) (geom->getVertexArray()))->size();
1277    for (int j = 0; j < size; j++) {
1278      _fout << indent() << c[0] << " " << c[1] << " " << c[2] << ",\n";
1279    }
1280
1281  } else if (geom->getColorBinding() == osg::Geometry::BIND_PER_PRIMITIVE_SET) {
1282    for (unsigned int j = 0; j < (*cArray).size(); j++) {
1283      c = (*cArray)[j];
1284      for (int k = 0; k < primitiveSetFaces[j]; k++) {
1285        _fout << indent() << c[0] << " " << c[1] << " " << c[2] << ",\n";
1286      }
1287    }
1288  }
1289
1290  _fout << indentL() << "]\n";
1291  _fout << indentL() << "}\n";
1292  indentL();
1293}
Note: See TracBrowser for help on using the browser.