<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "https://www.web3d.org/specifications/x3d-3.0.dtd">
<X3D profile='Immersive'  version='3.0 xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation =' https://www.web3d.org/specifications/x3d-3.0.xsd ' >
<head>
<meta name='titlecontent=' RenderingComponentPrototypes.x3d '/>
<meta name='descriptioncontent='Prototype implementations of X3D Rendering component nodes (IndexedTriangleFanSet IndexedTriangleSet IndexedTriangleStripSet LineSet TriangleFanSet TriangleSet TriangleStripSet) implemented as prototypes for backwards compatibility with VRML 97.'/>
<meta name='infocontent='X3dToVrml97.xslt translation stylesheet automatically invokes these prototypes upon encountering any new Rendering nodes.'/>
<meta name='creatorcontent='Don Brutzman, George Dabrowski, Ken Curtin, Duane Davis, Christos Kalogrias'/>
<meta name='createdcontent='17 November 2003'/>
<meta name='modifiedcontent='9 October 2023'/>
<meta name='referencecontent=' RenderingComponentExamples.x3d '/>
<meta name='referencecontent=' RenderingComponentExternProtoDefinitions.x3d '/>
<meta name='referencecontent=' https://www.web3d.org/specifications/X3Dv4/ISO-IEC19775-1v4-IS/Part01/components/rendering.html '/>
<meta name='referencecontent=' https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Chapter13-PointsLinesFaces/Figure13.11IndexedLineSetBoxWireframe.x3d '/>
<meta name='subjectcontent='X3D Rendering component nodes (IndexedTriangleFanSet IndexedTriangleSet IndexedTriangleStripSet LineSet TriangleFanSet TriangleSet TriangleStripSet)'/>
<meta name='identifiercontent=' https://www.web3d.org/x3d/content/examples/Basic/development/RenderingComponentPrototypes.x3d '/>
<meta name='generatorcontent='X3D-Edit 4.0, https://savage.nps.edu/X3D-Edit'/>
<meta name='licensecontent=' ../license.html'/>
</head>
<!-- -->
<Scene>
<!-- ==================== -->
<WorldInfo title='RenderingComponentPrototypes.x3d'/>
<ProtoDeclare name='ColorRGBAappinfo='ColorRGBA defines a set of RGBA colors. Warning: VRML 97 support does not include alpha values.' >
<ProtoInterface>
<field name='colortype='MFRotationaccessType='inputOutput'
 appinfo='locally override MFColorRGBA type (which is not supported in VRML 97) in order to downgrade to Color RGB' >
<!-- The color field is a 4-tuple float array, and so we map it to an MFOrientation for backwards compatibility with VRML 97. -->
</field>
<field name='metadatatype='SFNodeaccessType='inputOutput'
 appinfo='Metadata node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
</ProtoInterface>
<ProtoBody>
<Color DEF='ColorRGBcolor='0.8 0.8 0.8'/>
<!-- remaining nodes are not rendered -->
<OrientationInterpolator DEF='ColorRGBAholder'>
<IS>
<connect nodeField='keyValueprotoField='color'/>
</IS>
</OrientationInterpolator>
<Script DEF='ConvertColorRGBAtoRGBdirectOutput='true'>
<field name='colorRGBAnodetype='SFNodeaccessType='initializeOnly'>
<OrientationInterpolator USE=' ColorRGBAholder'/>
</field>
<field name='colorRGBnodetype='SFNodeaccessType='initializeOnly'>
<Color USE=' ColorRGB'/>
</field>
<![CDATA[
          
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;
	}
}

        
]]>
</Script>
<Group>
<MetadataSet>
<IS>
<connect nodeField='metadataprotoField='metadata'/>
</IS>
</MetadataSet>
</Group>
</ProtoBody>
</ProtoDeclare>
<!-- ==================== -->
<ProtoDeclare name='IndexedTriangleFanSetappinfo='IndexedTriangleFanSet represents a 3D shape composed of triangles that form a fan shape around the first vertex declared in each fan.' >
<ProtoInterface>
<field name='ccwtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='colorPerVertextype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='normalPerVertextype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='solidtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='set_indextype='MFInt32accessType='inputOnly'
 appinfo='[0 infinity] or -1' />

<field name='indextype='MFInt32accessType='initializeOnly'
 appinfo='[0 infinity] or -1' >
