#VRML_SIM R2022b utf8
# license: Copyright Cyberbotics Ltd. Licensed for use only with Webots.
# license url: https://cyberbotics.com/webots_assets_license
# A customizable conveyor belt moving at a constant speed.
# template language: javascript

EXTERNPROTO "webots://projects/appearances/protos/CorrugatedMetal.proto"
EXTERNPROTO "webots://projects/appearances/protos/Rubber.proto"

PROTO ConveyorBelt [
  field SFVec3f    translation      0 0 0
  field SFRotation rotation         0 0 1 0
  field SFString   name             "conveyor belt"
  field SFString   window           "<none>"
  field SFVec3f    size             1.5 0.5 0.6
  field SFNode     appearance       CorrugatedMetal { textureTransform TextureTransform { scale 2 2 } }  # Defines the appearance of the conveyor belt.
  field SFFloat    borderThickness  0.03                                                                 # Defines the thickness of the metal part around the conveyor belt.
  field SFFloat    borderHeight     0.01                                                                 # Defines the height of the border around the conveyor.
  field SFFloat    speed            0.5                                                                  # Defines the rubber band speed in meters per second.
  field SFFloat    acceleration     -1                                                                   # Defines the acceleration of the conveyor belt.
  field SFFloat    timer            0.0                                                                  # Defines for how long the conveyor belt should move (it will move forever if set to 0).
]
{
  %<
    let size = fields.size.value;
    if (size.x <= 0.0 || size.y <= 0.0 || size.z <= 0.0) {
      size = fields.size.defaultValue;
      console.error('\'size\' should be strictly positive. Value reset to (' + size.x + ', ' + size.y + ', ' + size.z + ').');
    }

    let borderThickness = fields.borderThickness.value;
    if (borderThickness <= 0.0) {
      borderThickness = fields.borderThickness.defaultValue;
      console.error('\'borderThickness\' must be strictly positive. Value reset to ' + borderThickness + '.');
    }

    const borderHeight = fields.borderHeight.value;
  >%
  Robot {
    translation IS translation
    rotation IS rotation
    name IS name
    controller "conveyor_belt"
    controllerArgs [
      %<= '"' + fields.speed.value + '"' >%
      %<= '"' + fields.timer.value + '"' >%
    ]
    window IS window
    children [
      Track {
        translation 0 0 %<= 0.75 * size.z >%
        children [
          Shape {
            appearance Rubber {
              type "dotted"
              textureTransform TextureTransform {
                scale %<= 4.0 * size.x >% %<= 4.0 * size.y >%
              }
            }
            geometry DEF BELT_BO Box {
              size %<= size.x >% %<= size.y >% %<= 0.5 * size.z >%
            }
          }
        ]
        boundingObject USE BELT_BO
        physics Physics {
          density -1
          mass 1
        }
        device [
          LinearMotor {
            name "belt_motor"
            acceleration IS acceleration
            maxVelocity %<= Math.abs(fields.speed.value) >%
            sound ""
          }
        ]
        textureAnimation %<= 1 / size.x >% 0
      }
      Shape {
        appearance IS appearance
        geometry IndexedFaceSet {
          %<
            const xA = 0.5 * size.x;
            const xB = 0.5 * size.x + borderThickness;
            const yA = 0.5 * size.y;
            const yB = 0.5 * size.y + borderThickness;
            const zA = 0.0;
            const zB = size.z;
            const zC = size.z + borderHeight;
          >%
          coord Coordinate {
            point [
              %<= xB >% %<= -yB >% %<= zA >%
              %<= xB >% %<= -yB >% %<= zC >%
              %<= -xB >% %<= -yB >% %<= zC >%
              %<= -xB >% %<= -yB >% %<= zA >%
              %<= xB >% %<= yB >% %<= zA >%
              %<= xB >% %<= yB >% %<= zC >%
              %<= -xB >% %<= yB >% %<= zC >%
              %<= -xB >% %<= yB >% %<= zA >%
              %<= xA >% %<= -yA >% %<= zC >%
              %<= xA >% %<= yA >% %<= zC >%
              %<= -xA >% %<= yA >% %<= zC >%
              %<= -xA >% %<= -yA >% %<= zC >%
              %<= xA >% %<= -yA >% %<= zB >%
              %<= xA >% %<= yA >% %<= zB >%
              %<= -xA >% %<= yA >% %<= zB >%
              %<= -xA >% %<= -yA >% %<= zB >%
            ]
          }
          texCoord TextureCoordinate {
            point [
              0 0
              1 0
              1 1
              0 1
              0 %<= zC/xB >%
              1 %<= zC/xB >%
              0 %<= zC/xB >%
              %<= yB/xB >% %<= zC/xB >%
              %<= yB/xB >% 0
              0 0
              0.001 0
              0.001 0.001
              0 0.001
            ]
          }
          texCoordIndex [
            1 5 4 0 -1
            0 1 5 4 -1
            0 8 7 6 -1
            0 8 7 6 -1
            9 10 11 12 -1
            9 10 11 12 -1
            9 10 11 12 -1
            9 10 11 12 -1
            9 10 11 12 -1
            %< if (borderHeight > 0.0) { >%
              9 10 11 12 -1
              9 10 11 12 -1
              9 10 11 12 -1
              9 10 11 12 -1
            %< } >%
          ]
          coordIndex [
            0 1 2 3 -1
            4 7 6 5 -1
            0 4 5 1 -1
            7 3 2 6 -1
            1 5 9 8 -1
            5 6 10 9 -1
            6 2 11 10 -1
            2 1 8 11 -1
            0 3 7 4 -1
            %< if (borderHeight > 0.0) { >%
              8 9 13 12 -1
              9 10 14 13 -1
              10 11 15 14 -1
              11 8 12 15 -1
            %< } >%
          ]
        }
      }
    ]
    boundingObject Group {
      children [
        Transform {
          translation %<= 0.5 * (size.x + borderThickness) >% 0 %<= 0.5 * (size.z + borderHeight) >%
          children [
            Box {
              size %<= borderThickness >% %<= size.y + 2.0 * borderThickness >% %<= size.z + borderHeight >%
            }
          ]
        }
        Transform {
          translation %<= -0.5 * (size.x + borderThickness) >% 0 %<= 0.5 * (size.z + borderHeight) >%
          children [
            Box {
              size %<= borderThickness >% %<= size.y + 2.0 * borderThickness >% %<= size.z + borderHeight >%
            }
          ]
        }
        Transform {
          translation 0 %<= -0.5 * (size.y + borderThickness) >% %<= 0.5 * (size.z + borderHeight) >%
          children [
            Box {
              size %<= size.x >% %<= borderThickness >% %<= size.z + borderHeight >%
            }
          ]
        }
        Transform {
          translation 0 %<= 0.5 * (size.y + borderThickness) >% %<= 0.5 * (size.z + borderHeight) >%
          children [
            Box {
              size %<= size.x >% %<= borderThickness >% %<= size.z + borderHeight >%
            }
          ]
        }
      ]
    }
  }
}