TransformGizmo Control
User manual of the trinckle paramate GUI Controls API.
Introduction
The TransformGizmo control serves as a powerful tool for manipulating 3D objects, providing intuitive control over translation, rotation, and scaling. With its hierarchical structure capabilities, it goes beyond the standard gizmo functionality by allowing users to establish parent-child relationships between objects, enabling more complex transformations and object interactions.
Key Features
1. Translation
The TransformGizmo enables translation control of 3D objects along the X, Y, and Z axes. Users can interactively move objects in the desired direction by dragging the translation handles provided by the gizmo. The translation feature allows for accurate positioning of objects within the 3D space, facilitating spatial adjustments and precise alignment.
2. Rotation
With the TransformGizmo's rotation functionality, users can intuitively rotate 3D objects around any axis. The gizmo provides rotation handles that allow users to freely rotate objects or constrain rotations to specific axes. This feature is particularly useful for adjusting object orientations, aligning objects with specific angles, or creating dynamic rotations in animation scenarios.
3. Scale
The TransformGizmo's scaling feature empowers users to resize 3D objects uniformly or selectively along the X, Y, and Z axes. The gizmo offers scaling handles that enable proportional scaling or independent scaling on each axis. This feature is valuable for adjusting object dimensions, scaling objects relative to one another, or achieving precise size variations.
4. Parent-Child Relationship
By leveraging the TransformGizmo's hierarchical structure, users can create parent-child relationships between objects. This relationship defines a dependency where the child object inherits the transformations applied to its parent. Consequently, manipulating the parent object will automatically propagate the transformations to its child objects, maintaining the relative positioning and orientation.
Understanding Transformations for Using TransformGizmo Control
To effectively use the TransformGizmo control provided by the paramate GUI Controls API, understanding concepts such as transformation between coordinate systems, matrix transformations, and the relationship between model and world coordinate spaces is essential.
The TransformGizmo control allows users to intuitively manipulate 3D objects by providing translation, rotation, and scaling handles. By interacting with these handles, users can apply transformations to objects in the scene. Behind the scenes, the control performs the necessary matrix transformations to convert the object's local coordinates to the appropriate coordinate system and update its position, rotation, and scale accordingly.
Having an intuition for coordinate systems, matrix transformations, and the relationship between model and world coordinate spaces helps users understand how the TransformGizmo control operates and how their interactions with the control affect the object's placement and appearance within the 3D scene.
Transformation from One Coordinate System to Another
In computer graphics and 3D modeling, objects are positioned and manipulated using coordinate systems. A coordinate system consists of axes (X, Y, and Z) that define directions in 3D space. Transforming an object from one coordinate system to another involves changing its position, rotation, and scale relative to the new coordinate system.
General Principles of Matrix Transformation
Matrix transformations are mathematical operations used to perform transformations in computer graphics. These transformations include translation (moving an object), rotation (changing its orientation), and scaling (resizing). Matrix transformation involves applying a series of mathematical operations to the coordinates of an object's vertices to achieve the desired transformation.
The general principles of matrix transformations include:
Translation: Moving an object in 3D space involves adding or subtracting specific values from its coordinates. This is achieved by multiplying the object's vertex coordinates by a translation matrix.
Rotation: Rotating an object involves changing its orientation around one or more axes. Rotation can be performed using rotation matrices that define the rotation angle and the axis of rotation.
Scaling: Scaling involves changing the size of an object. It can be uniform (scaling equally in all directions) or non-uniform (scaling along different axes by different amounts). Scaling matrices are used to perform scaling transformations.
Transformation from Model to World Coordinate Space
In computer graphics, the model coordinate space represents the local coordinate system of an individual object. The model coordinate space defines the object's position, rotation, and scale relative to its local origin. To place objects within a scene, their model coordinate spaces must be transformed to the world coordinate space (global coordinate system).
The transformation from the model coordinate space to the world coordinate space involves multiplying the model's vertex coordinates by a model-to-world transformation matrix. This matrix combines the object's translation, rotation, and scaling transformations with respect to the world coordinate system.
Transformation from World to Model Coordinate Space
Conversely, transforming an object from the world coordinate space back to its model coordinate space is useful for object manipulation and editing. It involves applying the inverse transformation of the model-to-world transformation to the object's vertices.
To transform an object from the world to the model coordinate space, the world-to-model transformation matrix is used. This matrix represents the inverse of the model-to-world transformation and reverses the translation, rotation, and scaling applied in the model-to-world transformation.
Control Initialization
The TransformGizmo control can be initialized using the TransformGizmo constructor function. This function allows the initialization of TransformGizmo control with or without being bound to a paramate open parameter. When a paramate open parameter is specified, the control establishes a direct connection with the paramate server and enables real-time updates and interactions. For more information about these two types of initialization, see Controls Initialization.
The options object provides a range of settings for customizing the behavior and appearance of the TransformGizmo control. These settings include optional configuration parameters like the flag to change gizmo drawing relative to the local axis, size of the control's handles, step of rotation, minimum scaling value allowed, and possibility to hide the axes of translation, rotation, and scaling handles. In addition, the options object includes a necessary hasChildren parameter that defines whether a gizmo has child gizmo(s) or not.
For the detailed list of the options object's settings please consult TransformGizmo constructor function.
By default, the TransformGizmo control object is drawn in the world (global) system of coordinates. This means that rotating a solid with gizmo will rotatate the solid but not the gizmo itself. This behaviour can be changed statically by setting the parameter worldSpace of the options object to false.
Note
Scaling, unlike rotation, always takes place in the model (local) system of coordinates, and this behaviour cannot be changed.
Below is the example that initializes gizmo with default settings, without any children, and with open parameter string.
Example
const transformGizmo = new ParamateControls.TransformGizmo(viewport, controls, { hasChildren: false }, 'main:modelMatrix');
In trCAD, open parameter can be defined like this:
Example
matrix identityMatrix = <[
<[1.0, 0.0, 0.0, 0.0]>,
<[0.0, 1.0, 0.0, 0.0]>,
<[0.0, 0.0, 1.0, 0.0]>,
<[0.0, 0.0, 0.0, 1.0]>
]>
open matrix modelMatrix
{
name = "TransformGizmo model matrix."
descr = "TransformGizmo local transformation matrix."
value = identityMatrix
}
get (modelMatrix)
Example
const transformGizmo = new ParamateControls.TransformGizmo(
viewport,
controls,
{ hasChildren: false,
translateActiveZ: false,
rotateActiveZ: false,
scaleActiveZ: false },
'main:modelMatrix');
Example
const transformGizmoChild = new ParamateControls.TransformGizmo(
viewport,
controls,
{ hasChildren: false },
'main:modelMatrix',
'main:worldMatrix');
const transformGizmoParent = new ParamateControls.TransformGizmo(
viewport,
controls,
{ hasChildren: true },
'main:worldMatrix');
In trCAD, open parameters can be defined like this:
Example
matrix initModelMatrix = <[
<[1.0, 0.0, 0.0, 10.0]>,
<[0.0, 1.0, 0.0, 0.0]>,
<[0.0, 0.0, 1.0, 10.0]>,
<[0.0, 0.0, 0.0, 1.0]>
]>
matrix initWorldMatrix = <[
<[1.0, 0.0, 0.0, 5.0]>,
<[0.0, 1.0, 0.0, 0.0]>,
<[0.0, 0.0, 1.0, 5.0]>,
<[0.0, 0.0, 0.0, 1.0]>
]>
open matrix modelMatrix
{
name = "TransformGizmo model matrix."
descr = "TransformGizmo local transformation matrix."
value = initModelMatrix
}
get (modelMatrix)
open matrix worldMatrix
{
name = "TransformGizmo world matrix."
descr = "TransformGizmo global transformation matrix."
value = initWorldMatrix
}
get (worldMatrix)
In this example, the transformGizmoChild receives two open parameter strings: modelMatrix and worldMatrix. The transformGizmoParent receives one matrix - worldMatrix. This establishes parent-child relationship between these two TransformGizmo objects, and produces the following result:
Look and Feel Customization
To modify the various visual aspects of the controls, such as fillStyle, strokeStyle, fillText, font, lineWidth, and more, users can create custom styling presets using the following setters:
Each styling setter setups a list of styling presets confirming to the corresponding interface.
For example, to create a preset of styles for the gizmo point selector that would vary point fill- and stroke color, a user may create the following fillStyles setting object:
Example
// Initialize TransformGizmo object.
const transformGizmo = new ParamateControls.TransformGizmo(
viewport,
controls,
{ hasChildren: false },
'main:modelMatrix');
// Initialize a preset of fill styles that will give a fill color to each selector point.
this.fillStyles = [
// 0: fill and stroke for the point on x-axis selector
{
strokeStyle: 'white',
fillStyle: 'red'
},
// 1: fill and stroke for the point on y-axis selector
{
strokeStyle: 'white',
fillStyle: 'green'
},
// 2: fill and stroke for the point on z-axis selector
{
strokeStyle: 'white',
fillStyle: 'blue'
},
// 3: fill and stroke for the center point selector in non-selected state
{
strokeStyle: 'white',
fillStyle: '#c9c4bf'
},
// 4: fill and stroke for the center point selector in selected state
{
strokeStyle: 'white',
fillStyle: '#00809F'
},
];
transformGizmo.fillStyles = fillStyles;
Next, to change a line type and thickness of the point and adjust the style for gizmo handles, the lineStyles preset may look like this:
Example
// Initialize a preset of line styles for a point line and gizmo handles styling
const lineStyles = [
// 0: x-axis in inactive state
{
strokeStyle: 'red',
lineWidth: 2,
lineDash: []
},
// 1: y-axis in inactive state
{
strokeStyle: 'green',
lineWidth: 2,
lineDash: []
},
// 2: z-axis in inactive state
{
strokeStyle: 'blue',
lineWidth: 2,
lineDash: []
},
// 3: x-axis in active state
{
strokeStyle: 'red',
lineWidth: 4,
lineDash: []
},
// 4: y-axis in active state
{
strokeStyle: 'green',
lineWidth: 4,
lineDash: []
},
// 5: z-axis in active state
{
strokeStyle: 'blue',
lineWidth: 4,
lineDash: []
},
// 6: x-axis rotation handle not selected
{
strokeStyle: 'grey',
lineWidth: 1,
lineDash: [5, 5]
},
// 7: y-axis rotation handle not selected
{
strokeStyle: 'grey',
lineWidth: 1,
lineDash: [5, 5]
},
// 8: y-axis rotation handle not selected
{
strokeStyle: 'grey',
lineWidth: 1,
lineDash: [5, 5]
},
// 9: x-axis rotation feedback
{
strokeStyle: 'white',
lineWidth: 4,
lineDash: []
},
// 10: y-axis rotation feedback
{
strokeStyle: 'green',
lineWidth: 4,
lineDash: []
},
// 11: z-axis rotation feedback
{
strokeStyle: 'blue',
lineWidth: 4,
lineDash: []
},
// 12: x-axis rotation feedback dashed
{
strokeStyle: 'red',
lineWidth: 2,
lineDash: [5, 5]
},
// 13: y-axis rotation feedback dashed
{
strokeStyle: 'green',
lineWidth: 2,
lineDash: [5, 5]
},
// 14: z-axis rotation feedback dashed
{
strokeStyle: 'blue',
lineWidth: 2,
lineDash: [5, 5]
},
// 15: z-axis rotation feedback dashed
{
strokeStyle: 'white',
lineWidth: 2,
lineDash: []
}
];
transformGizmo.lineStyles = lineStyles;
The styling above will produce the following result:
Default Key Events
Event | Key | Behaviour |
keydown | 'H' or 'h' | show / hide help window |
keydown | 'G' or 'g' | translate mode |
keydown | 'R' or 'r' | rotate mode |
keydown | 'S' or 's' | scale mode |
keydown | 'Escape' | reset to the initial values |
keydown | ctrlKey or metaKey (on Mac OS) | select multiple gizmos |
Internal
[TODO: 3-4 working examples published as real small applications with source code:
- 1 gizmo with sphere or cube
- 2 gizmos with parent-child relationship
- gizmo with center correction for cube
- gizmo with center correction with uploads ]