Updates to iv/vrml loader from Ruben.

This commit is contained in:
Robert Osfield 2002-07-31 15:16:14 +00:00
parent 3840972440
commit 1adc4992ff
11 changed files with 1558 additions and 1112 deletions

View File

@ -0,0 +1,39 @@
/*
* osgDB::wrl - a VRML 1.0 loader for OpenSceneGraph
* Copyright (C) 2002 Ruben Lopez <ryu@gpul.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ATR_VEC3_LIST_H__
#define __ATR_VEC3_LIST_H__
#include "attribute.h"
#include "geometry.h"
class AtrVec3List: public Attribute {
VertexList *list;
public:
AtrVec3List(char *name):Attribute(name) { list=0; }
AtrVec3List(char *name, VertexList *vlist):Attribute(name) {
this->list=vlist;
}
VertexList *getList() { return list; }
int getSize() { return list->size(); }
virtual char *type() { return "AtrVec3List"; }
};
#endif

View File

@ -0,0 +1,52 @@
/*
* osgDB::wrl - a VRML 1.0 loader for OpenSceneGraph
* Copyright (C) 2002 Ruben Lopez <ryu@gpul.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __INDEXED_TRI_STRIP_SET_H__
#define __INDEXED_TRI_STRIP_SET_H__
#include "mynode.h"
class IndexedTriStripSet: public MyNode {
PolygonList polys;
PolygonList textureIndices; // Indexed texture set.
bool _hasTextureIndices;
public:
IndexedTriStripSet() {}
IndexedTriStripSet(PolygonList *p) {
polys=*p;
_hasTextureIndices=false;
}
IndexedTriStripSet(PolygonList *p, PolygonList *t) {
polys=*p;
textureIndices=*t;
_hasTextureIndices=true;
}
bool hasTextureIndices() { return _hasTextureIndices; }
PolygonList getPolygons() { return polys; }
PolygonList getTextureIndices() { return textureIndices; }
virtual char *type() { return "IndexedTriStripSet"; }
virtual void accept(MyNodeVisitor *v) { v->applyIndexedTriStripSet(this); }
};
#endif

View File

@ -40,7 +40,7 @@ osg::Node *readVRMLNode(const char *file) {
yydebug=0;
yyin=fopen(file,"r");
std::cout << "Parsing..." << std::endl;
yyparse();
if (yyparse()!=0) return 0;
osg::ref_ptr<MyNode> n=getRoot();
try {
std::cout << "Generating OSG tree..." << std::endl;

View File

@ -26,6 +26,7 @@ class Coordinate3;
class MatrixTransform;
class Separator;
class IndexedFaceSet;
class IndexedTriStripSet;
class TextureCoordinate;
class Texture2;
class Transform;
@ -40,6 +41,7 @@ public:
virtual void applyMatrixTransform(MatrixTransform *tr)=0;
virtual void applySeparator(Separator *sep)=0;
virtual void applyIndexedFaceSet(IndexedFaceSet *ifs)=0;
virtual void applyIndexedTriStripSet(IndexedTriStripSet *its)=0;
virtual void applyTextureCoordinate(TextureCoordinate *texc)=0;
virtual void applyTexture2(Texture2 *tex)=0;
virtual void applyTransform(Transform *trans)=0;

View File

@ -28,6 +28,7 @@
#include "separator.h"
#include "matrixtransform.h"
#include "indexedfaceset.h"
#include "indexedtristripset.h"
#include "texturecoordinate.h"
#include "texture2.h"
#include "transform.h"
@ -51,18 +52,19 @@
#include "atrvec.h"
#include "atrfloat.h"
#include "atrstring.h"
#include "atrvec3list.h"
#include "ltstr.h"
#include "normals.h"
#define CREASE_ANGLE 2//3.14159265359 * 2.0 / 3.0
class CacheObjetos {
class ObjectCache {
typedef std::map<osg::ref_ptr<Material>, osg::ref_ptr<osg::Material> > MaterialMap;
typedef std::map<const char*, osg::ref_ptr<osg::Texture>, ltstr> TextureMap;
typedef std::map<osg::ref_ptr<MyNode>, osg::ref_ptr<osg::Node> > NodeMap;
static MaterialMap materiales;
static MaterialMap materials;
static TextureMap textures;
static NodeMap nodos;
public:
@ -71,21 +73,23 @@ public:
}
static osg::Material* getMaterial(Material* _material) {
if (materiales.find(_material) == materiales.end()) {
AtrVec *ambient=(AtrVec*)_material->getAttribute("ambientColor");
AtrVec *diffuse=(AtrVec*)_material->getAttribute("diffuseColor");
AtrVec *specular=(AtrVec*)_material->getAttribute("specularColor");
AtrFloat *shininess=(AtrFloat*)_material->getAttribute("shininess");
AtrFloat *transparency=(AtrFloat*)_material->getAttribute("transparency");
if (materials.find(_material) == materials.end()) {
AtrVec *ambient=dynamic_cast<AtrVec*>(_material->getAttribute("ambientColor"));
AtrVec *diffuse=dynamic_cast<AtrVec*>(_material->getAttribute("diffuseColor"));
AtrVec *specular=dynamic_cast<AtrVec*>(_material->getAttribute("specularColor"));
AtrFloat *shininess=dynamic_cast<AtrFloat*>(_material->getAttribute("shininess"));
AtrFloat *transparency=dynamic_cast<AtrFloat*>(_material->getAttribute("transparency"));
osg::Material *material=new osg::Material();
if (ambient) material->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(ambient->getValCut(0),ambient->getValCut(1),ambient->getValCut(2),1.0f));
if (diffuse) material->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4(diffuse->getValCut(0),diffuse->getValCut(1),diffuse->getValCut(2),1.0f));
if (specular) material->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4(specular->getValCut(0),specular->getValCut(1),specular->getValCut(2),1.0f));
if (shininess) material->setShininess(osg::Material::FRONT_AND_BACK,shininess->getValue());
if (transparency) material->setTransparency(osg::Material::FRONT_AND_BACK,transparency->getValue());
materiales[_material]=material;
if (ambient || diffuse || specular || transparency)
materials[_material]=material;
else return 0;
}
return materiales[_material].get();
return materials[_material].get();
}
static osg::Texture* getTextura(const char* _texture) {
@ -101,9 +105,9 @@ public:
}
};
CacheObjetos::MaterialMap CacheObjetos::materiales;
CacheObjetos::TextureMap CacheObjetos::textures;
CacheObjetos::NodeMap CacheObjetos::nodos;
ObjectCache::MaterialMap ObjectCache::materials;
ObjectCache::TextureMap ObjectCache::textures;
ObjectCache::NodeMap ObjectCache::nodos;
static void makeTransform(MatrixTransform *matriz_active, osg::Transform *nodo) {
// Original
@ -214,21 +218,14 @@ osg::Primitive *generatePrimitive(PolygonList &polys, unsigned primsize) {
return p;
}
void OSGVisitor::applyIndexedFaceSet(IndexedFaceSet *ifs) {
unsigned i;
if (coord3_active == 0) {
std::cerr << "ERROR: IndexedFaceSet without previous Coordinate3!" << std::endl;
throw -1;
}
osg::Geode *geode=new osg::Geode();
osg::Geometry *geometry=new osg::Geometry();
void OSGVisitor::makeGeode(osg::Geode *geode, osg::Geometry *geometry, bool twoSided) {
osg::StateSet *state=new osg::StateSet();
osg::FrontFace *frontface=new osg::FrontFace();
frontface->setMode(osg::FrontFace::CLOCKWISE);
state->setAttributeAndModes(frontface,osg::StateAttribute::ON);
osg::CullFace *cull=new osg::CullFace();
cull->setMode(osg::CullFace::BACK);
if (ifs->getTwoSided() == false) {
if (twoSided) {
state->setAttributeAndModes(cull,osg::StateAttribute::ON);
} else {
std::cout << "Deactivating culling for this object" << std::endl;
@ -242,18 +239,44 @@ void OSGVisitor::applyIndexedFaceSet(IndexedFaceSet *ifs) {
geode->setStateSet(state);
/** Applying the material */
if (material_active!=0) {
osg::Material *material = CacheObjetos::getMaterial(material_active);
osg::Material *material = ObjectCache::getMaterial(material_active);
state->setAttributeAndModes(material,osg::StateAttribute::ON);
}
/** Applying the texture */
if (texture_active!=0) {
AtrString *filename=(AtrString*)texture_active->getAttribute("filename");
if (filename) {
osg::Texture *texture=CacheObjetos::getTextura(filename->getValue());
osg::Texture *texture=ObjectCache::getTextura(filename->getValue());
state->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
}
}
/* If needed, apply per-vertex colors */
if (material_active) {
AtrVec3List *diffuse=dynamic_cast<AtrVec3List*>(material_active->getAttribute("diffuseColor"));
if (diffuse) { // Has per-vertex colors
std::cout << "Per vertex colors" << std::endl;
VertexList *colors=diffuse->getList();
osg::Vec3Array *colors_osg=new osg::Vec3Array();
for (unsigned i=0;i<colors->size();i++) {
colors_osg->push_back((*colors)[i]);
}
std::cout << colors->size() << " colors" << std::endl;
geometry->setColorArray(colors_osg);
geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
}
}
}
void OSGVisitor::applyIndexedFaceSet(IndexedFaceSet *ifs) {
unsigned i;
if (coord3_active == 0) {
std::cerr << "ERROR: IndexedFaceSet without previous Coordinate3!" << std::endl;
throw -1;
}
osg::Geode *geode=new osg::Geode();
osg::Geometry *geometry=new osg::Geometry();
makeGeode(geode,geometry,ifs->getTwoSided());
/* Converting list of vertices to the OSG way (mostly the same) */
VertexList vertices=coord3_active->getVertices();
osg::Vec3Array *vertices_osg=new osg::Vec3Array();
@ -261,6 +284,7 @@ void OSGVisitor::applyIndexedFaceSet(IndexedFaceSet *ifs) {
vertices_osg->push_back(vertices[i]);
}
geometry->setVertexArray(vertices_osg);
total_vert+=vertices.size();
/* Converting list of polys */
PolygonList polys=ifs->getPolygons();
@ -284,6 +308,7 @@ void OSGVisitor::applyIndexedFaceSet(IndexedFaceSet *ifs) {
geometry->setTexCoordArray(0,texCoords);
}
}
osgUtil::SmoothingVisitor v;
v.smooth(*geometry);
@ -297,6 +322,65 @@ void OSGVisitor::applyIndexedFaceSet(IndexedFaceSet *ifs) {
parent->addChild(geode);
}
void OSGVisitor::applyIndexedTriStripSet(IndexedTriStripSet *its) {
unsigned i,j;
if (coord3_active == 0) {
std::cerr << "ERROR: IndexedFaceSet without previous Coordinate3!" << std::endl;
throw -1;
}
osg::Geode *geode=new osg::Geode();
osg::Geometry *geometry=new osg::Geometry();
makeGeode(geode,geometry,its->getTwoSided());
/* Converting list of vertices to the OSG way (mostly the same) */
VertexList vertices=coord3_active->getVertices();
osg::Vec3Array *vertices_osg=new osg::Vec3Array();
for (i=0;i<vertices.size();i++) {
vertices_osg->push_back(vertices[i]);
}
geometry->setVertexArray(vertices_osg);
total_vert+=vertices.size();
/* Converting list of polys */
PolygonList polys=its->getPolygons();
for (i=0;i<polys.size();i++) {
VertexIndexList vindex=*polys[i];
unsigned short *indices=new unsigned short[vindex.size()];
for (j=0;j<vindex.size();j++) {
indices[j]=vindex[j];
}
geometry->addPrimitive(new osg::DrawElementsUShort(osg::Primitive::TRIANGLE_STRIP,vindex.size(),indices));
}
TextureCoordList tcoord;
if (tcoord_active) tcoord=tcoord_active->getTextureCoords();
PolygonList textureIndices = its->getTextureIndices();
if (tcoord_active) {
if (its->hasTextureIndices()) {
std::cerr << "texture indices are not supported!" << std::endl;
} else {
osg::Vec2Array *texCoords=new osg::Vec2Array();
for (i=0;i<vertices.size();i++) {
texCoords->push_back(osg::Vec2(tcoord[i].first,tcoord[i].second));
}
geometry->setTexCoordArray(0,texCoords);
}
}
osgUtil::SmoothingVisitor v;
v.smooth(*geometry);
// As SmoothingVisitor doesn't take the front face into account:
osg::Vec3Array *norm=geometry->getNormalArray();
for (i=0;i<norm->size();i++) {
(*norm)[i] = - (*norm)[i];
}
geode->addDrawable(geometry);
parent->addChild(geode);
}
void OSGVisitor::applyTextureCoordinate(TextureCoordinate *texc) {
tcoord_active=texc;
}