<!-- default initialization is NULL array [] to match X3D specification -->
</field>
<field name='colortype='SFNodeaccessType='inputOutput'
 appinfo='Color ColorRGBA node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='coordtype='SFNodeaccessType='inputOutput'
 appinfo='Coordinate node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='metadatatype='SFNodeaccessType='inputOutput'
 appinfo='Metadata node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='normaltype='SFNodeaccessType='inputOutput'
 appinfo='Normal node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='texCoordtype='SFNodeaccessType='inputOutput'
 appinfo='TextureCoordinate node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
</ProtoInterface>
<ProtoBody>
<IndexedFaceSet DEF='RenderedITFS'>
<IS>
<connect nodeField='ccwprotoField='ccw'/>
<connect nodeField='normalPerVertexprotoField='normalPerVertex'/>
<connect nodeField='solidprotoField='solid'/>
<connect nodeField='colorprotoField='color'/>
<connect nodeField='coordprotoField='coord'/>
<connect nodeField='normalprotoField='normal'/>
<connect nodeField='texCoordprotoField='texCoord'/>
</IS>
</IndexedFaceSet>
<Group DEF='UnrenderedITFS'>
<Shape>
<!-- is this really needed at all?? -->
<IndexedFaceSet DEF='NodesHolderITFS'>
<IS>
<connect nodeField='colorprotoField='color'/>
<connect nodeField='coordprotoField='coord'/>
<connect nodeField='normalprotoField='normal'/>
<connect nodeField='texCoordprotoField='texCoord'/>
</IS>
</IndexedFaceSet>
</Shape>
<Script DEF='IndexedTriangleFanSetToIndexedFaceSetdirectOutput='true'>
<field name='indextype='MFInt32accessType='initializeOnly'/>
<field name='set_indextype='MFInt32accessType='inputOnly'/>
<field name='renderedITFStype='SFNodeaccessType='initializeOnly'>
<IndexedFaceSet USE=' RenderedITFS'/>
</field>
<field name='nodesHoldertype='SFNodeaccessType='initializeOnly'>
<IndexedFaceSet USE=' NodesHolderITFS'/>
</field>
<field name='localTraceEnabledtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='coordIndexNewtype='MFInt32accessType='initializeOnly'>
<!-- constructed during initialization -->
</field>
<IS>
<connect nodeField='indexprotoField='index'/>
<connect nodeField='set_indexprotoField='set_index'/>
</IS>
<![CDATA[
            
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);
}

          
]]>
</Script>
<Group>
<MetadataString>
<IS>
<connect nodeField='metadataprotoField='metadata'/>
</IS>
</MetadataString>
</Group>
</Group>
</ProtoBody>
</ProtoDeclare>
<!-- ==================== -->
<ProtoDeclare name='IndexedTriangleSetappinfo='IndexedTriangleSet represents a 3D shape composed of a collection of individual triangles.' >
<ProtoInterface>
<field name='ccwtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='colorPerVertextype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='normalPerVertextype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='solidtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='set_indextype='MFInt32accessType='inputOnly'
 appinfo='[0 infinity] or -1' />

<field name='indextype='MFInt32accessType='initializeOnly'
 appinfo='[0 infinity] or -1' >
<!-- default initialization is NULL array [] to match X3D specification -->
</field>
<field name='colortype='SFNodeaccessType='inputOutput'
 appinfo='Color ColorRGBA node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='coordtype='SFNodeaccessType='inputOutput'
 appinfo='Coordinate node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='normaltype='SFNodeaccessType='inputOutput'
 appinfo='Normal node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='texCoordtype='SFNodeaccessType='inputOutput'
 appinfo='TextureCoordinate node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='metadatatype='SFNodeaccessType='inputOutput'
 appinfo='Metadata node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
