2D and 3D transformation

### Common properties for `group` and `scene` objects  
  

- active (true): indicate if the object is active or not. An inactive object will not be refreshed nor rendered  
- x (0): horizontal translation  
- y (0): vertical translation  
- cx (0): horizontal coordinate of rotation center  
- cy (0): vertical coordinate of rotation center  
- units ('rel'): unit type for `x`, `y`, `cx`, `cy`, `width` and `height`. Possible values are:  

    - rel: units are expressed in percent of current reference (see below)  
    - pix: units are expressed in pixels  

- rotation (0): rotation angle of the scene in degrees  
- hscale (1): horizontal scaling factor to apply to the group  
- vscale (1): vertical skewing factor to apply to the scene  
- hskew (0): horizontal skewing factor to apply to the scene  
- vskew (0): vertical skewing factor to apply to the scene  
- zorder (0): display order of the scene or of the offscreen group (ignored for regular groups)  
- untransform (false): if true, reset parent tree matrix to identity before computing matrix  
- mxjs (null): JS code for matrix evaluation  
- z (0): depth translation  
- cz (0): depth coordinate of rotation center  
- zscale (1): depth scaling factor to apply to the group  
- orientation ([0, 0, 1, 0]): scale along the given orientation axis [x, y, z, angle] - see VRML `scaleOrientation`  
- axis ([0, 0, 1]): rotation axis  
- position ([0, 0, auto]): camera location  
- target ([0, 0, 0]): point where the camera is looking  
- up ([0, 1, 0]): camera up vector  
- viewport ([0, 0, 100, 100]): viewport for camera  
- fov (45): field of view in degrees  
- ar (0): camera aspect ratio, 0 means default  
- znear (0): near Z plane distance, 0 means default  
- zfar (0): far Z plane distance, 0 means default  

  
### Coordinate System  
  
Each group or scene is specified in a local coordinate system for which:  

- {0,0} represents the center  
- X values increase to the right  
- Y values increase to the top  
- Z values increase  towards the eye of a viewer (Z=X^Y)  

  
The 2D local transformation matrix is computed as `rotate(cx, cy, rotation)` * `hskew` * `vskew` * `scale(hscale, vscale)` * `translate(x, y)`.  
The 3D local transformation matrix is computed as `translate(x, y, z)` * `rotate(cx, cy, cz, rotation)` * `scale(hscale, vscale, zscale)`. Skewing is not supported for 3D.  
  
The default unit system (`rel`) is relative to the current established reference space:  

- by default, the reference space is `{output_width, output_height}`, the origin {0,0} being the center of the output frame   
- any group with `reference=true`, `width>0` and `height>0` establishes a new reference space `{group.width, group.height}`  

  
Inside a reference space `R`, relative coordinates are interpreted as follows:  

- For horizontal coordinates, 0 means center, -50 means left edge (`-R.width/2`), 50 means right edge (`+R.width/2`).  
- For vertical coordinates, 0 means center, -50 means bottom edge (`-R.height/2`), 50 means top edge (`+R.height/2`).  
- For `width`, 100 means `R.width`.  
- For `height`, 100 means `R.height`.  
- For depth (z and cz) coordinates, the value is a percent of the reference height (`+R.height`).  

  
If `width=height`, the width is set to the computed height of the object.  
If `height=width`, the height is set to the computed width of the object.  
For `x` property, the following special values are defined:  

- `y` will set the value to the computed `y`  of the object.  
- `-y` will set the value to the computed `-y` of the object.  

For `y` property, the following special values are defined:  

- `x` will set the value to the computed `x` of the object.  
- `-x` will set the value to the computed `-x` of the object.  

  
Changing reference is typically needed when creating offscreen groups, so that children relative coordinates are resolved against the offscreen canvas size.  
  
The selection between 2D and 3D is done automatically based on `z`, `cz`, `axis` and `orientation` values.  
The default projection is:  

- viewport is the entire output frame  
- field of view is PI/4 and aspect ratio is output width/height  
- zNear is 0.1 and zFar is 10 times maximum(output width, output height)  
- camera up direction is Y axis and camera distance is so that a rectangle facing the camera with `z=0` and size equal to output size covers exactly the output frame.  
- depth buffer is disabled  

  
The default projection can be changed by setting camera properties at group or scene level. When set on a group, all children of the group will use the given camera properties (camera parameters on children are ignored).  
The `viewport` parameter is specified as an array `[x, y, w, h]`, where:  

- x: horizontal coordinate of the viewport center, in group or scene units, or 'y' to use `y` value, or '-y' to use -`y` value.  
- y: vertical coordinate of the viewport center, in group or scene units, or 'x' to use `x` value, or '-x' to use -`x` value.  
- w: width of the viewport, in group or scene units, or 'height' to use `h` value.  
- h: height of the viewport, in group or scene units, or 'width' to use `w` value.  

  
### z-ordering  
  
`zorder` specifies the display order of the element in the offscreen canvas of the enclosing offscreen group, or on the output frame if no offscreen group in parent tree.  
This order is independent of the parent group z-ordering. This allows moving objects of a group up and down the display stack without modifying the groups.  
  
### Coordinate modifications through JS  
  
The `JSFun` specified in `mxjs` has a single parameter `tr`.  
  
The `tr` parameter is an object containing the following variables that the code can modify:  

- x, y, z, cx, cy, cz, hscale, vscale, zscale, hskew, vskew, rotation, untransform, axis, orientation: these values are initialized to the current group values in local coordinate system units  
- update: if set to true, the object matrix will be recomputed at each frame even if no change in the group or scene parameters (always enforced to true if `use` is set)  
- depth: for groups with `use`, indicates the recursion level of the used element. A value of 0 indicates this is a direct render of the element, otherwise it is a render through `use`  

  
The `JSFun` may return false to indicate that the scene should be considered as inactive. Any other return value (undefined or not false) will mark the scene as active.  
  
Example
```
"mxjs": "tr.rotation = (get_media_time() % 8) * 360 / 8; tr.update=true;"
```