View File

@ -22,6 +22,7 @@
#include "mynodevisitor.h"
#include <osg/Group>
#include <osg/Geometry>
class OSGVisitor: public MyNodeVisitor {
osg::Node *root;
@ -41,10 +42,13 @@ public:
virtual void applyMatrixTransform(MatrixTransform *tr);
virtual void applySeparator(Separator *sep);
virtual void applyIndexedFaceSet(IndexedFaceSet *ifs);
virtual void applyIndexedTriStripSet(IndexedTriStripSet *its);
virtual void applyTextureCoordinate(TextureCoordinate *texc);
virtual void applyTexture2(Texture2 *tex);
virtual void applyTransform(Transform *trans);
osg::Node* getRoot();
private:
void makeGeode(osg::Geode *geode, osg::Geometry *geometry, bool twoSided);
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -27,21 +27,22 @@ typedef union {
# define DIFFUSE_COLOR 264
# define COORDINATE3 265
# define INDEXED_FACE_SET 266
# define A_POINT 267
# define COORD_INDEX 268
# define TEXTURE_COORD_INDEX 269
# define NORMAL_INDEX 270
# define TEXTURE_COORDINATE 271
# define TEXTURE2 272
# define MATRIX_TRANSFORM 273
# define MATRIX 274
# define LISTA_VACIA 275
# define FINPOLY 276
# define DOBLE_CARA 277
# define VECTOR 278
# define VRML_HEADER 279
# define TRANSFORM 280
# define USE 281
# define INDEXED_TRIANGLE_STRIP_SET 267
# define A_POINT 268
# define COORD_INDEX 269
# define TEXTURE_COORD_INDEX 270
# define NORMAL_INDEX 271
# define TEXTURE_COORDINATE 272
# define TEXTURE2 273
# define MATRIX_TRANSFORM 274
# define MATRIX 275
# define LISTA_VACIA 276
# define FINPOLY 277
# define TWO_SIDED 278
# define VECTOR 279
# define VRML_HEADER 280
# define TRANSFORM 281
# define USE 282
extern YYSTYPE yylval;

View File

@ -34,6 +34,7 @@
#include "separator.h"
#include "matrixtransform.h"
#include "indexedfaceset.h"
#include "indexedtristripset.h"
#include "texturecoordinate.h"
#include "texture2.h"
#include "transform.h"
@ -41,6 +42,7 @@
#include "atrfloat.h"
#include "atrstring.h"
#include "atrvec.h"
#include "atrvec3list.h"
#include "string.h"
extern int yyline;
extern int yylex();
@ -66,11 +68,11 @@ static MyNode *root_node;
%token <s_value> QUOTED_STRING
%token <f_value> FLOAT
%token <i_value> INT
%token SEPARATOR DEF UN_MATERIAL DIFFUSE_COLOR COORDINATE3 INDEXED_FACE_SET
%token SEPARATOR DEF UN_MATERIAL DIFFUSE_COLOR COORDINATE3 INDEXED_FACE_SET INDEXED_TRIANGLE_STRIP_SET
%token A_POINT COORD_INDEX TEXTURE_COORD_INDEX NORMAL_INDEX TEXTURE_COORDINATE TEXTURE2
%token MATRIX_TRANSFORM MATRIX
%token LISTA_VACIA FINPOLY
%token DOBLE_CARA
%token TWO_SIDED
%token VECTOR
%token VRML_HEADER
%token TRANSFORM
@ -99,9 +101,13 @@ node:
| INDEXED_FACE_SET '{' COORD_INDEX '[' polylist ']' '}' {$$=new IndexedFaceSet($5); delete $5; }
| INDEXED_FACE_SET '{' COORD_INDEX '[' polylist ']' TEXTURE_COORD_INDEX '[' polylist ']' '}' {$$=new IndexedFaceSet($5,$9); delete $5; delete $9; }
| INDEXED_FACE_SET '{' COORD_INDEX '[' polylist ']' NORMAL_INDEX '[' polylist ']' '}' {$$=new IndexedFaceSet($5); delete $5; delete $9; }
| INDEXED_FACE_SET '{' DOBLE_CARA COORD_INDEX '[' polylist ']' '}' {$$=new IndexedFaceSet($6); delete $6; $$->setTwoSided(); }
| INDEXED_FACE_SET '{' DOBLE_CARA COORD_INDEX '[' polylist ']' TEXTURE_COORD_INDEX '[' polylist ']' '}' {$$=new IndexedFaceSet($6,$10); delete $6; delete $10; $$->setTwoSided(); $$->setTwoSided(); }
| INDEXED_FACE_SET '{' DOBLE_CARA COORD_INDEX '[' polylist ']' NORMAL_INDEX '[' polylist ']' '}' {$$=new IndexedFaceSet($6); delete $6; delete $10; $$->setTwoSided(); }
| INDEXED_FACE_SET '{' TWO_SIDED COORD_INDEX '[' polylist ']' '}' {$$=new IndexedFaceSet($6); delete $6; $$->setTwoSided(); }
| INDEXED_FACE_SET '{' TWO_SIDED COORD_INDEX '[' polylist ']' TEXTURE_COORD_INDEX '[' polylist ']' '}' {$$=new IndexedFaceSet($6,$10); delete $6; delete $10; $$->setTwoSided(); $$->setTwoSided(); }
| INDEXED_FACE_SET '{' TWO_SIDED COORD_INDEX '[' polylist ']' NORMAL_INDEX '[' polylist ']' '}' {$$=new IndexedFaceSet($6); delete $6; delete $10; $$->setTwoSided(); }
| INDEXED_TRIANGLE_STRIP_SET '{' COORD_INDEX '[' polylist ']' '}' {$$=new IndexedTriStripSet($5); delete $5; }
| INDEXED_TRIANGLE_STRIP_SET '{' COORD_INDEX '[' polylist ']' TEXTURE_COORD_INDEX '[' polylist ']' '}' {$$=new IndexedTriStripSet($5,$9); delete $5; delete $9; }
| INDEXED_TRIANGLE_STRIP_SET '{' COORD_INDEX '[' polylist ']' NORMAL_INDEX '[' polylist ']' '}' {$$=new IndexedTriStripSet($5); delete $5; delete $9; }
| MATRIX_TRANSFORM '{' MATRIX matrix '}' { $$=new MatrixTransform($4); }
| TEXTURE_COORDINATE '{' A_POINT '[' coords ']' '}' { $$=new TextureCoordinate($5); delete $5; }
| TRANSFORM '{' node_contents '}' { $$=new Transform($3); delete $3; }
@ -143,6 +149,7 @@ attr: STRING FLOAT { $$=new AtrFloat($1,$2); }
| STRING FLOAT FLOAT FLOAT { $$=new AtrVec($1,$2,$3,$4); }
| STRING FLOAT FLOAT FLOAT FLOAT { $$=new AtrVec($1,$2,$3,$4,$5); }
| STRING QUOTED_STRING { $$=new AtrString($1,$2); }
| STRING '[' points ']' { $$=new AtrVec3List($1,$3); }
;
coords: coords FLOAT FLOAT { $1->push_back(TextureCoordVal($2,$3));$$=$1; }

File diff suppressed because it is too large Load Diff

View File

@ -36,10 +36,11 @@ Texture2 { return TEXTURE2; }
Separator { return SEPARATOR; }
Material { return UN_MATERIAL; }
IndexedFaceSet { return INDEXED_FACE_SET; }
IndexedTriangleStripSet { return INDEXED_TRIANGLE_STRIP_SET; }
TextureCoordinate2 { return TEXTURE_COORDINATE; }
Transform { return TRANSFORM; }
MatrixTransform { return MATRIX_TRANSFORM; }
DobleCara { return DOBLE_CARA; }
TwoSided { return TWO_SIDED; }
matrix { return MATRIX; }
point { return A_POINT; }
coordIndex { BEGIN cindex;return COORD_INDEX; }
@ -50,7 +51,7 @@ vector { return VECTOR; }
<INITIAL,cindex>\] { BEGIN INITIAL; return ']'; }
USE { BEGIN def;return USE; }
"#VRML\ V1.0 ascii" { return VRML_HEADER; }
"#Inventor\ V2.0 ascii" { return VRML_HEADER; }
"#Inventor\ V2."." ascii" { return VRML_HEADER; }
#[^\n\r]*
"-"?{DIGIT}+"."{DIGIT}* {
yylval.f_value=strtod(yytext,NULL);