</ProtoInterface>
<ProtoBody>
<IndexedFaceSet DEF='RenderedITS'>
<IS>
<connect nodeField='ccwprotoField='ccw'/>
<connect nodeField='normalPerVertexprotoField='normalPerVertex'/>
<connect nodeField='solidprotoField='solid'/>
<connect nodeField='colorprotoField='color'/>
<connect nodeField='coordprotoField='coord'/>
<connect nodeField='normalprotoField='normal'/>
<connect nodeField='texCoordprotoField='texCoord'/>
</IS>
</IndexedFaceSet>
<Group DEF='UnrenderedITS'>
<Shape>
<!-- is this really needed at all?? -->
<IndexedFaceSet DEF='NodesHolderITS'>
<IS>
<connect nodeField='colorprotoField='color'/>
<connect nodeField='coordprotoField='coord'/>
<connect nodeField='normalprotoField='normal'/>
<connect nodeField='texCoordprotoField='texCoord'/>
</IS>
</IndexedFaceSet>
</Shape>
<Script DEF='IndexedTriangleSetToIndexedFaceSetdirectOutput='true'>
<field name='indextype='MFInt32accessType='initializeOnly'/>
<field name='set_indextype='MFInt32accessType='inputOnly'/>
<field name='renderedITStype='SFNodeaccessType='initializeOnly'>
<IndexedFaceSet USE=' RenderedITS'/>
</field>
<field name='nodesHoldertype='SFNodeaccessType='initializeOnly'>
<IndexedFaceSet USE=' NodesHolderITS'/>
</field>
<field name='localTraceEnabledtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='coordIndexNewtype='MFInt32accessType='initializeOnly'>
<!-- constructed during initialization -->
</field>
<IS>
<connect nodeField='indexprotoField='index'/>
<connect nodeField='set_indexprotoField='set_index'/>
</IS>
<![CDATA[
            
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);
}

          
]]>
</Script>
<Group>
<MetadataString>
<IS>
<connect nodeField='metadataprotoField='metadata'/>
</IS>
</MetadataString>
</Group>
</Group>
</ProtoBody>
</ProtoDeclare>
<!-- ==================== -->
<ProtoDeclare name='IndexedTriangleStripSetappinfo='IndexedTriangleStripSet represents a 3D shape composed of strips of triangles.' >
<ProtoInterface>
<field name='ccwtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='colorPerVertextype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='normalPerVertextype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='solidtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='set_indextype='MFInt32accessType='inputOnly'/>
<field name='indextype='MFInt32accessType='initializeOnly'>
<!-- default initialization is NULL array [] to match X3D specification -->
</field>
<field name='colortype='SFNodeaccessType='inputOutput'
 appinfo='Color ColorRGBA node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='coordtype='SFNodeaccessType='inputOutput'
 appinfo='Coordinate node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='normaltype='SFNodeaccessType='inputOutput'
 appinfo='Normal node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='texCoordtype='SFNodeaccessType='inputOutput'
 appinfo='TextureCoordinate node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='metadatatype='SFNodeaccessType='inputOutput'
 appinfo='Metadata node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
</ProtoInterface>
<ProtoBody>
<IndexedFaceSet DEF='RenderedTSS'>
<IS>
<connect nodeField='ccwprotoField='ccw'/>
<connect nodeField='normalPerVertexprotoField='normalPerVertex'/>
<connect nodeField='solidprotoField='solid'/>
<connect nodeField='colorprotoField='color'/>
<connect nodeField='coordprotoField='coord'/>
<connect nodeField='normalprotoField='normal'/>
<connect nodeField='texCoordprotoField='texCoord'/>
</IS>
</IndexedFaceSet>
<Group>
<Shape>
<!-- is this really needed at all?? -->
<IndexedFaceSet DEF='NodesHolderTSS'>
<IS>
<connect nodeField='colorprotoField='color'/>
<connect nodeField='coordprotoField='coord'/>
<connect nodeField='normalprotoField='normal'/>
<connect nodeField='texCoordprotoField='texCoord'/>
</IS>
</IndexedFaceSet>
</Shape>
<Script DEF='IndexedTriangleStripSetToIndexedFaceSetdirectOutput='true'>
<field name='indextype='MFInt32accessType='initializeOnly'/>
<field name='set_indextype='MFInt32accessType='inputOnly'/>
<field name='renderedTSStype='SFNodeaccessType='initializeOnly'>
<IndexedFaceSet USE=' RenderedTSS'/>
</field>
<field name='nodesHoldertype='SFNodeaccessType='initializeOnly'>
<IndexedFaceSet USE=' NodesHolderTSS'/>
</field>
<field name='localTraceEnabledtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='coordIndexNewtype='MFInt32accessType='initializeOnly'>
<!-- constructed during initialization -->
</field>
<IS>
<connect nodeField='indexprotoField='index'/>
<connect nodeField='set_indexprotoField='set_index'/>
</IS>
<![CDATA[
            
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);
}

          
]]>
</Script>
<Group>
<MetadataString>
<IS>
<connect nodeField='metadataprotoField='metadata'/>
</IS>
</MetadataString>
</Group>
</Group>
</ProtoBody>
</ProtoDeclare>
<!-- ==================== -->
<ProtoDeclare name='LineSetappinfo='LineSet represents a 3D geometry formed by constructing polylines from 3D vertices.' >
<ProtoInterface>
<field name='vertexCounttype='MFInt32accessType='inputOutput'>
<!-- default initialization is NULL array [] to match X3D specification -->
</field>
<field name='colortype='SFNodeaccessType='inputOutput'
 appinfo='Color ColorRGBA node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='coordtype='SFNodeaccessType='inputOutput'
 appinfo='Coordinate node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='metadatatype='SFNodeaccessType='inputOutput'
 appinfo='Metadata node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
