13 #include "indexedFaceSet.h"
14 #include "vrmlAppearance.h"
15 #include "vrmlNodeType.h"
20 #include "eggVertex.h"
21 #include "eggVertexPool.h"
22 #include "eggPolygon.h"
31 _geometry(geometry), _appearance(appearance)
36 _has_normals = get_normals();
37 if (!_per_vertex_normals.empty()) {
38 assign_per_vertex_normals();
41 if (!_per_vertex_uvs.empty()) {
42 assign_per_vertex_uvs();
57 make_polys(vpool, group, net_transform);
58 if (!_has_normals && _appearance._has_material) {
59 compute_normals(group);
71 const VrmlNode *coord = _geometry->get_value(
"coord")._sfnode._p;
74 const MFArray *point = coord->get_value(
"point")._mf;
75 MFArray::const_iterator ci;
76 for (ci = point->begin(); ci != point->end(); ++ci) {
77 const double *p = (*ci)._sfvec;
78 _coord_values.push_back(
LVertexd(p[0], p[1], p[2]));
91 const MFArray *coordIndex = _geometry->get_value(
"coordIndex")._mf;
94 MFArray::const_iterator ci;
95 for (ci = coordIndex->begin(); ci != coordIndex->end(); ++ci) {
96 if ((*ci)._sfint32 < 0) {
97 _polys.push_back(poly);
100 const LVertexd &p = _coord_values[(*ci)._sfint32];
102 vert._index = (*ci)._sfint32;
104 poly._verts.push_back(vert);
115 void IndexedFaceSet::
116 get_vrml_colors(
const VrmlNode *color_node,
double transparency,
118 const MFArray *
color = color_node->get_value(
"color")._mf;
119 MFArray::const_iterator ci;
120 for (ci = color->begin(); ci != color->end(); ++ci) {
121 const double *p = (*ci)._sfvec;
122 LColor color(p[0], p[1], p[2], 1.0 - transparency);
123 color_list.push_back(color);
133 void IndexedFaceSet::
134 get_vrml_normals(
const VrmlNode *normal_node,
136 const MFArray *point = normal_node->get_value(
"vector")._mf;
137 MFArray::const_iterator ci;
138 for (ci = point->begin(); ci != point->end(); ++ci) {
139 const double *p = (*ci)._sfvec;
141 normal_list.push_back(normal);
151 void IndexedFaceSet::
152 get_vrml_uvs(
const VrmlNode *texCoord_node,
154 const MFArray *point = texCoord_node->get_value(
"point")._mf;
155 MFArray::const_iterator ci;
156 for (ci = point->begin(); ci != point->end(); ++ci) {
157 const double *p = (*ci)._sfvec;
159 uv_list.push_back(uv);
169 bool IndexedFaceSet::
171 const VrmlNode *color = _geometry->get_value(
"color")._sfnode._p;
175 get_vrml_colors(color, _appearance._transparency, color_list);
177 bool colorPerVertex = _geometry->get_value(
"colorPerVertex")._sfbool;
178 MFArray *colorIndex = _geometry->get_value(
"colorIndex")._mf;
179 if (colorPerVertex) {
180 MFArray::const_iterator ci;
183 for (ci = colorIndex->begin(); ci != colorIndex->end(); ++ci) {
184 if ((*ci)._sfint32 < 0) {
186 if (pv != _polys[pi]._verts.size()) {
187 cerr <<
"Color indices don't match up!\n";
193 if (pi >= _polys.size() || pv >= _polys[pi]._verts.size()) {
194 cerr <<
"Color indices don't match up!\n";
197 _polys[pi]._verts[pv]._attrib.set_color(color_list[(*ci)._sfint32]);
201 if (pi != _polys.size()) {
202 cerr <<
"Not enough color indices!\n";
206 if (!colorIndex->empty()) {
207 MFArray::const_iterator ci;
209 if (colorIndex->size() != _polys.size()) {
210 cerr <<
"Wrong number of color indices!\n";
213 for (ci = colorIndex->begin(); ci != colorIndex->end(); ++ci) {
214 if ((*ci)._sfint32 < 0 || (*ci)._sfint32 >= (
int)color_list.size()) {
215 cerr <<
"Invalid color index!\n";
218 _polys[pi]._attrib.set_color(color_list[(*ci)._sfint32]);
222 if (color_list.size() != _polys.size()) {
223 cerr <<
"Wrong number of colors!\n";
226 for (
size_t pi = 0; pi < color_list.size(); pi++) {
227 _polys[pi]._attrib.set_color(color_list[pi]);
241 bool IndexedFaceSet::
243 const VrmlNode *normal = _geometry->get_value(
"normal")._sfnode._p;
244 if (normal != NULL) {
247 get_vrml_normals(normal, normal_list);
249 bool normalPerVertex = _geometry->get_value(
"normalPerVertex")._sfbool;
250 MFArray *normalIndex = _geometry->get_value(
"normalIndex")._mf;
251 MFArray::const_iterator ci;
253 if (normalPerVertex &&
254 normal_list.size() == _polys.size() &&
255 normalIndex->empty()) {
260 normalPerVertex =
false;
263 if (normalPerVertex) {
265 if (normalIndex->empty()) {
270 for (
size_t i = 0; i < normal_list.size(); i++) {
273 (*normalIndex).push_back(fv);
282 bool linear_list = (normalIndex->size() == _coord_values.size());
283 for (ci = normalIndex->begin();
284 ci != normalIndex->end() && linear_list;
286 linear_list = ((*ci)._sfint32 >= 0);
293 _per_vertex_normals.reserve(_coord_values.size());
295 for (ci = normalIndex->begin(); ci != normalIndex->end(); ++ci) {
296 size_t vi = (*ci)._sfint32;
297 nassertr(vi >= 0,
false);
298 if (vi >= normal_list.size()) {
299 cerr <<
"Invalid normal index: " << vi <<
"\n";
302 _per_vertex_normals.push_back(normal_list[vi]);
304 nassertr(_per_vertex_normals.size() == _coord_values.size(),
false);
312 MFArray::const_iterator ci;
315 for (ci = normalIndex->begin(); ci != normalIndex->end(); ++ci) {
316 if ((*ci)._sfint32 < 0) {
318 if (pv != _polys[pi]._verts.size()) {
319 cerr <<
"Normal indices don't match up!\n";
325 if (pi >= _polys.size() || pv >= _polys[pi]._verts.size()) {
326 cerr <<
"Normal indices don't match up!\n";
329 const LNormald &d = normal_list[(*ci)._sfint32];
330 _polys[pi]._verts[pv]._attrib.set_normal(d);
334 if (pi != _polys.size()) {
335 cerr <<
"Not enough normal indices!\n";
340 if (!normalIndex->empty()) {
342 if (normalIndex->size() != _polys.size()) {
343 cerr <<
"Wrong number of normal indices!\n";
346 for (ci = normalIndex->begin(); ci != normalIndex->end(); ++ci) {
347 if ((*ci)._sfint32 < 0 || (*ci)._sfint32 >= (
int)normal_list.size()) {
348 cerr <<
"Invalid normal index!\n";
351 const LNormald &d = normal_list[(*ci)._sfint32];
352 _polys[pi]._attrib.set_normal(d);
356 if (normal_list.size() != _polys.size()) {
357 cerr <<
"Wrong number of normals!\n";
360 for (
size_t pi = 0; pi < normal_list.size(); pi++) {
361 const LNormald &d = normal_list[pi];
362 _polys[pi]._attrib.set_normal(d);
380 void IndexedFaceSet::
381 assign_per_vertex_normals() {
382 for (
size_t pi = 0; pi < _polys.size(); pi++) {
383 for (
size_t pv = 0; pv < _polys[pi]._verts.size(); pv++) {
384 VrmlVertex &vv = _polys[pi]._verts[pv];
385 if (vv._index >= 0 && vv._index < (
int)_per_vertex_normals.size()) {
386 const LNormald &d = _per_vertex_normals[vv._index];
387 vv._attrib.set_normal(d);
399 bool IndexedFaceSet::
401 const VrmlNode *texCoord = _geometry->get_value(
"texCoord")._sfnode._p;
402 if (texCoord != NULL) {
405 get_vrml_uvs(texCoord, uv_list);
407 MFArray *texCoordIndex = _geometry->get_value(
"texCoordIndex")._mf;
408 MFArray::const_iterator ci;
410 if (texCoordIndex->empty()) {
415 for (
size_t i = 0; i < uv_list.size(); i++) {
418 (*texCoordIndex).push_back(fv);
427 bool linear_list = (texCoordIndex->size() == _coord_values.size());
428 for (ci = texCoordIndex->begin();
429 ci != texCoordIndex->end() && linear_list;
431 linear_list = ((*ci)._sfint32 >= 0);
438 _per_vertex_uvs.reserve(_coord_values.size());
440 for (ci = texCoordIndex->begin(); ci != texCoordIndex->end(); ++ci) {
441 size_t vi = (*ci)._sfint32;
442 nassertr(vi >= 0,
false);
443 if (vi >= uv_list.size()) {
444 cerr <<
"Invalid texCoord index: " << vi <<
"\n";
447 _per_vertex_uvs.push_back(uv_list[vi]);
449 nassertr(_per_vertex_uvs.size() == _coord_values.size(),
false);
459 for (ci = texCoordIndex->begin(); ci != texCoordIndex->end(); ++ci) {
460 if ((*ci)._sfint32 < 0) {
462 if (pv != _polys[pi]._verts.size()) {
463 cerr <<
"texCoord indices don't match up!\n";
469 if (pi >= _polys.size() || pv >= _polys[pi]._verts.size()) {
470 cerr <<
"texCoord indices don't match up!\n";
473 _polys[pi]._verts[pv]._attrib.set_uv(uv_list[(*ci)._sfint32]);
477 if (pi != _polys.size()) {
478 cerr <<
"Not enough texCoord indices!\n";
496 void IndexedFaceSet::
497 assign_per_vertex_uvs() {
498 for (
size_t pi = 0; pi < _polys.size(); pi++) {
499 for (
size_t pv = 0; pv < _polys[pi]._verts.size(); pv++) {
500 VrmlVertex &vv = _polys[pi]._verts[pv];
501 if (vv._index >= 0 && vv._index < (
int)_per_vertex_uvs.size()) {
502 const LTexCoordd &d = _per_vertex_uvs[vv._index];
503 vv._attrib.set_uv(d);
515 void IndexedFaceSet::
518 bool ccw = _geometry->get_value(
"ccw")._sfbool;
519 bool solid = _geometry->get_value(
"solid")._sfbool;
521 for (
size_t pi = 0; pi < _polys.size(); pi++) {
526 if (!poly->has_color() && _appearance._has_material) {
527 poly->set_color(_appearance._color);
540 for (
int pv = 0; pv < (int)_polys[pi]._verts.size(); pv++) {
541 EggVertex vert(_polys[pi]._verts[pv]._attrib);
543 _polys[pi]._verts[pv]._pos * net_transform;
550 for (
int pv = (
int)_polys[pi]._verts.size() - 1; pv >= 0; pv--) {
551 EggVertex vert(_polys[pi]._verts[pv]._attrib);
553 _polys[pi]._verts[pv]._pos * net_transform;
568 void IndexedFaceSet::
570 const VrmlNode *normal = _geometry->get_value(
"normal")._sfnode._p;
571 if (normal == NULL) {
573 double creaseAngle = _geometry->get_value(
"creaseAngle")._sffloat;
574 if (creaseAngle == 0.0) {
This is a 4-by-4 transform matrix.
Defines a texture map that may be applied to geometry.
void recompute_polygon_normals(CoordinateSystem cs=CS_default)
Recomputes all the polygon normals for polygon geometry at this group node and below so that they acc...
void set_texture(EggTexture *texture)
Replaces the current list of textures with the indicated texture.
void copy_attributes(const EggAttributes &other)
Copies the rendering attributes from the indicated primitive.
This is a two-component point in space.
void set_bface_flag(bool flag)
Sets the backfacing flag of the polygon.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal...
This is the base class for all three-component vectors and points.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
EggVertex * create_unique_vertex(const EggVertex ©)
Creates a new vertex in the pool that is a copy of the indicated one and returns it.
A collection of vertices.
EggVertex * add_vertex(EggVertex *vertex)
Adds the indicated vertex to the end of the primitive's list of vertices, and returns it...
void recompute_vertex_normals(double threshold, CoordinateSystem cs=CS_default)
Recomputes all the vertex normals for polygon geometry at this group node and below so that they accu...