Prototype implementations of X3D Rendering component nodes (IndexedTriangleFanSet IndexedTriangleSet IndexedTriangleStripSet LineSet TriangleFanSet TriangleSet TriangleStripSet) implemented as prototypes for backwards compatibility with VRML 97.
X3dToVrml97.xslt translation stylesheet automatically invokes these prototypes upon encountering any new Rendering nodes.
Don Brutzman, George Dabrowski, Ken Curtin, Duane Davis, Christos Kalogrias
X3D Rendering component nodes (IndexedTriangleFanSet IndexedTriangleSet IndexedTriangleStripSet LineSet TriangleFanSet TriangleSet TriangleStripSet)
X3D-Edit 4.0, https://www.web3d.org/x3d/tools/X3D-Edit
ColorRGBA defines a set of RGBA colors. Warning: VRML 97 support does not include alpha values.
locally override MFColorRGBA type (which is not supported in VRML 97) in order to downgrade to Color RGB
ecmascript: function initialize () { // Browser.println ('colorRGBAnode.keyValue.length=' + colorRGBAnode.keyValue.length); for (i=0; i<=colorRGBAnode.keyValue.length-1; i++) { // type conversion of each array element // specifically, colorRGBAnode.keyValue[i] is an SFRotation // and individual element values are then extracted from that nextColor = new SFColor ( colorRGBAnode.keyValue[i].x, colorRGBAnode.keyValue[i].y, colorRGBAnode.keyValue[i].z); // note colorRGBAnode.keyValue[i].angle holds the alpha value; ignored // Browser.println ('color[' + i + ']=' + nextColor); colorRGBnode.color[i] = nextColor; } }
IndexedTriangleFanSet represents a 3D shape composed of triangles that form a fan shape around the first vertex declared in each fan.
ecmascript: function initialize() { // index is an array of triangle indices that form a fan shape // around the first vertex declared in each fan. The ordering of // the vertices is ccw (counter-clockwise). // ensure terminated by -1 if (index[index.length-1] != -1) index[index.length] = -1; // ensure legal index values for (i=0; i <= index.length-1; i++) { if (index[i] < -1) { alwaysPrint ('error, index[' + i + ']=' + index[i] + ' is illegal value, treated as -1'); index[i] = -1; } } tracePrint ('index.length=' + index.length); tracePrint ('index=' + index); if (index.length < 4) { alwaysPrint ('warning, index.length=' + index.length + ' insufficient to construct a triangle, ITFS ignored'); return; } j = 0; // coordIndexNew counter coordIndexNew = new MFInt32 (); // i walks through index array, // goal is to initialize coordIndexNew list to match triangles for (i=2; i <= index.length-1; i++) { if ((index[i] == index[i-1]) || (index[i] == index[i-2]) || (index[i-1] == index[i-2])) { alwaysPrint ('index=' + index); alwaysPrint ('error, pair of equal indices in triangle'); return; } if (index[i] >= 0) { // add another triangle from latest 3 points of fan set to IFS // swap order to ensure normal is ccw, i.e. in correct halfplane direction coordIndexNew [coordIndexNew.length] = 0; coordIndexNew [coordIndexNew.length] = index[i]; coordIndexNew [coordIndexNew.length] = index[i-1]; coordIndexNew [coordIndexNew.length] = -1; // terminate } else if (index[i] == -1) // finish current triangle, fan { // ensure done, or sufficient points remain to build another triangle if ( (i!=index.length-1) && (index.length - i < 2)) { alwaysPrint ('index=' + index); alwaysPrint ('error, insufficient index values after' + 'index[' + i + ']=-1'); return; } // ensure done, or enough legal index values remain to build another triangle if ( (i!=index.length-1) && ((index[i+1] == -1) || (index[i+2] == -1) || (index[i+3] == -1))) { alwaysPrint ('index=' + index); alwaysPrint ('error, insufficient non-negative-one index values after' + 'index[' + i + ']=-1'); return; } tracePrint ('encountered -1 in index array'); // skip ahead to build next fan set, no effect if done if (i!=index.length-1) i = i + 2; } // incremental trace of array being built tracePrint ('coordIndexNew=' + coordIndexNew); } renderedITFS.set_coordIndex = coordIndexNew; tracePrint ('renderedITFS.coordIndex=' + renderedITFS.coordIndex); // match colorIndex if any Color node exists if (nodesHolder.color) { if (nodesHolder.color.color.length > 0) { renderedITFS.set_colorIndex = coordIndexNew; tracePrint ('set_colorIndex=' + coordIndexNew); } } } function set_index (value, timestamp) { index = value; initialize (); } function tracePrint(outputString) { if (localTraceEnabled) Browser.println ('[IndexedTriangleFanSet]' + outputString); } function alwaysPrint(outputString) { Browser.println ('[IndexedTriangleFanSet]' + outputString); }
IndexedTriangleSet represents a 3D shape composed of a collection of individual triangles.
ecmascript: function initialize() { // index is an array of triangle indices. The ordering of // the vertices is ccw (counter-clockwise). // ensure legal index values for (ii=0; ii <= index.length-1; ii++) { if (index[ii] < -1) { alwaysPrint ('error, index[' + ii + ']=' + index[ii] + ' is illegal value'); return; } } tracePrint ('index.length=' + index.length); tracePrint ('index=' + index); if (index.length < 3) { alwaysPrint ('warning, index.length=' + index.length + ' insufficient to construct a triangle, ITS ignored'); return; } coordIndexNew = new MFInt32 (); // ii walks through index array, // goal is to initialize coordIndexNew list to match triangles for (ii=0; ii <= index.length-1; ii+=3) { if ((index[ii] == index[ii+1]) || (index[ii] == index[ii+2]) || (index[ii+1] == index[ii+2])) { alwaysPrint ('index=' + index); alwaysPrint ('error, pair of equal indices in triangle'); return; } if (index[ii] >= 0) { // add another triangle from latest 3 points of fan set to ITS // order is ccw, i.e. in correct halfplane direction coordIndexNew [coordIndexNew.length] = index[ii]; coordIndexNew [coordIndexNew.length] = index[ii+1]; coordIndexNew [coordIndexNew.length] = index[ii+2]; coordIndexNew [coordIndexNew.length] = -1; } if (index.length % 3 != 0) { alwaysPrint ('error, index field does not contain a multiple' + 'of three coordinate values.'); alwaysPrint ('The remaining vertices shall be ignored'); return; } // ensure done, or sufficient points remain to build another triangle // if ( (i!=index.length-1) && (index.length - i < 2)) // { // alwaysPrint ('index=' + index); // alwaysPrint ('error, insufficient index values after' + // 'index[' + i + ']=-1'); // return; // } // ensure done, or enough legal index values remain to build another triangle // if ( (i!=index.length-1) && // ((index[i+1] == -1) || (index[i+2] == -1) || (index[i+3] == -1))) // { // alwaysPrint ('index=' + index); // alwaysPrint ('error, insufficient non-negative-one index values after' + // 'index[' + i + ']=-1'); // return; // } // incremental trace of array being built tracePrint ('coordIndexNew=' + coordIndexNew); } renderedITS.coordIndex = coordIndexNew; tracePrint ('renderedITS.coordIndex=' + renderedITS.coordIndex); // match colorIndex if any Color node exists if (nodesHolder.color) { if (nodesHolder.color.color.length > 0) { renderedITS.set_colorIndex = coordIndexNew; tracePrint ('set_colorIndex=' + coordIndexNew); } } } function set_index (value, timestamp) { index = value; initialize (); } function tracePrint(outputString) { if (localTraceEnabled) Browser.println ('[IndexedTriangleSet]' + outputString); } function alwaysPrint(outputString) { Browser.println ('[IndexedTriangleSet]' + outputString); }
IndexedTriangleStripSet represents a 3D shape composed of strips of triangles.
ecmascript: function initialize() { // index is an array of triangle indices. The ordering of // the vertices is ccw (counter-clockwise). // ensure legal index values for (ii=0; ii <= index.length-1; ii++) { if (index[ii] < -1) { alwaysPrint ('error, index[' + ii + ']=' + index[ii] + ' is illegal value'); return; } } tracePrint ('index.length=' + index.length); tracePrint ('index=' + index); if (index.length < 3) { alwaysPrint ('warning, index.length=' + index.length + ' insufficient to construct a triangle, ITS ignored'); return; } coordIndexNew = new MFInt32 (); // ii walks through index array, // goal is to initialize coordIndexNew list to match triangles for (ii=2; ii <= index.length-1; ii++) { if ((index[ii] == index[ii-1]) || (index[ii] == index[ii-2]) || (index[ii-1] == index[ii-2])) { alwaysPrint ('index=' + index); alwaysPrint ('error, pair of equal indices in triangle'); return; } if (index[ii] >= 0) { // add another triangle from latest 3 points of fan set to ITS // order is ccw, i.e. in correct halfplane direction coordIndexNew [coordIndexNew.length] = index[ii-2]; coordIndexNew [coordIndexNew.length] = index[ii-1]; coordIndexNew [coordIndexNew.length] = index[ii]; coordIndexNew [coordIndexNew.length] = -1; } // ensure done, or sufficient points remain to build another triangle // if ( (i!=index.length-1) && (index.length - i < 2)) // { // alwaysPrint ('index=' + index); // alwaysPrint ('error, insufficient index values after' + // 'index[' + i + ']=-1'); // return; // } // ensure done, or enough legal index values remain to build another triangle // if ( (i!=index.length-1) && // ((index[i+1] == -1) || (index[i+2] == -1) || (index[i+3] == -1))) // { // alwaysPrint ('index=' + index); // alwaysPrint ('error, insufficient non-negative-one index values after' + // 'index[' + i + ']=-1'); // return; // } // incremental trace of array being built tracePrint ('TSScoordIndexNew=' + coordIndexNew); } renderedTSS.set_coordIndex = coordIndexNew; tracePrint ('renderedTSS.coordIndex=' + renderedTSS.coordIndex); // match colorIndex if any Color node exists if (nodesHolder.color) { if (nodesHolder.color.color.length > 0) { renderedTSS.set_colorIndex = coordIndexNew; tracePrint ('set_colorIndex=' + coordIndexNew); } } } function set_index (value, timestamp) { index = value; initialize (); } function tracePrint(outputString) { if (localTraceEnabled) Browser.println ('[IndexedTriangleStripSet]' + outputString); } function alwaysPrint(outputString) { Browser.println ('[IndexedTriangleStripSet]' + outputString); }
LineSet represents a 3D geometry formed by constructing polylines from 3D vertices.
ecmascript: function initialize() { vertexCountSum = 0; tracePrint ('vertexCount=' + vertexCount); for (i=0; i < vertexCount.length; i++) { if (vertexCount[i] < 2) { alwaysPrint ('error, vertexCount[' + i + ']=' + vertexCount[i] + ' is illegal value, must be >= 2'); return; } vertexCountSum = vertexCountSum + vertexCountSum[i]; } tracePrint ('vertexCountSum=' + vertexCountSum); numberPoints = nodesHolder.coord.point.length; if (numberPoints < vertexCountSum) { alwaysPrint ('warning, Coordinate.point.length=' + numberPoints + ' is less than vertexCountSum=' + vertexCountSum + ', LS ignored'); return; } coordIndexNew = new MFInt32 (); numberSegments = vertexCountSum.length; // need validity check // i walks through array of points to build line-segment indices i = 0; for (seg=0; seg < numberSegments; seg++) { for (j=0; j < vertexCount[seg]; j++) { coordIndexNew [coordIndexNew.length] = i; i++; } coordIndexNew [coordIndexNew.length] = -1; // terminate current fan // incremental trace of array being built tracePrint ('coordIndexNew=' + coordIndexNew); } // repeat for all vertices renderedILS.coordIndex = coordIndexNew; tracePrint ('renderedILS.coordIndex=' + renderedILS.coordIndex); // match colorIndex if any Color node exists if (nodesHolder.color) { if (nodesHolder.color.color.length > 0) { renderedILS.colorIndex = coordIndexNew; tracePrint ('set_colorIndex=' + coordIndexNew); } } } function tracePrint(outputString) { if (localTraceEnabled) Browser.println ('[TriangleFanSet]' + outputString); } function alwaysPrint(outputString) { Browser.println ('[TriangleFanSet]' + outputString); }
TriangleFanSet represents a 3D shape composed of triangles that form a fan shape around the first vertex declared in each fan.
ecmascript: function initialize() { fanCountSum = 0; tracePrint ('fanCount=' + fanCount); for (i=0; i < fanCount.length; i++) { if (fanCount[i] < 3) { alwaysPrint ('error, fanCount[' + i + ']=' + fanCount[i] + ' is illegal value, must be >= 3'); return; } fanCountSum = fanCountSum + fanCount[i]; } tracePrint ('fanCountSum=' + fanCountSum); numberPoints = nodesHolder.coord.point.length; if (numberPoints < fanCountSum) { alwaysPrint ('warning, Coordinate.point.length=' + numberPoints + ' is less than fanCountSum=' + fanCountSum + ', TFS ignored'); return; } coordIndexNew = new MFInt32 (); numberFans = fanCount.length; // need validity check // i walks through array of points to build polygon indices i = 0; for (fan=0; fan < numberFans; fan++) { for (j=0; j < fanCount[fan]; j++) { coordIndexNew [coordIndexNew.length] = i; i++; } coordIndexNew [coordIndexNew.length] = -1; // terminate current fan // incremental trace of array being built tracePrint ('coordIndexNew=' + coordIndexNew); } // repeat for all fans renderedTFS.coordIndex = coordIndexNew; tracePrint ('renderedTFS.coordIndex=' + renderedTFS.coordIndex); // match colorIndex if any Color node exists if (nodesHolder.color) { if (nodesHolder.color.color.length > 0) { renderedTFS.set_colorIndex = coordIndexNew; tracePrint ('set_colorIndex=' + coordIndexNew); } } } function tracePrint(outputString) { if (localTraceEnabled) Browser.println ('[TriangleFanSet]' + outputString); } function alwaysPrint(outputString) { Browser.println ('[TriangleFanSet]' + outputString); }
TriangleSet represents a 3D shape that represents a collection of individual triangles.
ecmascript: function initialize() { // index is an array of triangle indices. The ordering of // the vertices is ccw (counter-clockwise). // ensure legal index values for (ii=0; ii <= index.length-1; ii++) { if (index[ii] < -1) { alwaysPrint ('error, index[' + ii + ']=' + index[ii] + ' is illegal value'); return; } } tracePrint ('index.length=' + index.length); tracePrint ('index=' + index); if (index.length < 3) { alwaysPrint ('warning, index.length=' + index.length + ' insufficient to construct a triangle, ITS ignored'); return; } coordIndexNew = new MFInt32 (); // ii walks through index array, // goal is to initialize coordIndexNew list to match triangles for (ii=0; ii <= index.length-1; ii+=3) { if ((index[ii] == index[ii+1]) || (index[ii] == index[ii+2]) || (index[ii+1] == index[ii+2])) { alwaysPrint ('index=' + index); alwaysPrint ('error, pair of equal indices in triangle'); return; } if (index[ii] >= 0) { // add another triangle from latest 3 points of fan set to ITS // order is ccw, i.e. in correct halfplane direction coordIndexNew [coordIndexNew.length] = index[ii]; coordIndexNew [coordIndexNew.length] = index[ii+1]; coordIndexNew [coordIndexNew.length] = index[ii+2]; coordIndexNew [coordIndexNew.length] = -1; } if (index.length % 3 != 0) { alwaysPrint ('error, index field does not contain a multiple' + 'of three coordinate values.'); alwaysPrint ('The remaining vertices shall be ignored'); return; } // ensure done, or sufficient points remain to build another triangle // if ( (i!=index.length-1) && (index.length - i < 2)) // { // alwaysPrint ('index=' + index); // alwaysPrint ('error, insufficient index values after' + // 'index[' + i + ']=-1'); // return; // } // ensure done, or enough legal index values remain to build another triangle // if ( (i!=index.length-1) && // ((index[i+1] == -1) || (index[i+2] == -1) || (index[i+3] == -1))) // { // alwaysPrint ('index=' + index); // alwaysPrint ('error, insufficient non-negative-one index values after' + // 'index[' + i + ']=-1'); // return; // } // incremental trace of array being built tracePrint ('coordIndexNew=' + coordIndexNew); } renderedITS.set_coordIndex = coordIndexNew; tracePrint ('renderedITS.coordIndex=' + renderedITS.coordIndex); // match colorIndex if any Color node exists if (nodesHolder.color) { if (nodesHolder.color.color.length > 0) { renderedITS.set_colorIndex = coordIndexNew; tracePrint ('set_colorIndex=' + coordIndexNew); } } } function set_index (value, timestamp) { index = value; initialize (); } function tracePrint(outputString) { if (localTraceEnabled) Browser.println ('[IndexedTriangleSet]' + outputString); } function alwaysPrint(outputString) { Browser.println ('[IndexedTriangleSet]' + outputString); }
TriangleStripSet represents a 3D shape composed of strips of triangles.
"RenderingComponentExamples.x3d" "https://www.web3d.org/x3d/content/examples/Basic/development/RenderingComponentExamples.x3d" "RenderingComponentExamples.wrl" "https://www.web3d.org/x3d/content/examples/Basic/development/RenderingComponentExamples.wrl"
"RenderingComponentPrototypes" "is a developmental file." "Click this text to view" "RenderingComponentExamples"