[x3d-public] Proposal: expressions

Yves Piguet yves.piguet at gmail.com
Mon Sep 12 14:22:51 PDT 2016


On 12 sept. 2016, at 19:26, Joe D Williams wrote:

> Can you compare these examples with how it would be done using the script node in the prototype instead of the 'simple' expression using inline maths?

I've added to the examples a version with Script nodes which should be compatible with X3D v3. I've also added explicit field names to the 3rd example.

Yves


Example 1: led with boolean state

1a. With expressions:

#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
}

1b. With a Script node:

#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
 inputOnly SFBool set_state
] {
 Shape {
   geometry Box {
     size IS size
   }
   appearance Appearance {
     material DEF mat Material {
       diffuseColor IS diffuseColor
     }
   }
 }
 Script {
   initializeOnly SFNode mat USE mat
   initializeOnly SFColor emissiveColor IS emissiveColor
   initializeOnly SFColor black 0 0 0
   initializeOnly SFBool state IS state
   inputOnly SFBool set_state IS set_state
   url "javascript:
     function setEmissiveColor() {
       mat.emissiveColor = state ? emissiveColor : black;
     }
     function initialize() {
       setEmissiveColor();
     }
     function set_state(s) {
       state = s;
       setEmissiveColor();
     }
   "
 }
}

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"

2a. With expressions:

#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
}

2b. With a Script node:

#X3D V3.3 utf8

PROTO Gauge [
 inputOutput SFFloat height 2
 inputOutput SFFloat radius 1
 inputOutput SFNode appearance1 NULL
 inputOutput SFNode appearance2 NULL
 initializeOnly SFFloat value 0.5
 inputOnly SFFloat set_value
] {
 Group {
   children [
     DEF t1 Transform {
       children Shape {
         geometry Cylinder {
           radius IS radius
         }
         appearance IS appearance1
       }
     }
     DEF t2 Transform {
       children Shape {
         geometry Cylinder {
           radius IS radius
         }
         appearance IS appearance2
       }
     }
   ]
 }
 Script {
   initializeOnly SFNode t1 USE t1
   initializeOnly SFNode t2 USE t2
   initializeOnly SFFloat height IS height
   initializeOnly SFFloat value IS value
   inputOnly SFFloat set_value IS set_value
   url "javascript:
     function setFields() {
       t1.translation = new SFVec3f(0, (1 - value) * height / 2, 0);
       cyl1.height = value * height;
       t2.translation = new SFVec3f(0, -value * height / 2, 0);
       cyl2.height = (1 - value) * height;
     }
     function initialize() {
       setFields();
     }
     function set_value(v) {
       value = v;
       setFields();
     }
   "
 }
}

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)

3a. With expressions:

#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
}

3b. With a Script node:

#X3D V3.3 utf8

PROTO TorsionShaft [
  initializeOnly SFFloat radius 1
  initializeOnly SFFloat height 2
  initializeOnly SFBool solid TRUE
  initializeOnly SFNode material NULL
  initializeOnly SFFloat textureScale 1
  initializeOnly SFFloat bottomRotation 0
  initializeOnly SFFloat topRotation 0
  inputOnly SFFloat set_bottomRotation
  inputOnly SFFloat set_topRotation
] {
  DEF transform Transform {
    children Shape {
      appearance Appearance {
        texture ImageTexture {
          url "texture:checkerboard"
        }
        textureTransform DEF texTransform TextureMatrixTransform {
          matrix 1 0 0 0 0 0 0 0 1
        }
        material IS material
      }
      geometry Cylinder {
        radius IS radius
        height IS height
        top FALSE
        bottom FALSE
        solid IS solid
      }
    }
  }
  Script {
    initializeOnly SFFloat sc IS textureScale
    initializeOnly SFFloat bottomRotation IS bottomRotation
    initializeOnly SFFloat topRotation IS topRotation
    inputOnly SFFloat set_bottomRotation IS set_bottomRotation
    inputOnly SFFloat set_topRotation IS set_topRotation
    initializeOnly SFNode transform USE transform
    initializeOnly SFNode texTransform USE texTransform
    url "javascript:
      function setTextureTransform() {
        transform.rotation = new SFRotation(0, 1, 0, bottomRotation);
        texTransform.matrix[0] = sc;
        texTransform.matrix[1] = sc * (bottomRotation - topRotation) / 2 / Math.PI;
      }
      function initialize() {
        setTextureTransform();
      }
      function set_bottomRotation(a) {
        bottomRotation = a;
        setTextureTransform();
      }
      function set_topRotation(a) {
        topRotation = a;
        setTextureTransform();
      }
    "
  }
}

TorsionShaft {
  textureScale 4
  bottomRotation 0.1
  topRotation 0.8
}




More information about the x3d-public mailing list