</ProtoInterface>
<ProtoBody>
<IndexedLineSet DEF='RenderedILS'>
<IS>
<connect nodeField='colorprotoField='color'/>
</IS>
</IndexedLineSet>
<Group>
<Shape>
<IndexedLineSet DEF='NodesHolderILS'>
<IS>
<connect nodeField='colorprotoField='color'/>
<connect nodeField='coordprotoField='coord'/>
</IS>
</IndexedLineSet>
<Appearance DEF='UnusedAppearance'>
<Material emissiveColor='0.8 0.8 0.8'/>
</Appearance>
</Shape>
<Script DEF='LineSetToIndexedLineSetdirectOutput='true'>
<field name='vertexCounttype='MFInt32accessType='inputOutput'>
<!-- default initialization is NULL array [] to match X3D specification -->
</field>
<field name='renderedILStype='SFNodeaccessType='initializeOnly'>
<IndexedLineSet USE=' RenderedILS'/>
</field>
<field name='nodesHoldertype='SFNodeaccessType='initializeOnly'>
<IndexedLineSet USE=' NodesHolderILS'/>
</field>
<field name='localTraceEnabledtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='coordIndexNewtype='MFInt32accessType='initializeOnly'>
<!-- constructed during initialization -->
</field>
<IS>
<connect nodeField='vertexCountprotoField='vertexCount'/>
</IS>
<![CDATA[
            
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);
}

          
]]>
</Script>
<Group>
<MetadataString>
<IS>
<connect nodeField='metadataprotoField='metadata'/>
</IS>
</MetadataString>
</Group>
</Group>
</ProtoBody>
</ProtoDeclare>
<!-- ==================== -->
<ProtoDeclare name='TriangleFanSetappinfo='TriangleFanSet represents a 3D shape composed of triangles that form a fan shape around the first vertex declared in each fan.' >
<ProtoInterface>
<field name='fanCounttype='MFInt32accessType='inputOutput'>
<!-- default initialization is NULL array [] to match X3D specification -->
</field>
<field name='ccwtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='colorPerVertextype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='normalPerVertextype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='solidtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='colortype='SFNodeaccessType='inputOutput'
 appinfo='Color ColorRGBA node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='coordtype='SFNodeaccessType='inputOutput'
 appinfo='Coordinate node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='normaltype='SFNodeaccessType='inputOutput'
 appinfo='Normal node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='texCoordtype='SFNodeaccessType='inputOutput'
 appinfo='TextureCoordinate node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='metadatatype='SFNodeaccessType='inputOutput'
 appinfo='Metadata node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
