16 #include "vrmlNodeType.h" 32 _geometry(geometry), _appearance(appearance)
37 _has_normals = get_normals();
38 if (!_per_vertex_normals.empty()) {
39 assign_per_vertex_normals();
42 if (!_per_vertex_uvs.empty()) {
43 assign_per_vertex_uvs();
52 convert_to_egg(
EggGroup *group,
const LMatrix4d &net_transform) {
56 make_polys(vpool, group, net_transform);
57 if (!_has_normals && _appearance._has_material) {
58 compute_normals(group);
68 const VrmlNode *coord = _geometry->get_value(
"coord")._sfnode._p;
70 if (coord !=
nullptr) {
71 const MFArray *point = coord->get_value(
"point")._mf;
72 MFArray::const_iterator ci;
73 for (ci = point->begin(); ci != point->end(); ++ci) {
74 const double *p = (*ci)._sfvec;
75 _coord_values.push_back(LVertexd(p[0], p[1], p[2]));
86 const MFArray *coordIndex = _geometry->get_value(
"coordIndex")._mf;
89 MFArray::const_iterator ci;
90 for (ci = coordIndex->begin(); ci != coordIndex->end(); ++ci) {
91 if ((*ci)._sfint32 < 0) {
92 _polys.push_back(poly);
95 const LVertexd &p = _coord_values[(*ci)._sfint32];
97 vert._index = (*ci)._sfint32;
99 poly._verts.push_back(vert);
107 void IndexedFaceSet::
108 get_vrml_colors(
const VrmlNode *color_node,
double transparency,
110 const MFArray *color = color_node->get_value(
"color")._mf;
111 MFArray::const_iterator ci;
112 for (ci = color->begin(); ci != color->end(); ++ci) {
113 const double *p = (*ci)._sfvec;
114 LColor color(p[0], p[1], p[2], 1.0 - transparency);
115 color_list.push_back(color);
123 void IndexedFaceSet::
124 get_vrml_normals(
const VrmlNode *normal_node,
126 const MFArray *point = normal_node->get_value(
"vector")._mf;
127 MFArray::const_iterator ci;
128 for (ci = point->begin(); ci != point->end(); ++ci) {
129 const double *p = (*ci)._sfvec;
130 LNormald normal(p[0], p[1], p[2]);
131 normal_list.push_back(normal);
139 void IndexedFaceSet::
140 get_vrml_uvs(
const VrmlNode *texCoord_node,
142 const MFArray *point = texCoord_node->get_value(
"point")._mf;
143 MFArray::const_iterator ci;
144 for (ci = point->begin(); ci != point->end(); ++ci) {
145 const double *p = (*ci)._sfvec;
146 LTexCoordd uv(p[0], p[1]);
147 uv_list.push_back(uv);
155 bool IndexedFaceSet::
157 const VrmlNode *color = _geometry->get_value(
"color")._sfnode._p;
158 if (color !=
nullptr) {
161 get_vrml_colors(color, _appearance._transparency, color_list);
163 bool colorPerVertex = _geometry->get_value(
"colorPerVertex")._sfbool;
164 MFArray *colorIndex = _geometry->get_value(
"colorIndex")._mf;
165 if (colorPerVertex) {
166 MFArray::const_iterator ci;
169 for (ci = colorIndex->begin(); ci != colorIndex->end(); ++ci) {
170 if ((*ci)._sfint32 < 0) {
172 if (pv != _polys[pi]._verts.size()) {
173 cerr <<
"Color indices don't match up!\n";
179 if (pi >= _polys.size() || pv >= _polys[pi]._verts.size()) {
180 cerr <<
"Color indices don't match up!\n";
183 _polys[pi]._verts[pv]._attrib.set_color(color_list[(*ci)._sfint32]);
187 if (pi != _polys.size()) {
188 cerr <<
"Not enough color indices!\n";
192 if (!colorIndex->empty()) {
193 MFArray::const_iterator ci;
195 if (colorIndex->size() != _polys.size()) {
196 cerr <<
"Wrong number of color indices!\n";
199 for (ci = colorIndex->begin(); ci != colorIndex->end(); ++ci) {
200 if ((*ci)._sfint32 < 0 || (*ci)._sfint32 >= (
int)color_list.size()) {
201 cerr <<
"Invalid color index!\n";
204 _polys[pi]._attrib.set_color(color_list[(*ci)._sfint32]);
208 if (color_list.size() != _polys.size()) {
209 cerr <<
"Wrong number of colors!\n";
212 for (
size_t pi = 0; pi < color_list.size(); pi++) {
213 _polys[pi]._attrib.set_color(color_list[pi]);
225 bool IndexedFaceSet::
227 const VrmlNode *normal = _geometry->get_value(
"normal")._sfnode._p;
228 if (normal !=
nullptr) {
231 get_vrml_normals(normal, normal_list);
233 bool normalPerVertex = _geometry->get_value(
"normalPerVertex")._sfbool;
234 MFArray *normalIndex = _geometry->get_value(
"normalIndex")._mf;
235 MFArray::const_iterator ci;
237 if (normalPerVertex &&
238 normal_list.size() == _polys.size() &&
239 normalIndex->empty()) {
244 normalPerVertex =
false;
247 if (normalPerVertex) {
249 if (normalIndex->empty()) {
253 for (
size_t i = 0; i < normal_list.size(); i++) {
256 (*normalIndex).push_back(fv);
265 bool linear_list = (normalIndex->size() == _coord_values.size());
266 for (ci = normalIndex->begin();
267 ci != normalIndex->end() && linear_list;
269 linear_list = ((*ci)._sfint32 >= 0);
276 _per_vertex_normals.reserve(_coord_values.size());
278 for (ci = normalIndex->begin(); ci != normalIndex->end(); ++ci) {
279 size_t vi = (*ci)._sfint32;
280 nassertr(vi >= 0,
false);
281 if (vi >= normal_list.size()) {
282 cerr <<
"Invalid normal index: " << vi <<
"\n";
285 _per_vertex_normals.push_back(normal_list[vi]);
287 nassertr(_per_vertex_normals.size() == _coord_values.size(),
false);
295 MFArray::const_iterator ci;
298 for (ci = normalIndex->begin(); ci != normalIndex->end(); ++ci) {
299 if ((*ci)._sfint32 < 0) {
301 if (pv != _polys[pi]._verts.size()) {
302 cerr <<
"Normal indices don't match up!\n";
308 if (pi >= _polys.size() || pv >= _polys[pi]._verts.size()) {
309 cerr <<
"Normal indices don't match up!\n";
312 const LNormald &d = normal_list[(*ci)._sfint32];
313 _polys[pi]._verts[pv]._attrib.set_normal(d);
317 if (pi != _polys.size()) {
318 cerr <<
"Not enough normal indices!\n";
323 if (!normalIndex->empty()) {
325 if (normalIndex->size() != _polys.size()) {
326 cerr <<
"Wrong number of normal indices!\n";
329 for (ci = normalIndex->begin(); ci != normalIndex->end(); ++ci) {
330 if ((*ci)._sfint32 < 0 || (*ci)._sfint32 >= (
int)normal_list.size()) {
331 cerr <<
"Invalid normal index!\n";
334 const LNormald &d = normal_list[(*ci)._sfint32];
335 _polys[pi]._attrib.set_normal(d);
339 if (normal_list.size() != _polys.size()) {
340 cerr <<
"Wrong number of normals!\n";
343 for (
size_t pi = 0; pi < normal_list.size(); pi++) {
344 const LNormald &d = normal_list[pi];
345 _polys[pi]._attrib.set_normal(d);
360 void IndexedFaceSet::
361 assign_per_vertex_normals() {
362 for (
size_t pi = 0; pi < _polys.size(); pi++) {
363 for (
size_t pv = 0; pv < _polys[pi]._verts.size(); pv++) {
364 VrmlVertex &vv = _polys[pi]._verts[pv];
365 if (vv._index >= 0 && vv._index < (
int)_per_vertex_normals.size()) {
366 const LNormald &d = _per_vertex_normals[vv._index];
367 vv._attrib.set_normal(d);
377 bool IndexedFaceSet::
379 const VrmlNode *texCoord = _geometry->get_value(
"texCoord")._sfnode._p;
380 if (texCoord !=
nullptr) {
383 get_vrml_uvs(texCoord, uv_list);
385 MFArray *texCoordIndex = _geometry->get_value(
"texCoordIndex")._mf;
386 MFArray::const_iterator ci;
388 if (texCoordIndex->empty()) {
392 for (
size_t i = 0; i < uv_list.size(); i++) {
395 (*texCoordIndex).push_back(fv);
404 bool linear_list = (texCoordIndex->size() == _coord_values.size());
405 for (ci = texCoordIndex->begin();
406 ci != texCoordIndex->end() && linear_list;
408 linear_list = ((*ci)._sfint32 >= 0);
415 _per_vertex_uvs.reserve(_coord_values.size());
417 for (ci = texCoordIndex->begin(); ci != texCoordIndex->end(); ++ci) {
418 size_t vi = (*ci)._sfint32;
419 nassertr(vi >= 0,
false);
420 if (vi >= uv_list.size()) {
421 cerr <<
"Invalid texCoord index: " << vi <<
"\n";
424 _per_vertex_uvs.push_back(uv_list[vi]);
426 nassertr(_per_vertex_uvs.size() == _coord_values.size(),
false);
436 for (ci = texCoordIndex->begin(); ci != texCoordIndex->end(); ++ci) {
437 if ((*ci)._sfint32 < 0) {
439 if (pv != _polys[pi]._verts.size()) {
440 cerr <<
"texCoord indices don't match up!\n";
446 if (pi >= _polys.size() || pv >= _polys[pi]._verts.size()) {
447 cerr <<
"texCoord indices don't match up!\n";
450 _polys[pi]._verts[pv]._attrib.set_uv(uv_list[(*ci)._sfint32]);
454 if (pi != _polys.size()) {
455 cerr <<
"Not enough texCoord indices!\n";
469 void IndexedFaceSet::
470 assign_per_vertex_uvs() {
471 for (
size_t pi = 0; pi < _polys.size(); pi++) {
472 for (
size_t pv = 0; pv < _polys[pi]._verts.size(); pv++) {
473 VrmlVertex &vv = _polys[pi]._verts[pv];
474 if (vv._index >= 0 && vv._index < (
int)_per_vertex_uvs.size()) {
475 const LTexCoordd &d = _per_vertex_uvs[vv._index];
476 vv._attrib.set_uv(d);
486 void IndexedFaceSet::
488 const LMatrix4d &net_transform) {
489 bool ccw = _geometry->get_value(
"ccw")._sfbool;
490 bool solid = _geometry->get_value(
"solid")._sfbool;
492 for (
size_t pi = 0; pi < _polys.size(); pi++) {
497 if (!poly->has_color() && _appearance._has_material) {
498 poly->set_color(_appearance._color);
501 if (_appearance._tex !=
nullptr) {
511 for (
int pv = 0; pv < (int)_polys[pi]._verts.size(); pv++) {
512 EggVertex vert(_polys[pi]._verts[pv]._attrib);
514 _polys[pi]._verts[pv]._pos * net_transform;
521 for (
int pv = (
int)_polys[pi]._verts.size() - 1; pv >= 0; pv--) {
522 EggVertex vert(_polys[pi]._verts[pv]._attrib);
524 _polys[pi]._verts[pv]._pos * net_transform;
537 void IndexedFaceSet::
539 const VrmlNode *normal = _geometry->get_value(
"normal")._sfnode._p;
540 if (normal ==
nullptr) {
542 double creaseAngle = _geometry->get_value(
"creaseAngle")._sffloat;
543 if (creaseAngle == 0.0) {
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_texture(EggTexture *texture)
Replaces the current list of textures with the indicated texture.
set_bface_flag
Sets the backfacing flag of the polygon.
void copy_attributes(const EggAttributes &other)
Copies the rendering attributes from the indicated primitive.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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...