[x3d-public] Proposal: expressions
Joe D Williams
joedwil at earthlink.net
Mon Sep 12 10:26:12 PDT 2016
Hi Yves,
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? Also, can you show the rest of the user code that
declares and instances the proto and shows any routes?
I remember discussions of using an expression inline in a proto as you
show to avoid a script, and also even expressions in the main user
code to avoid some simple scripts and prototypes, and that this step
has never been seriously considered. Maybe your examples with proto
could help get some support from a second independent implementation.
Have you looked at how this would could work in the x3d in html
integration?
Thanks and Best,
Joe
----- Original Message -----
From: "Yves Piguet" <yves.piguet at gmail.com>
To: "X3D Graphics public mailing list" <x3d-public at web3d.org>
Sent: Monday, September 12, 2016 2:36 AM
Subject: [x3d-public] Proposal: expressions
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
--------------------------------------------------------------------------------
> _______________________________________________
> x3d-public mailing list
> x3d-public at web3d.org
> http://web3d.org/mailman/listinfo/x3d-public_web3d.org
>
More information about the x3d-public
mailing list