[x3d-public] Proposal: expressions

Yves Piguet yves.piguet at gmail.com
Mon Sep 12 02:36:40 PDT 2016


Hi,

In prototypes, there is often a need for simple expressions to set field values. For instance in a toggle switch, the most obvious type for its state is an SFBool which cannot be used directly to change the switch position (SFVec3f translation), angle (SFRotation orientation) or light (SFNode material). Likewise there is a Switch node where the active child is selected with an SFInt32, which provides a lot of flexibility but doesn't match directly the most frequent case, a boolean value. Currently, the only solution is scripts with node references (DEF/USE) or routes (DEF/ROUTE).

I suggest to add expressions as an intermediate possibility between scripts and direct IS references. I'll use the Classic notation.

Wherever "IS name" is permitted, the syntax "(expr)" stands for an expression which must be evaluated the first time the scene is rendered and when the values it refers to change.

For the syntax, instead of JavaScript which quickly becomes verbose with "Math." namespace and objects, I propose what follows. This should cover the intended applications.

Types:
- number, compatible with all X3D scalar numbers: SFFloat, SFInt32, SFTime...
- boolean
- string
- node (reference to X3D fields), including null
- 1D array (syntax: [a,b,c,...]; compatible with all array-like X3D types (SFVec3f, SFColor, SFMatrix3f etc.) and MF* (including MFBoolean, MFString and MFNode), flatten

Operators:
- arithmetic +-*/% ^ (power), +- also as prefix operators, + also for string concatenation
- comparison == != < > <= >=
- logical && ||
- conditional ?:
- same precedence as JS with parenthesized subexpressions

Functions:
- trig: sin cos tan asin acos atan atan2
- log: log log10 exp
- misc. math: abs round floor ceil sqrt
- logical: xor
- string: tbd (at least conversion from numbers with toFixed(x,n))

Values:
- literal numbers and strings with X3D syntax
- true false null (lowercase)
- prototype field names for initializeOnly and inputOutput

Example 1: led with boolean state:

#X3D V3.3 utf8

PROTO Led [
  inputOutput SFVec3f size 2 2 2
  inputOutput SFColor diffuseColor 0.2 0.2 0.2
  inputOutput SFColor emissiveColor 0 1 0
  inputOutput SFBool state FALSE
] {
  Shape {
    geometry Box {
      size IS size
    }
    appearance Appearance {
      material Material {
        diffuseColor IS diffuseColor
        emissiveColor (state ? emissiveColor : [0, 0, 0])
      }
    }
  }
}

Led {
  diffuseColor 0.3 0.1 0.1
  emissiveColor 1 0 0
  state TRUE
}

Example 2: gauge with two cylindric parts and a total height, where the ratio of the first part is specified with an SFFloat field "value":

#X3D V3.3 utf8

PROTO Gauge [
  inputOutput SFFloat height 2
  inputOutput SFFloat radius 1
  inputOutput SFNode appearance1 NULL
  inputOutput SFNode appearance2 NULL
  inputOutput SFFloat value 0.5
] {
  Group {
    children [
      Transform {
        translation ([0, (1 - value) * height / 2, 0])
        children Shape {
          geometry Cylinder {
            radius IS radius
            height (value * height)
          }
          appearance IS appearance1
        }
      }
      Transform {
        translation ([0, -value * height / 2, 0])
        children Shape {
          geometry Cylinder {
            radius IS radius
            height ((1 - value) * height)
          }
          appearance IS appearance2
        }
      }
    ]
  }
}

Gauge {
  appearance1 Appearance {
    material Material {
      diffuseColor 1 0 0
    }
  }
  appearance2 Appearance {
    material Material {
      diffuseColor 0 0.8 0
    }
  }
  value 0.7
}

Example 3: torsion shaft, a cylinder with different rotations for top and bottom with a texture which shows the torsion (requires a TextureMatrixTransform node with an arbitrary 2D SFMatrix3f transform matrix; url "texture:checkerboard" refers to a 2x2 checkerboard image)

#X3D V3.3 utf8

PROTO TorsionShaft [
  initializeOnly SFFloat radius 1
  inputOutput SFFloat height 2
  initializeOnly SFBool solid TRUE
  initializeOnly SFNode material NULL
  initializeOnly SFFloat textureScale 1
  inputOutput SFFloat bottomRotation 0
  inputOutput SFFloat topRotation 0
] {
  Transform {
    rotation ([0, 1, 0, bottomRotation])
    Shape {
      Appearance {
        ImageTexture {
          url "texture:checkerboard"
        }
        TextureMatrixTransform {
          matrix ([
            textureScale,
            textureScale * (bottomRotation - topRotation) / 2 / pi,
            0,
            0, 0, 0,
            0, 0, 1
          ])
        }
        material IS material
      }
      Cylinder {
        radius IS radius
        height IS height
        top FALSE
        bottom FALSE
        solid IS solid
      }
    }
  }
}

TorsionShaft {
  textureScale 4
  bottomRotation 0.1
  topRotation 0.8
}

All examples have been tested in our experimental implementation. I've attached snapshots for examples 2 and 3. Feedback welcome...

Yves

-------------- next part --------------
A non-text attachment was scrubbed...
Name: PastedGraphic-2.png
Type: image/png
Size: 6627 bytes
Desc: not available
URL: <http://web3d.org/pipermail/x3d-public_web3d.org/attachments/20160912/bdad0646/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PastedGraphic-1.png
Type: image/png
Size: 7113 bytes
Desc: not available
URL: <http://web3d.org/pipermail/x3d-public_web3d.org/attachments/20160912/bdad0646/attachment-0001.png>


More information about the x3d-public mailing list