</ProtoInterface>
<ProtoBody>
<IndexedFaceSet DEF='RenderedTFS'>
<IS>
<connect nodeField='ccwprotoField='ccw'/>
<connect nodeField='colorPerVertexprotoField='colorPerVertex'/>
<connect nodeField='normalPerVertexprotoField='normalPerVertex'/>
<connect nodeField='solidprotoField='solid'/>
<connect nodeField='colorprotoField='color'/>
<connect nodeField='coordprotoField='coord'/>
<connect nodeField='normalprotoField='normal'/>
<connect nodeField='texCoordprotoField='texCoord'/>
</IS>
</IndexedFaceSet>
<Group DEF='UnrenderedTFS'>
<Shape>
<!-- is this really needed at all?? -->
<IndexedFaceSet DEF='NodesHolderTFS'>
<IS>
<connect nodeField='colorprotoField='color'/>
<connect nodeField='coordprotoField='coord'/>
<connect nodeField='normalprotoField='normal'/>
<connect nodeField='texCoordprotoField='texCoord'/>
</IS>
</IndexedFaceSet>
</Shape>
<Script DEF='TriangleFanSetToIndexedFaceSetdirectOutput='true'>
<field name='fanCounttype='MFInt32accessType='inputOutput'>
<!-- default initialization is NULL array [] to match X3D specification -->
</field>
<field name='renderedTFStype='SFNodeaccessType='initializeOnly'>
<IndexedFaceSet USE=' RenderedTFS'/>
</field>
<field name='nodesHoldertype='SFNodeaccessType='initializeOnly'>
<IndexedFaceSet USE=' NodesHolderTFS'/>
</field>
<field name='localTraceEnabledtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='coordIndexNewtype='MFInt32accessType='initializeOnly'>
<!-- constructed during initialization -->
</field>
<IS>
<connect nodeField='fanCountprotoField='fanCount'/>
</IS>
<![CDATA[
            
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);
}

          
]]>
</Script>
<Group>
<MetadataString>
<IS>
<connect nodeField='metadataprotoField='metadata'/>
</IS>
</MetadataString>
</Group>
</Group>
</ProtoBody>
</ProtoDeclare>
<!-- ==================== -->
<ProtoDeclare name='TriangleSetappinfo='TriangleSet represents a 3D shape that represents a collection of individual triangles.' >
<ProtoInterface>
<field name='ccwtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='colorPerVertextype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='normalPerVertextype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='solidtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='colortype='SFNodeaccessType='inputOutput'
 appinfo='Color ColorRGBA node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='coordtype='SFNodeaccessType='inputOutput'
 appinfo='Coordinate node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='normaltype='SFNodeaccessType='inputOutput'
 appinfo='Normal node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='texCoordtype='SFNodeaccessType='inputOutput'
 appinfo='TextureCoordinate node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='metadatatype='SFNodeaccessType='inputOutput'
 appinfo='Metadata node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
</ProtoInterface>
<ProtoBody>
<IndexedFaceSet DEF='RenderedTS'>
<IS>
<connect nodeField='ccwprotoField='ccw'/>
<connect nodeField='normalPerVertexprotoField='normalPerVertex'/>
<connect nodeField='solidprotoField='solid'/>
<connect nodeField='colorprotoField='color'/>
<connect nodeField='coordprotoField='coord'/>
<connect nodeField='normalprotoField='normal'/>
<connect nodeField='texCoordprotoField='texCoord'/>
</IS>
</IndexedFaceSet>
<Group DEF='UnrenderedTS'>
<Shape>
<!-- is this really needed at all?? -->
<IndexedFaceSet DEF='NodesHolderTS'>
<IS>
<connect nodeField='colorprotoField='color'/>
<connect nodeField='coordprotoField='coord'/>
<connect nodeField='normalprotoField='normal'/>
<connect nodeField='texCoordprotoField='texCoord'/>
</IS>
</IndexedFaceSet>
</Shape>
<Script DEF='TriangleSetToIndexedFaceSetdirectOutput='true'>
<field name='indextype='MFInt32accessType='initializeOnly'>
<!-- default initialization is NULL -->
</field>
<field name='set_indextype='MFInt32accessType='inputOnly'/>
<field name='renderedTStype='SFNodeaccessType='initializeOnly'>
<IndexedFaceSet USE=' RenderedTS'/>
</field>
<field name='nodesHoldertype='SFNodeaccessType='initializeOnly'>
<IndexedFaceSet USE=' NodesHolderTS'/>
</field>
<field name='localTraceEnabledtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='coordIndexNewtype='MFInt32accessType='initializeOnly'>
<!-- constructed during initialization -->
</field>
<![CDATA[
            
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);
}

          
]]>
</Script>
<Group>
<MetadataString>
<IS>
<connect nodeField='metadataprotoField='metadata'/>
</IS>
</MetadataString>
</Group>
</Group>
</ProtoBody>
</ProtoDeclare>
<!-- ==================== -->
<ProtoDeclare name='TriangleStripSetappinfo='TriangleStripSet represents a 3D shape composed of strips of triangles.' >
<ProtoInterface>
<field name='stripCounttype='MFInt32accessType='inputOutput'>
<!-- default initialization is NULL array [] to match X3D specification -->
</field>
<field name='ccwtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='colorPerVertextype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='normalPerVertextype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='solidtype='SFBoolvalue='trueaccessType='initializeOnly'/>
<field name='colortype='SFNodeaccessType='inputOutput'
 appinfo='Color ColorRGBA node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='coordtype='SFNodeaccessType='inputOutput'
 appinfo='Coordinate node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='normaltype='SFNodeaccessType='inputOutput'
 appinfo='Normal node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='texCoordtype='SFNodeaccessType='inputOutput'
 appinfo='TextureCoordinate node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
