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

Revision 13041, 42.6 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • 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  // are all primitives faces or line ?
272  GLenum mode;
273  osg::PrimitiveSet::Type type;
274
275  _fout << indent() << "Shape {\n";
276  indentM();
277  writeAppearance( getCurrentStateSet());
278  indentL();
279
280  int modePoints = 0;
281  int modeLines = 0;
282  int modeFaces = 0;
283
284  for (unsigned int p = 0; p < geom->getNumPrimitiveSets(); p++) {
285    mode = geom->getPrimitiveSet(p)->getMode();
286    if (mode == osg::PrimitiveSet::POINTS) {
287      modePoints++;
288
289    } else if ((mode == osg::PrimitiveSet::LINES) || (mode == osg::PrimitiveSet::LINE_STRIP) || (mode == osg::PrimitiveSet::LINE_LOOP)) {
290      modeLines++;
291
292    } else if ((mode == osg::PrimitiveSet::TRIANGLES) || (mode == osg::PrimitiveSet::TRIANGLE_STRIP) || (mode == osg::PrimitiveSet::TRIANGLE_FAN) || (mode
293    == osg::PrimitiveSet::QUADS) || (mode == osg::PrimitiveSet::QUAD_STRIP) || (mode == osg::PrimitiveSet::POLYGON)) {
294      modeFaces++;
295    }
296  }
297
298  //std::cout << "primitives type : Points " << modePoints << " Line " << modeLines << " Face " << modeFaces << std::endl;
299
300  if (modePoints > 0) {
301    _fout << indentM() << "geometry PointSet {\n";
302    for (unsigned int p = 0; p < geom->getNumPrimitiveSets(); p++) {
303      mode = geom->getPrimitiveSet(p)->getMode();
304      type = geom->getPrimitiveSet(p)->getType();
305      if (mode == osg::PrimitiveSet::POINTS) {
306        osg::notify(osg::WARN) << " osg::PrimitiveSetMode = POINTS not supported by VRML Writer" << std::endl;
307      }
308    }
309  }
310
311  if (modeLines > 0) {
312    _fout << indentM() << "geometry IndexedLineSet {\n";
313    for (unsigned int p = 0; p < geom->getNumPrimitiveSets(); p++) {
314      mode = geom->getPrimitiveSet(p)->getMode();
315      type = geom->getPrimitiveSet(p)->getType();
316      if ((mode == osg::PrimitiveSet::LINES) || (mode == osg::PrimitiveSet::LINE_STRIP) || (mode == osg::PrimitiveSet::LINE_LOOP)) {
317        osg::notify(osg::WARN) << " osg::PrimitiveSetMode = LINES, LINE_STRIP or LINE_LOOP not supported by VRML Writer" << std::endl;
318      }
319    }
320  }
321
322  if (modeFaces > 0) {
323    _fout << indentM() << "geometry IndexedFaceSet {\n";
324    _fout << indentM() << "solid FALSE\n";
325    indentL();
326    _fout << indentM() << "coordIndex [\n";
327    indentM();
328
329    std::vector<int> primitiveSetFaces;
330    int primitiveFaces = 0;
331
332    for (unsigned int p = 0; p < geom->getNumPrimitiveSets(); p++) {
333      mode = geom->getPrimitiveSet(p)->getMode();
334      type = geom->getPrimitiveSet(p)->getType();
335      if ((mode == osg::PrimitiveSet::TRIANGLES) || (mode == osg::PrimitiveSet::TRIANGLE_STRIP) || (mode == osg::PrimitiveSet::TRIANGLE_FAN) || (mode == osg::PrimitiveSet::QUADS)
336      || (mode == osg::PrimitiveSet::QUAD_STRIP) || (mode == osg::PrimitiveSet::POLYGON)) {
337        if (type == osg::PrimitiveSet::PrimitiveType) {
338          osg::notify(osg::WARN) << "osg::PrimitiveSet::PrimitiveType not supported by VRML Writer" << std::endl;
339
340        } else if (type == osg::PrimitiveSet::DrawArraysPrimitiveType) {
341          //std::cout << "osg::PrimitiveSet::DrawArraysPrimitiveType" << std::endl;
342          osg::ref_ptr < osg::DrawArrays > dra = dynamic_cast<osg::DrawArrays*> (geom->getPrimitiveSet(p));
343
344          unsigned int* indices = new unsigned int[dra->getCount()];
345          for (int j = 0; j < dra->getCount(); j++) {
346            indices[j] = dra->getFirst() + j;
347          }
348          writeCoordIndex(mode, indices, dra->getCount(), primitiveSetFaces, primitiveFaces);
349          delete[] indices;
350
351        } else if (type == osg::PrimitiveSet::DrawArrayLengthsPrimitiveType) {
352          //osg::notify(osg::WARN) << " osg::PrimitiveSet::DrawArrayLengthsPrimitiveType not supported by VRML Writer" << std::endl;
353          osg::ref_ptr < osg::DrawArrayLengths > dal = dynamic_cast<osg::DrawArrayLengths*> (geom->getPrimitiveSet(p));
354
355          //std::cout<<dal->getFirst()<<" "<<dal->getNumPrimitives()<<" "<<   dal->getNumIndices ()<<" "<< dal->getNumInstances()<<std::endl;
356          int first = 0;
357          for (unsigned int prim = dal->getFirst(); prim < dal->getNumPrimitives(); prim++) {
358            //std::cout<<(*dal)[prim]<<std::endl;
359            unsigned int numIndices = (*dal)[prim];
360            unsigned int * indices = new unsigned int[numIndices];
361            for (unsigned int i = 0; i < numIndices; i++) {
362              indices[i] = first + i;
363            }
364
365            first += (*dal)[prim];
366            // write coorIndex as if wa have an indexed geometry
367            writeCoordIndex(mode, indices, numIndices, primitiveSetFaces, primitiveFaces);
368            delete[] indices;
369          }
370
371        } else if (type == osg::PrimitiveSet::DrawElementsUBytePrimitiveType) {
372          //std::cout << "osg::PrimitiveSet::DrawElementsUBytePrimitiveType" << std::endl;
373
374          osg::ref_ptr < osg::DrawElementsUByte > drui = dynamic_cast<osg::DrawElementsUByte*> (geom->getPrimitiveSet(p));
375          const unsigned char * indices = (const unsigned char*) (drui->getDataPointer());
376          writeCoordIndex(mode, indices, drui->getNumIndices(), primitiveSetFaces, primitiveFaces);
377
378        } else if (type == osg::PrimitiveSet::DrawElementsUShortPrimitiveType) {
379          //std::cout << "osg::PrimitiveSet::DrawElementsUShortPrimitiveType" << std::endl;
380
381          osg::ref_ptr < osg::DrawElementsUShort > drui = dynamic_cast<osg::DrawElementsUShort*> (geom->getPrimitiveSet(p));
382          const unsigned short * indices = (const unsigned short*) (drui->getDataPointer());
383          writeCoordIndex(mode, indices, drui->getNumIndices(), primitiveSetFaces, primitiveFaces);
384
385        } else if (type == osg::PrimitiveSet::DrawElementsUIntPrimitiveType) {
386          //std::cout << "osg::PrimitiveSet::DrawElementsUIntPrimitiveType" << std::endl;
387
388          osg::ref_ptr < osg::DrawElementsUInt > drui = dynamic_cast<osg::DrawElementsUInt*> (geom->getPrimitiveSet(p));
389          const unsigned int * indices = (const unsigned int*) (drui->getDataPointer());
390          writeCoordIndex(mode, indices, drui->getNumIndices(), primitiveSetFaces, primitiveFaces);
391        }
392
393      }
394
395    }
396    _fout << indentL() << "]\n";
397    indentL();
398
399    //write vertex
400    writeCoord((osg::Vec3Array*) (geom->getVertexArray()));
401    //write texture coordinate
402    if (_textureMode != NO_TEXTURE) {
403      writeTexCoord((osg::Vec2Array*) (geom->getTexCoordArray(_txtUnit)), (osg::Vec3Array*) (geom->getVertexArray()));
404    }
405    //write normals
406    writeNormal(geom, primitiveSetFaces, primitiveFaces);
407    //write colors
408    writeColor(geom, primitiveSetFaces, primitiveFaces);
409  }
410
411  _fout << indent() << "}\n";
412  _fout << indentL() << "}\n";
413
414}
415
416/////////////////////////////////////////////////////////////////////////
417//
418// writeAppearance
419//
420/////////////////////////////////////////////////////////////////////////
421void ToVRML::writeAppearance(osg::StateSet* stateset) {
422
423  if (stateset == NULL) {
424    return;
425  }
426
427  osg::ref_ptr < osg::StateSet > ss = stateset;
428
429  _fout << indent() << "appearance Appearance {\n";
430  osg::Material* mat = (osg::Material*) (ss->getAttribute(osg::StateAttribute::MATERIAL));
431  osg::Texture2D* tex;
432  if (_textureMode == NO_TEXTURE) {
433    tex = NULL;
434  } else {
435    tex = (osg::Texture2D*) (ss->getTextureAttribute(_txtUnit, osg::StateAttribute::TEXTURE));
436  }
437
438  if (mat) {
439
440    bool alreadyLoaded;
441    std::string name;
442    osg::Vec4 ambient, diffuse, specular, emission;
443    float shininess;
444
445    ambient = mat->getAmbient(osg::Material::FRONT);
446    diffuse = mat->getDiffuse(osg::Material::FRONT);
447    specular = mat->getSpecular(osg::Material::FRONT);
448    shininess = mat->getShininess(osg::Material::FRONT);
449    emission = mat->getEmission(osg::Material::FRONT);
450
451    float transp = 1 - (ambient[3] + diffuse[3] + specular[3] + emission[3]) / 4.0;
452    if (transp < 0)
453      transp = 0;
454
455    //if (transp == 0 && tex) {
456    //  if (tex->getImage()->isImageTranslucent()) {
457    //    transp = 0.01;
458    //    mat->setTransparency(osg::Material::FRONT,transp);
459    //  }
460    //}
461
462    findMaterialName(mat, name, alreadyLoaded);
463    if (alreadyLoaded) {
464      _fout << indentM() << "material USE " << name << "\n";
465      indentL();
466    } else {
467
468      _fout << indentM() << "material DEF " << name << " Material {\n";
469      //_fout << indentM() << "material Material {\n";
470      _fout << indentM() << "diffuseColor " << diffuse[0] << " " << diffuse[1] << " " << diffuse[2] << "\n";
471      _fout << indent() << "emissiveColor " << emission[0] << " " << emission[1] << " " << emission[2] << "\n";
472
473      _fout << indent() << "specularColor " << specular[0] << " " << specular[1] << " " << specular[2] << "\n";
474      _fout << indent() << "shininess " << shininess << "\n";
475      float ambientI = (ambient[0] + ambient[1] + ambient[2]) / 3.0;
476      if (ambientI > 1)
477        ambientI = 1;
478      _fout << indent() << "ambientIntensity " << ambientI << "\n";
479
480      _fout << indent() << "transparency " << transp << "\n";
481      _fout << indentL() << "}\n";
482      indentL();
483    }
484  }
485
486  if (tex) {
487    bool alreadyLoaded;
488    std::string name;
489    findTextureName(tex, name, alreadyLoaded);
490    if (alreadyLoaded) {
491      _fout << indentM() << "texture USE " << name << "\n";
492      indentL();
493    } else {
494      _fout << indentM() << "texture DEF " << name << " ImageTexture {\n";
495      std::string texName = tex->getImage()->getFileName();
496      if (_textureMode == COPY_TEXTURE || _textureMode == CONVERT_TEXTURE) {
497        texName = _pathRelativeToOutput + "/" + osgDB::getSimpleFileName(texName);
498
499      } else if (_textureMode == KEEP_ORIGINAL_TEXTURE) {
500        texName = _pathRelativeToOutput + "/" + texName;
501      }
502      _fout << indentM() << "url [ \"" << texName << "\" ]\n";
503      //std::cout<<"WRAP "<<tex->getWrap(osg::Texture::WRAP_S)<<std::endl;
504      if (tex->getWrap(osg::Texture::WRAP_S) == osg::Texture::REPEAT) {
505        _fout << indent() << "repeatS TRUE\n";
506      } else {
507        _fout << indent() << "repeatS FALSE\n";
508      }
509      if (tex->getWrap(osg::Texture::WRAP_T) == osg::Texture::REPEAT) {
510        _fout << indent() << "repeatT TRUE\n";
511      } else {
512        _fout << indent() << "repeatT FALSE\n";
513      }
514      _fout << indentL() << "}\n";
515      indentL();
516    }
517  }
518
519  _fout << indent() << "}\n";
520
521}
522
523/////////////////////////////////////////////////////////////////////////
524//
525// apply(osg::Group)
526//
527/////////////////////////////////////////////////////////////////////////
528void ToVRML::apply(osg::Group& node) {
529  //cout << "Group" << endl;
530  _fout << indent() << "Group {\n";
531  _fout << indentM() << "children [\n";
532
533  pushStateSetStack(node.getStateSet());
534
535  indentM();
536  traverse(node);
537  indentL();
538
539  popStateSetStack();
540
541  _fout << indent() << "]\n";
542  _fout << indentL() << "}\n";
543}
544
545/////////////////////////////////////////////////////////////////////////
546//
547// apply(osg::MatrixTransform)
548//
549/////////////////////////////////////////////////////////////////////////
550void ToVRML::apply(osg::MatrixTransform& node) {
551  //cout << "MatrixTransform" << endl;
552  osg::Matrixf mat = node.getMatrix();
553  //   for(int i=0;i<16;i++){
554  //     cout <<mat.ptr()[i]<<" ";
555  //   }
556  //   cout<<endl;
557
558
559  osg::Vec3 trans = mat.getTrans();
560  osg::Vec3 scale = mat.getScale();
561  osg::Quat quat;
562  mat.get(quat);
563  double angle;
564  osg::Vec3 axe;
565  quat.getRotate(angle, axe);
566
567  _fout << indent() << "Transform {\n";
568  _fout << indentM() << "scale " << scale[0] << " " << scale[1] << " " << scale[2] << "\n";
569  //_fout << indentM() << "scale 1 1 1\n";
570  _fout << indent() << "translation " << trans[0] << " " << trans[1] << " " << trans[2] << "\n";
571  _fout << indent() << "rotation " << axe[0] << " " << axe[1] << " " << axe[2] << " " << angle << "\n";
572  _fout << indent() << "children [\n";
573
574  pushStateSetStack(node.getStateSet());
575
576  indentM();
577  traverse(node);
578  indentL();
579
580  popStateSetStack();
581
582  _fout << indent() << "]\n";
583
584  _fout << indentL() << "}\n";
585
586}
587
588/////////////////////////////////////////////////////////////////////////
589//
590// apply(osg::PositionAttitudeTransform)
591//
592/////////////////////////////////////////////////////////////////////////
593void ToVRML::apply(osg::PositionAttitudeTransform& node) {
594
595  osg::Vec3 trans = node.getPosition();
596  osg::Vec3 scale = node.getScale();
597  osg::Quat quat = node.getAttitude();
598  double angle;
599  osg::Vec3 axe;
600  quat.getRotate(angle, axe);
601
602  _fout << indent() << "Transform {\n";
603  _fout << indentM() << "scale " << scale[0] << " " << scale[1] << " " << scale[2] << "\n";
604  //_fout << indentM() << "scale 1 1 1\n";
605  _fout << indent() << "translation " << trans[0] << " " << trans[1] << " " << trans[2] << "\n";
606  _fout << indent() << "rotation " << axe[0] << " " << axe[1] << " " << axe[2] << " " << angle << "\n";
607  _fout << indent() << "children [\n";
608
609  pushStateSetStack(node.getStateSet());
610
611  indentM();
612  traverse(node);
613  indentL();
614
615  popStateSetStack();
616
617  _fout << indent() << "]\n";
618
619  _fout << indentL() << "}\n";
620
621}
622
623////////////////////////////////////////////////////////////////////////
624//
625// apply(osg::Billboard)
626//
627/////////////////////////////////////////////////////////////////////////
628void ToVRML::apply(osg::Billboard& node) {
629  osg::notify(osg::ALWAYS) << "WARNING : Billboard is changed to Group" << endl;
630  _fout << indent() << "Group {\n";
631  indentM();
632
633  //osg::Billboard::Mode mode = node.getMode();
634  //const osg::Vec3 axe = node.getAxis();
635  //const osg::Vec3 normal = node.getNormal();
636
637  //if (mode == osg::Billboard::AXIAL_ROT) {
638  //  _fout << indent() << "axisOfRotation " << axe[0] << " " << axe[1] << " " << axe[2] << "\n";
639  //}
640  //osg::BoundingSphere sph=node.getBound();
641  //_fout << indent() << "bboxCenter "<<sph.center()[0]<<" "<<sph.center()[1]<<" "<<sph.center()[2]<<"\n";
642  //_fout << indent() << "bboxSize "<<sph.radius()<<" "<<sph.radius()<<" "<<sph.radius()<<"\n";
643
644  _fout << indent() << "children [\n";
645
646  pushStateSetStack(node.getStateSet());
647
648  indentM();
649  for (unsigned int i = 0; i < node.getNumDrawables(); i++) {
650    osg::Vec3 trans = node.getPosition(i);
651    _fout << indent() << "Transform {\n";
652    _fout << indentM() << "translation " << trans[0] << " " << trans[1] << " " << trans[2] << "\n";
653    _fout << indent() << "children [\n";
654    indentM();
655    apply(node.getDrawable(i));
656    _fout << indentL() << "]\n";
657    _fout << indentL() << "}\n";
658  }
659
660  popStateSetStack();
661
662  _fout << indentL() << "]\n";
663  _fout << indentL() << "}\n";
664}
665
666////////////////////////////////////////////////////////////////////////
667//
668// apply(osg::LOD)
669//
670/////////////////////////////////////////////////////////////////////////
671void ToVRML::apply(osg::LOD& node) {
672  //std::cout << "LOD" << endl;
673  _fout << indent() << "LOD {\n";
674
675  bool fakeFirst = false;
676  bool fakeLast = false;
677  if (node.getMinRange(0) > 0) {
678    fakeFirst = true;
679  }
680  if (node.getMaxRange(node.getNumRanges() - 1) < std::numeric_limits<float>::max()) {
681    fakeLast = true;
682  }
683
684  _fout << indentM() << "level [\n";
685  if (fakeFirst) {
686    _fout << indentM() << "Shape {\n";
687    _fout << indent() << "}\n";
688    indentL();
689  }
690  pushStateSetStack(node.getStateSet());
691  indentM();
692  traverse(node);
693  indentL();
694  popStateSetStack();
695
696  if (fakeLast) {
697    _fout << indentM() << "Shape {\n";
698    _fout << indent() << "}\n";
699    indentL();
700  }
701
702  _fout << indent() << "]\n";
703
704  osg::Vec3 center;
705  if (node.getCenterMode() == osg::LOD::USER_DEFINED_CENTER) {
706    center = node.getCenter();
707  } else {
708    center = node.getBound().center();
709  }
710  _fout << indent() << "center " << center[0] << " " << center[1] << " " << center[2] << "\n";
711
712  _fout << indentM() << "range [";
713  if (fakeFirst) {
714    _fout << indentM() << node.getMinRange(0) << ",";
715  }
716  for (unsigned int i = 0; i < node.getNumRanges(); i++) {
717
718    _fout << indentM() << node.getMaxRange(i);
719    if (i < node.getNumRanges() - 1) {
720      _fout << ",";
721    }
722  }
723  _fout << "]\n";
724
725  _fout << indentL() << "}\n";
726}
727
728/////////////////////////////////////////////////////////////////////////
729//
730// apply(osg::Node)
731//
732/////////////////////////////////////////////////////////////////////////
733void ToVRML::apply(osg::Node& node) {
734  osg::notify(osg::ALWAYS) << node.className() << " not supported" << endl;
735  pushStateSetStack(node.getStateSet());
736  traverse(node);
737  popStateSetStack();
738}
739
740/////////////////////////////////////////////////////////////////////////
741//
742// pushStateSetStack
743//
744/////////////////////////////////////////////////////////////////////////
745void ToVRML::pushStateSetStack(osg::StateSet* ss) {
746  _stack.push_back(osg::ref_ptr<osg::StateSet>(ss));
747}
748
749/////////////////////////////////////////////////////////////////////////
750//
751// popStateSetStack
752//
753/////////////////////////////////////////////////////////////////////////
754void ToVRML::popStateSetStack() {
755  if (!_stack.empty()) {
756    _stack.pop_back();
757  }
758}
759
760/////////////////////////////////////////////////////////////////////////
761//
762// getCurrentStateSet
763//
764/////////////////////////////////////////////////////////////////////////
765osg::StateSet* ToVRML::getCurrentStateSet() {
766  // return current StateSet by flatten StateSet stack.
767  // until flatten is done, just return top StateSet
768  if (!_stack.empty()) {
769    osg::StateSet* ssFinal = new osg::StateSet();
770    ssFinal->setGlobalDefaults();
771    //std::cout << "StateSet Stack Size " << _stack.size() << std::endl;
772    for (unsigned int i = 0; i < _stack.size(); i++) {
773      osg::StateSet* ssCur = _stack[i].get();
774      if (ssCur != NULL) {
775        ssFinal->merge(*ssCur);
776      }
777    }
778    return (ssFinal);
779  } else
780    return (NULL);
781}
782
783/////////////////////////////////////////////////////////////////////////
784//
785// findMaterialName
786//
787/////////////////////////////////////////////////////////////////////////
788void ToVRML::findMaterialName(osg::Material* mat, std::string& name, bool& alreadyLoaded) {
789
790  osg::Vec4 ambient, diffuse, specular, emission;
791  //float shininess;
792  std::map<osg::ref_ptr<osg::Material>, std::string>::iterator it;// = _matMap.find(obj);
793
794  for (it = _matMap.begin(); it != _matMap.end(); it++) {
795    osg::ref_ptr < osg::Material > matLoaded = it->first;
796    ambient = mat->getAmbient(osg::Material::FRONT);
797    //diffuse = mat->getDiffuse(osg::Material::FRONT);
798    //specular = mat->getSpecular(osg::Material::FRONT);
799    //shininess = mat->getShininess(osg::Material::FRONT);
800    //emission = mat->getEmission(osg::Material::FRONT);
801    //std::cout << "MATERIAL " << ambient[3] << " " << matLoaded->getAmbient(osg::Material::FRONT)[3] << std::endl;
802
803    if ((matLoaded->getAmbient(osg::Material::FRONT) == mat->getAmbient(osg::Material::FRONT)) && (matLoaded->getDiffuse(osg::Material::FRONT)
804    == mat->getDiffuse(osg::Material::FRONT)) && (matLoaded->getSpecular(osg::Material::FRONT) == mat->getSpecular(osg::Material::FRONT))
805    && (matLoaded->getShininess(osg::Material::FRONT) == mat->getShininess(osg::Material::FRONT)) && (matLoaded->getEmission(osg::Material::FRONT)
806    == mat->getEmission(osg::Material::FRONT))) {
807
808      name = it->second;
809      alreadyLoaded = true;
810      return;
811    }
812  }
813  std::stringstream ss;
814  ss << "material_" << _matMap.size();
815  name = ss.str();
816  _matMap[mat] = name;
817  alreadyLoaded = false;
818
819}
820
821/////////////////////////////////////////////////////////////////////////
822//
823// findTextureName
824//
825/////////////////////////////////////////////////////////////////////////
826void ToVRML::findTextureName(osg::Texture2D* tex, std::string& name, bool& alreadyLoaded) {
827
828  //std::cout << "ORI -" << tex->getImage() << "- " << std::endl;
829  if (tex->getImage() == NULL) {
830    tex->setImage(_defaultImage.get());
831  }
832
833  std::string nameOri = osgDB::convertFileNameToNativeStyle(tex->getImage()->getFileName());
834  std::string nameInput = osgDB::findDataFile(nameOri, NULL);
835  if (nameInput == "") {
836    osg::notify(osg::ALWAYS) << "WARNING: couldn't find texture named: -" << nameOri << "- use default one instead -" << _defaultImage->getFileName() << "-" << std::endl;
837    tex->setImage(_defaultImage.get());
838    nameOri = osgDB::convertFileNameToNativeStyle(tex->getImage()->getFileName());
839    nameInput = osgDB::findDataFile(nameOri, NULL);
840  }
841
842  std::string nameOutput;
843  std::string::size_type pos = nameInput.find_last_of(".");
844  std::string ext = nameInput.substr(pos, nameInput.length() - pos);
845
846  osg::ref_ptr < osg::Image > imgIn = osgDB::readImageFile(nameInput);
847  if (!imgIn.valid()) {
848    osg::notify(osg::ALWAYS) << "WARNING: couldn't read texture named: -" << nameOri << "- use default one instead -" << _defaultImage->getFileName() << "-" << std::endl;
849    tex->setImage(_defaultImage.get());
850    nameOri = osgDB::convertFileNameToNativeStyle(tex->getImage()->getFileName());
851    nameInput = osgDB::findDataFile(nameOri, NULL);
852    pos = nameInput.find_last_of(".");
853    nameInput.substr(pos, nameInput.length() - pos);
854    imgIn = _defaultImage.get();
855  }
856
857  //int nbBand = poSrcDS->GetRasterCount();
858  if (_textureMode == KEEP_ORIGINAL_TEXTURE) {
859    nameOutput = nameInput;
860
861  } else if (_textureMode == COPY_TEXTURE) {
862    nameOutput = _pathToOutput + "/" + _pathRelativeToOutput + "/" + osgDB::getSimpleFileName(nameInput);
863
864  } else if (_textureMode == CONVERT_TEXTURE) {
865    nameOutput = _pathToOutput + "/" + _pathRelativeToOutput + "/" + osgDB::getSimpleFileName(nameInput);
866    if (ext != ".png" && ext != ".jpg") {
867      if (imgIn->isImageTranslucent()) {//(nbBand != 1 && nbBand != 3) {
868        nameOutput = _pathToOutput + "/" + _pathRelativeToOutput + "/" + osgDB::getSimpleFileName(nameInput.substr(0, pos) + ".png");
869      } else {
870        nameOutput = _pathToOutput + "/" + _pathRelativeToOutput + "/" + osgDB::getSimpleFileName(nameInput.substr(0, pos) + ".jpg");
871      }
872    }
873  }
874
875  std::map<osg::ref_ptr<osg::Texture2D>, std::string>::iterator it;
876  for (it = _texMap.begin(); it != _texMap.end(); it++) {
877    osg::ref_ptr < osg::Texture2D > texLoaded = it->first;
878
879    if ((nameOutput == texLoaded->getImage()->getFileName()) && (tex->getWrap(osg::Texture::WRAP_S) == texLoaded->getWrap(osg::Texture::WRAP_S))
880    && (tex->getWrap(osg::Texture::WRAP_T) == texLoaded->getWrap(osg::Texture::WRAP_T))) {
881      name = it->second;
882      alreadyLoaded = true;
883      return;
884    }
885  }
886
887  // first time we see these texture
888  // add it to textureMap
889  std::stringstream ss;
890  ss << "texture2D_" << _texMap.size();
891  name = ss.str();
892  _texMap[tex] = name;
893  alreadyLoaded = false;
894
895  tex->getImage()->setFileName(nameOutput);
896
897  if (nameInput == nameOutput) {
898    return;
899  }
900  // else write image file
901
902  if (_textureMode == CONVERT_TEXTURE) {
903    // convert format (from dds to rgb or rgba, or from rgba to rgb)
904    std::string newName;
905    GLenum type = GL_UNSIGNED_BYTE;
906    GLenum pixelFormat;
907    GLint internalFormat;
908    int nbC;
909    if (imgIn->isImageTranslucent()) {
910      // convert to png if transparency
911      pixelFormat = GL_RGBA;
912      internalFormat = GL_RGBA;
913      nbC = 4;
914    } else {
915      // convert to jpeg if no transparency
916      pixelFormat = GL_RGB;
917      internalFormat = GL_RGB;
918      nbC = 3;
919    }
920    osg::ref_ptr < osg::Image > curImg = tex->getImage();
921    osg::ref_ptr < osg::Image > mmImg = new osg::Image();
922    unsigned char* data = new unsigned char[curImg->s() * curImg->t() * nbC];
923    for (int j = 0; j < curImg->t(); j++) {
924      for (int i = 0; i < curImg->s(); i++) {
925        osg::Vec4 c = curImg->getColor(i, j);
926        data[(i + j * curImg->s()) * nbC] = c[0] * 255;
927        data[(i + j * curImg->s()) * nbC + 1] = c[1] * 255;
928        data[(i + j * curImg->s()) * nbC + 2] = c[2] * 255;
929        if (nbC == 4) {
930          data[(i + j * curImg->s()) * nbC + 3] = c[3] * 255;
931        }
932      }
933    }
934    mmImg->setImage(curImg->s(), curImg->t(), 1, internalFormat, pixelFormat, type, data, osg::Image::USE_NEW_DELETE, 1);
935    osgDB::writeImageFile(*(mmImg.get()), nameOutput);
936
937  } else {
938    // no conversion needed, input and output have the same format, but path to image has changed
939    osgDB::writeImageFile(*(tex->getImage()), nameOutput);
940  }
941
942}
943
944/////////////////////////////////////////////////////////////////////////
945//
946// writeCoordIndex
947//
948/////////////////////////////////////////////////////////////////////////
949template<typename T> void ToVRML::writeCoordIndex(GLenum mode, T* indices, unsigned int number, std::vector<int>& primitiveSetFaces, int& primitiveFaces) {
950
951  int currentFaces = 0;
952  if (mode == osg::PrimitiveSet::TRIANGLES) {
953    //std::cout << "TRIANGLES" << std::endl;
954    for (unsigned int j = 0; j < number; j += 3) {
955      _fout << indent() << indices[j] << "," << indices[j + 1] << "," << indices[j + 2] << ",-1,\n";
956      currentFaces++;
957    }
958    primitiveSetFaces.push_back(currentFaces);
959    primitiveFaces += currentFaces;
960
961  } else if (mode == osg::PrimitiveSet::TRIANGLE_FAN) {
962    //std::cout << "TRIANGLE FAN" << std::endl;
963    int firstPoint = indices[0];
964    int secondPoint = indices[1];
965    for (unsigned int j = 2; j < number; j++) {
966      _fout << indent() << firstPoint << "," << secondPoint << "," << indices[j] << ",-1,\n";
967      secondPoint = indices[j];
968      currentFaces++;
969    }
970    primitiveSetFaces.push_back(currentFaces);
971    primitiveFaces += currentFaces;
972
973  } else if (mode == osg::PrimitiveSet::TRIANGLE_STRIP) {
974    //std::cout << "TRIANGLE STRIP" << std::endl;
975    int firstPoint = indices[0];
976    int secondPoint = indices[1];
977    bool changeSecond = false;
978    for (unsigned int j = 2; j < number; j++) {
979      _fout << indent() << firstPoint << "," << secondPoint << "," << indices[j] << ",-1,\n";
980      if (!changeSecond) {
981        firstPoint = indices[j];
982        changeSecond = true;
983      } else {
984        secondPoint = indices[j];
985        changeSecond = false;
986      }
987      currentFaces++;
988    }
989    primitiveSetFaces.push_back(currentFaces);
990    primitiveFaces += currentFaces;
991
992  } else if (mode == osg::PrimitiveSet::QUADS) {
993    //std::cout << "QUADS" << std::endl;
994    for (unsigned int j = 0; j < number; j += 4) {
995      _fout << indent() << indices[j] << "," << indices[j + 1] << "," << indices[j + 2] << "," << indices[j + 3] << ",-1,\n";
996      currentFaces++;
997    }
998    primitiveSetFaces.push_back(currentFaces);
999    primitiveFaces += currentFaces;
1000
1001  } else if (mode == osg::PrimitiveSet::QUAD_STRIP) {
1002    //std::cout << "QUADS STRIP" << std::endl;
1003    int firstPoint = indices[0];
1004    int secondPoint = indices[1];
1005    for (unsigned int j = 2; j < number; j += 2) {
1006      _fout << indent() << firstPoint << "," << secondPoint << "," << indices[j + 1] << " " << indices[j] << ",-1,\n";
1007      firstPoint = indices[j];
1008      secondPoint = indices[j + 1];
1009      currentFaces++;
1010    }
1011    primitiveSetFaces.push_back(currentFaces);
1012    primitiveFaces += currentFaces;
1013
1014  } else if (mode == osg::PrimitiveSet::POLYGON) {
1015    //std::cout << "POLYGON" << std::endl;
1016    _fout << indent();
1017    for (unsigned int j = 0; j < number; j++) {
1018      _fout << indices[j] << ",";
1019    }
1020    currentFaces++;
1021    _fout << "-1,\n";
1022    primitiveSetFaces.push_back(currentFaces);
1023    primitiveFaces += currentFaces;
1024
1025  } else {
1026    osg::notify(osg::ALWAYS) << "Unknown Primitive Set Type : " << mode << std::endl;
1027  }
1028
1029}
1030
1031/////////////////////////////////////////////////////////////////////////
1032//
1033// writeCoord
1034//
1035/////////////////////////////////////////////////////////////////////////
1036void ToVRML::writeCoord(osg::Vec3Array* array) {
1037
1038  if (array == NULL) {
1039    std::cerr << "Vec3Array is NULL" << std::endl;
1040    return;
1041  }
1042  osg::ref_ptr < osg::Vec3Array > vArray = array;
1043
1044  _fout << indentM() << "coord Coordinate {\n";
1045  _fout << indentM() << "point [\n";
1046  indentM();
1047  osg::Vec3 xyz;
1048  for (unsigned int j = 0; j < vArray->size(); j++) {
1049    xyz = (*vArray)[j];
1050    _fout << indent() << xyz[0] << " " << xyz[1] << " " << xyz[2] << ",\n";
1051  }
1052  _fout << indentL() << "]\n";
1053  _fout << indentL() << "}\n";
1054  indentL();
1055}
1056
1057/////////////////////////////////////////////////////////////////////////
1058//
1059// writeTexCoord
1060//
1061/////////////////////////////////////////////////////////////////////////
1062void ToVRML::writeTexCoord(osg::Vec2Array* array, osg::Vec3Array* array2) {
1063
1064  osg::ref_ptr < osg::StateSet > ss = getCurrentStateSet();
1065  osg::Texture2D* tex = (osg::Texture2D*) (ss->getTextureAttribute(_txtUnit, osg::StateAttribute::TEXTURE));
1066  if (tex == NULL) {
1067    return;
1068  }
1069
1070  osg::ref_ptr < osg::TexGen > texGen = dynamic_cast<osg::TexGen*> (ss->getTextureAttribute(_txtUnit, osg::StateAttribute::TEXGEN));
1071  osg::ref_ptr < osg::TexEnv > texEnv = dynamic_cast<osg::TexEnv*> (ss->getTextureAttribute(_txtUnit, osg::StateAttribute::TEXENV));
1072
1073  osg::Texture::WrapMode wrap_s = tex->getWrap(osg::Texture::WRAP_S);//osg::Texture::REPEAT;
1074  osg::Texture::WrapMode wrap_t = tex->getWrap(osg::Texture::WRAP_T);//osg::Texture::REPEAT;
1075
1076  if (array != NULL) {
1077    writeUVArray(array, wrap_s, wrap_t);
1078
1079  } else if (texGen.valid()) {
1080    //std::cout << "TEXGEN" << std::endl;
1081    osg::ref_ptr < osg::Vec2Array > uvArray = buildUVArray(texGen.get(), array2);
1082    if (uvArray.valid()) {
1083      writeUVArray(uvArray.get(), wrap_s, wrap_t);
1084    }
1085
1086  } else if (texEnv.valid()) {
1087    //std::cout << "TEXENV" << std::endl;
1088    osg::ref_ptr < osg::Vec2Array > uvArray = buildUVArray(texEnv.get(), array2);
1089    if (uvArray.valid()) {
1090      writeUVArray(uvArray.get(), wrap_s, wrap_t);
1091    }
1092  }
1093}
1094
1095/////////////////////////////////////////////////////////////////////////
1096//
1097// writeNormal
1098//
1099/////////////////////////////////////////////////////////////////////////
1100void ToVRML::writeNormal(osg::Geometry* geom, std::vector<int>& primitiveSetFaces, int nbFaces) {
1101
1102  osg::ref_ptr < osg::Vec3Array > nArray = (osg::Vec3Array*) (geom->getNormalArray());
1103  if (!nArray.valid()) {
1104    return;
1105  }
1106
1107  if (geom->getNormalBinding() == osg::Geometry::BIND_PER_VERTEX || geom->getNormalBinding() == osg::Geometry::BIND_OVERALL) {
1108    _fout << indentM() << "normalPerVertex TRUE \n";
1109  } else {
1110    _fout << indentM() << "normalPerVertex FALSE \n";
1111  }
1112
1113  _fout << indent() << "normal Normal {\n";
1114  _fout << indentM() << "vector [\n";
1115  indentM();
1116  osg::Vec3 n;
1117
1118  if (geom->getNormalBinding() == osg::Geometry::BIND_PER_VERTEX) {
1119    for (unsigned int j = 0; j < (*nArray).size(); j++) {
1120      n = (*nArray)[j];
1121      _fout << indent() << n[0] << " " << n[1] << " " << n[2] << ",\n";
1122    }
1123
1124  } else if (geom->getNormalBinding() == osg::Geometry::BIND_OVERALL) {
1125    n = (*nArray)[0];
1126    int size = ((osg::Vec3Array*) (geom->getVertexArray()))->size();
1127    for (int j = 0; j < size; j++) {
1128      _fout << indent() << n[0] << " " << n[1] << " " << n[2] << ",\n";
1129    }
1130
1131  } else if (geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE) {
1132    for (unsigned int j = 0; j < (*nArray).size(); j++) {
1133      n = (*nArray)[j];
1134      _fout << indent() << n[0] << " " << n[1] << " " << n[2] << ",\n";
1135    }
1136
1137  } else if (geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE_SET) {
1138    for (unsigned int j = 0; j < (*nArray).size(); j++) {
1139      n = (*nArray)[j];
1140      for (int k = 0; k < primitiveSetFaces[j]; k++) {
1141        _fout << indent() << n[0] << " " << n[1] << " " << n[2] << ",\n";
1142      }
1143    }
1144  }
1145
1146  _fout << indentL() << "]\n";
1147  _fout << indentL() << "}\n";
1148  indentL();
1149}
1150
1151/////////////////////////////////////////////////////////////////////////
1152//
1153// writeUVArray
1154//
1155/////////////////////////////////////////////////////////////////////////
1156void ToVRML::writeUVArray(osg::Vec2Array* uvArray, osg::Texture::WrapMode wrap_s, osg::Texture::WrapMode wrap_t) {
1157
1158  _fout << indentM() << "texCoord TextureCoordinate {\n";
1159  _fout << indentM() << "point [\n";
1160  indentM();
1161  osg::Vec2 uv;
1162
1163  for (unsigned int j = 0; j < (*uvArray).size(); j++) {
1164    uv = (*uvArray)[j];
1165    if (wrap_s != osg::Texture::REPEAT) {
1166      // clamp to 0-1
1167      if (uv[0] < 0) {
1168        uv[0] = 0;
1169      } else if (uv[0] > 1) {
1170        uv[0] = 1;
1171      }
1172    }
1173    if (wrap_t != osg::Texture::REPEAT) {
1174      // clamp to 0-1
1175      if (uv[1] < 0) {
1176        uv[1] = 0;
1177      } else if (uv[1] > 1) {
1178        uv[1] = 1;
1179      }
1180    }
1181    _fout << indent() << uv[0] << " " << uv[1] << ",\n";
1182  }
1183  _fout << indentL() << "]\n";
1184  _fout << indentL() << "}\n";
1185  indentL();
1186}
1187
1188/////////////////////////////////////////////////////////////////////////
1189//
1190// buildUVArray
1191//
1192/////////////////////////////////////////////////////////////////////////
1193osg::Vec2Array* ToVRML::buildUVArray(osg::TexGen* tGen, osg::Vec3Array* array) {
1194  osg::ref_ptr < osg::TexGen > texGen = tGen;
1195  osg::ref_ptr < osg::Vec3Array > vArray = array;
1196  osg::Vec2Array* uvRet = NULL;
1197
1198  osg::TexGen::Mode mode = texGen->getMode();
1199  if (mode == osg::TexGen::OBJECT_LINEAR) {
1200    //std::cout << "I know" << std::endl;
1201
1202    uvRet = new osg::Vec2Array();
1203    osg::Plane planS = texGen->getPlane(osg::TexGen::S);//, osg::Vec4(1 / rangeS, 0, 0, -(adfGeoTransform[0] / rangeS)));
1204    osg::Plane planT = texGen->getPlane(osg::TexGen::T);//, osg::Vec4(0, 1 / rangeT, 0, -(adfGeoTransform[3] + sy * adfGeoTransform[5]) / rangeT));
1205    osg::Vec4 pS = planS.asVec4();
1206    osg::Vec4 pT = planT.asVec4();
1207    double width, height, xmin, ymin;
1208    width = 1.0 / pS[0];
1209    height = 1.0 / pT[1];
1210    xmin = -width * pS[3];
1211    ymin = -height * pT[3];
1212
1213    for (unsigned int j = 0; j < vArray->size(); j++) {
1214      osg::Vec3d p = (*vArray)[j];
1215      double x, y;
1216      osg::Vec2 uv;
1217      x = p[0];
1218      y = p[1];
1219      uv[0] = (x - xmin) / width;
1220      uv[1] = (y - ymin) / height;
1221      (*uvRet).push_back(uv);
1222
1223    }
1224  } else {
1225    osg::notify(osg::ALWAYS) << "Unknown TexGen mode" << std::endl;
1226  }
1227
1228  return (uvRet);
1229}
1230
1231/////////////////////////////////////////////////////////////////////////
1232//
1233// buildUVArray
1234//
1235/////////////////////////////////////////////////////////////////////////
1236osg::Vec2Array* ToVRML::buildUVArray(osg::TexEnv* tEnv, osg::Vec3Array* array) {
1237  osg::ref_ptr < osg::TexEnv > texEnv = tEnv;
1238  osg::Vec2Array* uvRet = NULL;
1239
1240 // osg::TexEnv::Mode mode = texEnv->getMode();
1241  //if (mode == osg::TexEnv::MODULATE) {
1242  //  std::cout << "I know" << std::endl;
1243  //} else {
1244  osg::notify(osg::ALWAYS) << "Unknown TexEnv mode" << std::endl;
1245  //}
1246  return (uvRet);
1247}
1248
1249/////////////////////////////////////////////////////////////////////////
1250//
1251// writeColor
1252//
1253/////////////////////////////////////////////////////////////////////////
1254void ToVRML::writeColor(osg::Geometry* geom, std::vector<int>& primitiveSetFaces, int nbFaces) {
1255
1256  osg::ref_ptr < osg::Vec4Array > cArray = (osg::Vec4Array*) (geom->getColorArray());
1257  if (!cArray.valid()) {
1258    return;
1259  }
1260
1261  if (geom->getColorBinding() == osg::Geometry::BIND_PER_VERTEX || geom->getColorBinding() == osg::Geometry::BIND_OVERALL) {
1262    _fout << indentM() << "colorPerVertex TRUE \n";
1263  } else {
1264    _fout << indentM() << "colorPerVertex FALSE \n";
1265  }
1266
1267  _fout << indent() << "color Color {\n";
1268  _fout << indentM() << "color [\n";
1269  indentM();
1270  osg::Vec4 c;
1271
1272  if (geom->getColorBinding() == osg::Geometry::BIND_PER_VERTEX) {
1273    for (unsigned int j = 0; j < (*cArray).size(); j++) {
1274      c = (*cArray)[j];
1275      _fout << indent() << c[0] << " " << c[1] << " " << c[2] << ",\n";
1276    }
1277
1278  } else if (geom->getColorBinding() == osg::Geometry::BIND_OVERALL) {
1279    c = (*cArray)[0];
1280    int size = ((osg::Vec3Array*) (geom->getVertexArray()))->size();
1281    for (int j = 0; j < size; j++) {
1282      _fout << indent() << c[0] << " " << c[1] << " " << c[2] << ",\n";
1283    }
1284
1285  } else if (geom->getColorBinding() == osg::Geometry::BIND_PER_PRIMITIVE) {
1286    for (unsigned int j = 0; j < (*cArray).size(); j++) {
1287      c = (*cArray)[j];
1288      _fout << indent() << c[0] << " " << c[1] << " " << c[2] << ",\n";
1289    }
1290
1291  } else if (geom->getColorBinding() == osg::Geometry::BIND_PER_PRIMITIVE_SET) {
1292    for (unsigned int j = 0; j < (*cArray).size(); j++) {
1293      c = (*cArray)[j];
1294      for (int k = 0; k < primitiveSetFaces[j]; k++) {
1295        _fout << indent() << c[0] << " " << c[1] << " " << c[2] << ",\n";
1296      }
1297    }
1298  }
1299
1300  _fout << indentL() << "]\n";
1301  _fout << indentL() << "}\n";
1302  indentL();
1303}
Note: See TracBrowser for help on using the browser.