<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.2//EN" "https://www.web3d.org/specifications/x3d-3.2.dtd">
<X3D profile='Immersive' version='3.2' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-3.2.xsd'>
  <head>
    <meta content='RoomDirect.x3d' name='title'/>
    <meta content='X3D Follower example' name='description'/>
    <meta content='Herbert Stocker' name='creator'/>
    <meta content='Don Brutzman' name='translator'/>
    <meta content='18 April 2006' name='created'/>
    <meta content='2 December 2011' name='translated'/>
    <meta content='2 December 2024' name='modified'/>
    <meta content='originals/room-direct.wrl' name='reference'/>
    <meta content='Stocker_06_Followers.pdf' name='reference'/>
    <meta content='http://www.hersto.com/Publications/Followers' name='reference'/>
    <meta content='X3D version 3.2 or greater' name='requires'/>
    <meta content='X3D Follower Chaser Damper' name='subject'/>
    <meta content='https://www.web3d.org/x3d/specifications/ISO-IEC-19775-1.2-X3D-AbstractSpecification/Part01/components/followers.html' name='reference'/>
    <meta content='https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html' name='reference'/>
    <meta content='https://www.web3d.org/x3d/content/examples/Basic/Followers/RoomDirect.x3d' name='identifier'/>
    <meta content='Vrml97ToX3dNist, http://ovrt.nist.gov/v2_x3d.html' name='generator'/>
    <meta content='X3D-Edit 3.3, https://www.web3d.org/x3d/tools/X3D-Edit' name='generator'/>
    <meta content='../../license.html' name='license'/>
  </head>
  <Scene>
    <WorldInfo title='RoomDirect.x3d'/>
    <ExternProtoDeclare name='Selection' url='"originals/bitmanagement-nodes.x3d#Selection" "https://www.web3d.org/x3d/content/examples/Basic/Followers/originals/bitmanagement-nodes.x3d#Selection" "originals/bitmanagement-nodes.wrl#Selection" "https://www.web3d.org/x3d/content/examples/Basic/Followers/originals/bitmanagement-nodes.wrl#Selection"'>
      <!-- "urn:inet:blaxxun.com:node:Selection" -->
      <field accessType='inputOutput' name='select' type='SFBool'/>
      <field accessType='inputOnly' name='addChildren' type='MFNode'/>
      <field accessType='initializeOnly' name='bboxCenter' type='SFVec3f'/>
      <field accessType='inputOnly' name='removeChildren' type='MFNode'/>
      <field accessType='inputOutput' name='children' type='MFNode'/>
      <field accessType='initializeOnly' name='proxy' type='SFNode'/>
      <field accessType='initializeOnly' name='bboxSize' type='SFVec3f'/>
      <field accessType='inputOutput' name='collide' type='SFBool'/>
    </ExternProtoDeclare>
    <Background skyColor='0.1 0.2 0.3'/>
    <Viewpoint description='inside' fieldOfView='0.785' orientation='-1.0 -0.0 0.0 0.105' position='-0.0 1.7 7.985'/>
    <Viewpoint description='outside' fieldOfView='0.785' orientation='-1.0 0.0 0.0 0.105' position='0.0 2.068 13.879'/>
    <NavigationInfo avatarSize='0.25 1.2 0.75' headlight='false'/>
    <DirectionalLight intensity='0.5'/>
    <PointLight location='2.5 1.0 0.0' radius='20.0'/>
    <DirectionalLight direction='0.0 -1.0 0.0'/>
    <DirectionalLight intensity='0.5'/>
    <Group>
      <TouchSensor DEF='TouchFloor' description='Touch to move picture here'/>
      <Shape>
        <Appearance>
          <TextureTransform scale='17.0 17.0'/>
          <ImageTexture url='"floor.png" "https://www.web3d.org/x3d/content/examples/Basic/Followers/floor.png"'/>
        </Appearance>
        <Box size='10.0 0.1 10.0'/>
      </Shape>
    </Group>
    <Group>
      <TouchSensor DEF='TouchWallFront' description='Touch to move picture here'/>
      <Transform translation='0.0 1.5 -5.0'>
        <Shape DEF='ShWall'>
          <Appearance>
            <Material ambientIntensity='0.0567' diffuseColor='0.52 0.51 0.45' emissiveColor='0.28 0.27 0.24' shininess='0.53' specularColor='0.76 0.78 0.54'/>
          </Appearance>
          <Box size='10.0 3.0 0.1'/>
        </Shape>
      </Transform>
    </Group>
    <Group>
      <TouchSensor DEF='TouchWallLeft' description='Touch to move picture here'/>
      <Transform rotation='0.0 1.0 0.0 -1.571' translation='-5.0 1.5 0.0'>
        <Shape USE='ShWall'/>
      </Transform>
    </Group>
    <Group>
      <TouchSensor DEF='TouchWallRight' description='Touch to move picture here'/>
      <Transform rotation='0.0 1.0 0.0 1.571' translation='5.0 1.5 0.0'>
        <Shape USE='ShWall'/>
      </Transform>
    </Group>
    <Group>
      <TouchSensor DEF='TouchRoof' description='Touch to move picture here'/>
      <Transform translation='0.0 3.0 0.0'>
        <Shape>
          <Appearance>
            <Material ambientIntensity='0.0567' diffuseColor='0.522 0.451 0.447' emissiveColor='0.306 0.235 0.176' shininess='0.53' specularColor='0.761 0.541 0.584'/>
          </Appearance>
          <Box size='10.0 0.1 10.0'/>
        </Shape>
      </Transform>
    </Group>
    <ProtoInstance name='Selection'>
      <fieldValue name='select' value='false'/>
      <fieldValue name='children'>
        <Transform DEF='TransInd' scale='3.5 3.0 3.0'>
          <Transform scale='0.223 0.341 0.5'>
            <Shape>
              <Appearance>
                <ImageTexture url='"Photo.jpg" "https://www.web3d.org/x3d/content/examples/Basic/Followers/Photo.jpg"'/>
              </Appearance>
              <IndexedFaceSet coordIndex='0 1 2 3 -1 4 5 6 7 -1 4 0 3 7 -1 5 1 0 4 -1 6 2 1 5 -1 7 3 2 6 -1' solid='false' texCoordIndex='0 1 2 3 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1'>
                <TextureCoordinate DEF='SquareTextureCoordinatePoints' point='0 0 1 0 1 1 0 1'/>
                <Coordinate point='-1.0 -1.0 0.03 1.0 -1.0 0.03 1.0 1.0 0.03 -1.0 1.0 0.03 -1.0 -1.0 0.0 1.0 -1.0 0.0 1.0 1.0 0.0 -1.0 1.0 0.0'/>
              </IndexedFaceSet>
            </Shape>
            <Shape>
              <Appearance>
                <ImageTexture url='"Shadow.png" "https://www.web3d.org/x3d/content/examples/Basic/Followers/Shadow.png"'/>
                <Material diffuseColor='0.321569 0.713726 1'/>
              </Appearance>
              <IndexedFaceSet coordIndex='0 1 2 3 -1'>
                <TextureCoordinate USE='SquareTextureCoordinatePoints'/>
                <Coordinate point='-1.15 -1.15 0.01 1.15 -1.15 0.01 1.15 1.15 0.01 -1.15 1.15 0.01'/>
              </IndexedFaceSet>
            </Shape>
          </Transform>
        </Transform>
      </fieldValue>
    </ProtoInstance>
    <Script DEF='Worker'>
      <field accessType='inputOnly' name='set_hitPoint' type='SFVec3f'/>
      <field accessType='inputOnly' name='touchedWallLeft' type='SFTime'/>
      <field accessType='outputOnly' name='indPos' type='SFVec3f'/>
      <field accessType='inputOnly' name='touchedWallRight' type='SFTime'/>
      <field accessType='initializeOnly' name='cRoomDepth' type='SFFloat' value='9.9'/>
      <field accessType='initializeOnly' name='cPaintingWidth' type='SFFloat' value='1.561'/>
      <field accessType='initializeOnly' name='cFloorY' type='SFFloat' value='0.05'/>
      <field accessType='initializeOnly' name='cPaintingHeight' type='SFFloat' value='2.046'/>
      <field accessType='inputOnly' name='touchedWallFront' type='SFTime'/>
      <field accessType='inputOnly' name='touchedFloor' type='SFTime'/>
      <field accessType='inputOnly' name='touchedRoof' type='SFTime'/>
      <field accessType='outputOnly' name='indOri' type='SFRotation'/>
      <field accessType='initializeOnly' name='cRoomHeight' type='SFFloat' value='2.9'/>
      <field accessType='initializeOnly' name='cRoomWidth' type='SFFloat' value='9.9'/>
      <field accessType='initializeOnly' name='lastHitPoint' type='SFVec3f' value='0.0 0.0 0.0'/>
      <![CDATA[
ecmascript:

function set_hitPoint(hp)
{
    lastHitPoint= hp;
}

function touchedFloor(t)
{
    indPos= CheckGroundRoof(lastHitPoint);
    indOri= new SFRotation(-1, 0, 0, 1.571);
}

function touchedWallLeft(t)
{
    indPos= CheckLeftRightWall(CheckHeight(lastHitPoint));
    indOri= new SFRotation(0, 1, 0, 1.5705);
}

function touchedWallRight(t)
{
    indPos= CheckLeftRightWall(CheckHeight(lastHitPoint));
    indOri= new SFRotation(0, -1, 0, 1.5705);
}

function touchedWallFront(t)
{
    indPos= CheckFrontWall(CheckHeight(lastHitPoint));
    indOri= new SFRotation(0, 1, 0, 0);
}

function touchedRoof(t)
{
    indPos= CheckGroundRoof(lastHitPoint);
    indOri= (new SFRotation(1, 0, 0, 1.57));//.multiply(new SFRotation(0, 1, 0, 3.14159));
}

function CheckGroundRoof(pos)
{
return new SFVec3f( Limit(pos.x, -cRoomWidth/2 + cPaintingWidth/2, cRoomWidth/2 - cPaintingWidth/2)
                  , pos.y
                  , Limit(pos.z, -cRoomDepth/2 + cPaintingHeight/2, cRoomDepth/2 - cPaintingHeight/2)
                  );
}

function CheckHeight(pos)
{
return new SFVec3f( pos.x
                  , Limit(pos.y, cFloorY + cPaintingHeight/2, cFloorY + cRoomHeight - cPaintingHeight/2)
                  , pos.z
                  );
}

function CheckLeftRightWall(pos)
{
    return new SFVec3f( pos.x
                      , pos.y
                      , Limit(pos.z, -cRoomDepth/2 + cPaintingWidth/2, cRoomDepth/2 - cPaintingWidth/2)
                      );
}

function CheckFrontWall(pos)
{
    return new SFVec3f( Limit(pos.x, -cRoomWidth/2 + cPaintingWidth/2, cRoomWidth/2 - cPaintingWidth/2)
                      , pos.y
                      , pos.z
                      );
}
function Limit(x, min, max)
{
    return Min(Max(x, min), max);
}

function Max(a, b)
{
    return a > b? a:b;
}

function Min(a, b)
{
    return a > b? b:a;
}
]]>
    </Script>
    <ROUTE fromField='hitPoint_changed' fromNode='TouchFloor' toField='set_hitPoint' toNode='Worker'/>
    <ROUTE fromField='hitPoint_changed' fromNode='TouchWallLeft' toField='set_hitPoint' toNode='Worker'/>
    <ROUTE fromField='hitPoint_changed' fromNode='TouchWallRight' toField='set_hitPoint' toNode='Worker'/>
    <ROUTE fromField='hitPoint_changed' fromNode='TouchWallFront' toField='set_hitPoint' toNode='Worker'/>
    <ROUTE fromField='hitPoint_changed' fromNode='TouchRoof' toField='set_hitPoint' toNode='Worker'/>
    <ROUTE fromField='touchTime' fromNode='TouchFloor' toField='touchedFloor' toNode='Worker'/>
    <ROUTE fromField='touchTime' fromNode='TouchWallLeft' toField='touchedWallLeft' toNode='Worker'/>
    <ROUTE fromField='touchTime' fromNode='TouchWallRight' toField='touchedWallRight' toNode='Worker'/>
    <ROUTE fromField='touchTime' fromNode='TouchWallFront' toField='touchedWallFront' toNode='Worker'/>
    <ROUTE fromField='touchTime' fromNode='TouchRoof' toField='touchedRoof' toNode='Worker'/>
    <ROUTE fromField='indPos' fromNode='Worker' toField='translation' toNode='TransInd'/>
    <ROUTE fromField='indOri' fromNode='Worker' toField='rotation' toNode='TransInd'/>
  </Scene>
</X3D>