<field name='metadatatype='SFNodeaccessType='inputOutput'
 appinfo='Metadata node only' >
<!-- default initialization is NULL node to match X3D specification -->
</field>
</ProtoInterface>
<ProtoBody>
<IndexedFaceSet/>
</ProtoBody>
</ProtoDeclare>
<!-- ==================== -->
<!-- ProtoInstance examples are found in RenderingComponentExamples.x3d -->
<Background groundColor='0.2 0.2 0.2skyColor='0.2 0.2 0.2'/>
<Anchor DEF='LinkToExamplesdescription='link to examples'
  url=' 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" ' >
<Shape>
<Appearance>
<Material diffuseColor='1 1 1'/>
</Appearance>
<Text string='"RenderingComponentPrototypes" "is a developmental file." "Click this text to view" "RenderingComponentExamples"'>
<FontStyle justify='"MIDDLE" "MIDDLE"'/>
</Text>
</Shape>
<!-- Selectable Text has transparent Box and TouchSensor description as a tooltip -->
<Shape>
<Box size='12 5 .001'/>
<Appearance>
<Material transparency='0.8'/>
</Appearance>
</Shape>
</Anchor>
</Scene>
</X3D>
<!--

to top <!-- Event Graph ROUTE Table shows event connections -->
 
<!-- Index for DEF nodes: ColorRGB, ColorRGBAholder, ConvertColorRGBAtoRGB, IndexedTriangleFanSetToIndexedFaceSet, IndexedTriangleSetToIndexedFaceSet, IndexedTriangleStripSetToIndexedFaceSet, LineSetToIndexedLineSet, LinkToExamples, NodesHolderILS, NodesHolderITFS, NodesHolderITS, NodesHolderTFS, NodesHolderTS, NodesHolderTSS, RenderedILS, RenderedITFS, RenderedITS, RenderedTFS, RenderedTS, RenderedTSS, TriangleFanSetToIndexedFaceSet, TriangleSetToIndexedFaceSet, UnrenderedITFS, UnrenderedITS, UnrenderedTFS, UnrenderedTS, UnusedAppearance

Index for ProtoDeclare definitions: ColorRGBA, IndexedTriangleFanSet, IndexedTriangleSet, IndexedTriangleStripSet, LineSet, TriangleFanSet, TriangleSet, TriangleStripSet
-->

Event Graph ROUTE Table with 0 ROUTE total, showing X3D event-model relationships for this scene.

Each row shows an event cascade that may occur during a single timestamp interval between frame renderings, as part of the X3D execution model.

ConvertColorRGBAtoRGB
Script
No ROUTE connection found for output from this node.
Contains SFNode field with indirect access to another node. 


IndexedTriangleFanSetToIndexedFaceSet
Script
No ROUTE connection found for output from this node.
Contains SFNode field with indirect access to another node. 


IndexedTriangleSetToIndexedFaceSet
Script
No ROUTE connection found for output from this node.
Contains SFNode field with indirect access to another node. 


IndexedTriangleStripSetToIndexedFaceSet
Script
No ROUTE connection found for output from this node.
Contains SFNode field with indirect access to another node. 


LineSetToIndexedLineSet
Script
No ROUTE connection found for output from this node.
Contains SFNode field with indirect access to another node. 


TriangleFanSetToIndexedFaceSet
Script
No ROUTE connection found for output from this node.
Contains SFNode field with indirect access to another node. 


TriangleSetToIndexedFaceSet
Script
No ROUTE connection found for output from this node.
Contains SFNode field with indirect access to another node. 


-->

<!-- Online at
https://www.web3d.org/x3d/content/examples/Basic/development/RenderingComponentPrototypesIndex.html -->
<!-- Version control at
https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/content/examples/Basic/development/RenderingComponentPrototypes.x3d -->

<!-- Color legend: X3D terminology <X3dNode DEF='idName' field='value'/> matches XML terminology <XmlElement DEF='idName' attribute='value'/>
(Light-blue background: event-based behavior node or statement) (Grey background inside box: inserted documentation) (Magenta background: X3D Extensibility)
    <ProtoDeclare name='ProtoName'> <field name='fieldName'/> </ProtoDeclare> -->

to top <!-- For additional help information about X3D scenes, please see X3D Tooltips, X3D Resources, and X3D Scene Authoring Hints. -->