Skip to content
Snippets Groups Projects
MaterialChoiceExample.x3d 11.99 KiB
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "http://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='http://www.web3d.org/specifications/x3d-3.0.xsd'>
  <head>
    <meta content='MaterialChoiceExample.x3d' name='title'/>
    <meta content='Example for toggle-able Material node that can choose among an array of material nodes, and is switchable at run time.' name='description'/>
    <meta content='Don Brutzman and MV4205 class' name='creator'/>
    <meta content='2 May 2004' name='created'/>
    <meta content='28 November 2019' name='modified'/>
    <meta content='MaterialChoicePrototype.x3d' name='reference'/>
    <meta content='https://savage.nps.edu/Savage/Tools/Animation/MaterialChoiceExample.x3d' name='identifier'/>
    <meta content='X3D-Edit 3.2, https://savage.nps.edu/X3D-Edit' name='generator'/>
    <meta content='../../license.html' name='license'/>
  </head>
  <Scene>
    <WorldInfo title='MaterialChoiceExample.x3d'/>
    <ExternProtoDeclare name='MaterialChoice' url='"MaterialChoicePrototype.x3d#MaterialChoice" "https://savage.nps.edu/Savage/Tools/Animation/MaterialChoicePrototype.x3d#MaterialChoice" "MaterialChoicePrototype.wrl#MaterialChoice" "https://savage.nps.edu/Savage/Tools/Animation/MaterialChoicePrototype.wrl#MaterialChoice"'>
      <field accessType='inputOnly' name='set_index' type='SFInt32'/>
      <field accessType='initializeOnly' appinfo='which Material node is chosen, with array index starting at 0' name='index' type='SFInt32'/>
      <field accessType='outputOnly' name='index_changed' type='SFInt32'/>
      <field accessType='inputOnly' name='set_fraction' type='SFFloat'/>
      <field accessType='initializeOnly' appinfo='fraction to interpolate between current and next Material node (if any) across all field values.' name='fraction' type='SFFloat'/>
      <field accessType='inputOnly' name='next' type='SFBool'/>
      <field accessType='inputOnly' name='previous' type='SFBool'/>
      <field accessType='initializeOnly' appinfo='array of available Material nodes defaults to zeroth Material' name='materials' type='MFNode'/>
      <field accessType='inputOnly' appinfo='append another Material node to materials array' name='appendMaterial' type='SFNode'/>
      <field accessType='inputOnly' appinfo='delete Material node indicated by input index value' name='deleteMaterial' type='SFInt32'/>
      <field accessType='inputOnly' appinfo='deletes all Material nodes resets scene to default Material values defined in X3D Specification' name='deleteAllMaterials' type='SFBool'/>
    </ExternProtoDeclare>
    <!-- ==================== -->
    <Viewpoint description='MaterialChoice index is sequenced to change selected Material value' position='0 0 6'/>
    <Transform DEF='RotateBox' rotation='1 0 0 0.79'>
      <Transform rotation='0 1 0 0.79'>
        <Shape>
          <Box/>
          <Appearance>
            <ProtoInstance DEF='MC' containerField='material' name='MaterialChoice'>
              <fieldValue name='index' value='0'/>
              <fieldValue name='fraction' value='0.0'/>
              <fieldValue name='materials'>
                <Material ambientIntensity='0.24' diffuseColor='1 0.452381 0.40339' shininess='0.9' specularColor='0.686486 0.396903 0.419275'>
                  <!-- Universal Media Library: ArtDeco 3 -->
                </Material>
                <Material ambientIntensity='0.24' diffuseColor='0.330519 0.3389 0.6' shininess='0.78' specularColor='0.290909 0.290909 0.290909'>
                  <!-- Universal Media Library: ArtDeco 8 -->
                </Material>
                <Material ambientIntensity='0.25' diffuseColor='0 0.251004 0.239248' shininess='0.06' specularColor='0.177935 0.249369 0.229278'>
                  <!-- Universal Media Library: ArtDeco 19 -->
                </Material>
              </fieldValue>
            </ProtoInstance>
          </Appearance>
        </Shape>
      </Transform>
    </Transform>
    <!-- other tests -->
    <Group DEF='AnimationGroup'>
      <!-- Animate the MaterialChoice automatically -->
      <TimeSensor DEF='Clock' cycleInterval='2' enabled='false' loop='true'/>
      <BooleanTrigger DEF='TriggerNext'/>
      <ROUTE fromField='cycleTime' fromNode='Clock' toField='set_triggerTime' toNode='TriggerNext'/>
      <ROUTE fromField='triggerTrue' fromNode='TriggerNext' toField='next' toNode='MC'/>
      <!-- iff another action starts (i.e. touch true), then negate value and stop clock -->
      <BooleanFilter DEF='ClockStopper'/>
      <BooleanFilter DEF='ClockStopperFilter'/>
      <ROUTE fromField='inputTrue' fromNode='ClockStopper' toField='set_boolean' toNode='ClockStopperFilter'/>
      <ROUTE fromField='inputNegate' fromNode='ClockStopperFilter' toField='enabled' toNode='Clock'/>
    </Group>
    <Transform DEF='TestNext' translation='-2.5 2 0'>
      <Billboard axisOfRotation='0 0 0'>
        <Shape>
          <Text string='"next"'>
            <FontStyle DEF='FS' size='0.6'/>
          </Text>
          <Appearance>
            <Material diffuseColor='0 0.9 0'/>
          </Appearance>
        </Shape>
        <TouchSensor DEF='TouchNext' description='touch for next Material'/>
        <ROUTE fromField='isActive' fromNode='TouchNext' toField='set_boolean' toNode='ClockStopper'/>
        <ROUTE fromField='isActive' fromNode='TouchNext' toField='next' toNode='MC'/>
      </Billboard>
    </Transform>
    <Transform DEF='TestPrevious' translation='1 2 0'>
      <Billboard axisOfRotation='0 0 0'>
        <Shape>
          <Text string='"previous"'>
            <FontStyle USE='FS'/>
          </Text>
          <Appearance>
            <Material diffuseColor='0.9 0 0'/>
          </Appearance>
        </Shape>
        <TouchSensor DEF='TouchPrevious' description='touch for previous Material'/>
        <ROUTE fromField='isActive' fromNode='TouchPrevious' toField='set_boolean' toNode='ClockStopper'/>
        <ROUTE fromField='isActive' fromNode='TouchPrevious' toField='previous' toNode='MC'/>
      </Billboard>
    </Transform>
    <Transform DEF='TestLoop' translation='-3 -2 0'>
      <Billboard axisOfRotation='0 0 0'>
        <Shape>
          <Text string='"loop"'>
            <FontStyle USE='FS'/>
          </Text>
          <Appearance>
            <Material diffuseColor='0 0 0.9'/>
          </Appearance>
        </Shape>
        <TouchSensor DEF='TouchLoop' description='touch to loop through Materials'/>
        <BooleanToggle DEF='ToggleLoop'/>
        <ROUTE fromField='isActive' fromNode='TouchLoop' toField='set_boolean' toNode='ToggleLoop'/>
        <ROUTE fromField='toggle_changed' fromNode='ToggleLoop' toField='enabled' toNode='Clock'/>
      </Billboard>
    </Transform>
    <Transform DEF='TestAppend' translation='1 -2 0'>
      <Billboard axisOfRotation='0 0 0'>
        <Shape>
          <Text string='"append"'>
            <FontStyle USE='FS'/>
          </Text>
          <Appearance>
            <Material diffuseColor='0.6 0.6 0'/>
          </Appearance>
        </Shape>
        <TouchSensor DEF='TouchAppend' description='touch to add a new Material'/>
        <Script DEF='AddNewMaterialScript' directOutput='true'>
          <field accessType='inputOnly' name='generateAndAppendMaterial' type='SFBool'/>
          <field accessType='outputOnly' name='newMaterial' type='SFNode'/>
          <field accessType='initializeOnly' name='defaultMaterial' type='SFNode'>
            <Material/>
          </field>
          <field accessType='initializeOnly' name='traceEnabled' type='SFBool' value='false'/>
          <![CDATA[
ecmascript:

function initialize ()
{
	if (traceEnabled) Browser.print ('[ MaterialChoiceExample ] AddNewMaterialScript.initialize()');
}
function generateAndAppendMaterial(trigger, timestamp)
{
   if (trigger == true)
   {
	if (traceEnabled) Browser.print ('[MaterialChoiceExample AddNewMaterialScript] generateAndAppendMaterial(' + trigger + ')');
	newColor = new SFColor (Math.random(), Math.random(), Math.random());
	defaultMaterial.diffuseColor = newColor;
	newMaterial = defaultMaterial;
	if (traceEnabled) Browser.print ('[ MaterialChoiceExample AddNewMaterialScript] append Material with diffuseColor (' + newColor + ')');
   }
}
]]>
        </Script>
        <ROUTE fromField='isActive' fromNode='TouchAppend' toField='set_boolean' toNode='ClockStopper'/>
        <ROUTE fromField='isActive' fromNode='TouchAppend' toField='generateAndAppendMaterial' toNode='AddNewMaterialScript'/>
        <ROUTE fromField='newMaterial' fromNode='AddNewMaterialScript' toField='appendMaterial' toNode='MC'/>
      </Billboard>
    </Transform>
    <Transform DEF='TestDeleteOne' translation='-3 0 0'>
      <Transform>
        <Billboard axisOfRotation='0 0 0'>
          <Shape>
            <Text string='"delete"'>
              <FontStyle USE='FS'/>
            </Text>
            <Appearance>
              <Material/>
            </Appearance>
          </Shape>
        </Billboard>
      </Transform>
      <Transform DEF='TestDelete0' translation='0 -0.5 0'>
        <Billboard axisOfRotation='0 0 0'>
          <Shape>
            <Text string='"0"'>
              <FontStyle USE='FS'/>
            </Text>
            <Appearance>
              <Material/>
            </Appearance>
          </Shape>
        </Billboard>
        <TouchSensor DEF='TouchDelete0' description='touch to delete Material[0]'/>
        <IntegerTrigger DEF='TouchDelete0Trigger' integerKey='0'/>
        <ROUTE fromField='isActive' fromNode='TouchDelete0' toField='set_boolean' toNode='ClockStopper'/>
        <ROUTE fromField='isActive' fromNode='TouchDelete0' toField='set_boolean' toNode='TouchDelete0Trigger'/>
        <ROUTE fromField='triggerValue' fromNode='TouchDelete0Trigger' toField='deleteMaterial' toNode='MC'/>
      </Transform>
      <Transform DEF='TestDelete1' translation='0.5 -0.5 0'>
        <Billboard axisOfRotation='0 0 0'>
          <Shape>
            <Text string='"1"'>
              <FontStyle USE='FS'/>
            </Text>
            <Appearance>
              <Material/>
            </Appearance>
          </Shape>
        </Billboard>
        <TouchSensor DEF='TouchDelete2' description='touch to delete Material[1]'/>
        <IntegerTrigger DEF='TouchDelete2Trigger' integerKey='1'/>
        <ROUTE fromField='isActive' fromNode='TouchDelete2' toField='set_boolean' toNode='ClockStopper'/>
        <ROUTE fromField='isActive' fromNode='TouchDelete2' toField='set_boolean' toNode='TouchDelete2Trigger'/>
        <ROUTE fromField='triggerValue' fromNode='TouchDelete2Trigger' toField='deleteMaterial' toNode='MC'/>
      </Transform>
      <Transform DEF='TestDelete2' translation='1 -0.5 0'>
        <Billboard axisOfRotation='0 0 0'>
          <Shape>
            <Text string='"2"'>
              <FontStyle USE='FS'/>
            </Text>
            <Appearance>
              <Material/>
            </Appearance>
          </Shape>
        </Billboard>
        <TouchSensor DEF='TouchDelete1' description='touch to delete Material[2]'/>
        <IntegerTrigger DEF='TouchDelete1Trigger' integerKey='1'/>
        <ROUTE fromField='isActive' fromNode='TouchDelete1' toField='set_boolean' toNode='ClockStopper'/>
        <ROUTE fromField='isActive' fromNode='TouchDelete1' toField='set_boolean' toNode='TouchDelete1Trigger'/>
        <ROUTE fromField='triggerValue' fromNode='TouchDelete1Trigger' toField='deleteMaterial' toNode='MC'/>
      </Transform>
    </Transform>
    <Transform DEF='TestDeleteAll' translation='1.8 0 0'>
      <Billboard axisOfRotation='0 0 0'>
        <Shape>
          <Text string='"delete" " all"'>
            <FontStyle USE='FS'/>
          </Text>
          <Appearance>
            <Material/>
          </Appearance>
        </Shape>
        <TouchSensor DEF='TouchDeleteAll' description='touch to delete all Materials'/>
        <ROUTE fromField='isActive' fromNode='TouchDeleteAll' toField='set_boolean' toNode='ClockStopper'/>
        <ROUTE fromField='isActive' fromNode='TouchDeleteAll' toField='deleteAllMaterials' toNode='MC'/>
      </Billboard>
    </Transform>
  </Scene>
</X3D>