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)

Single TransformGizmo instance with default settings displayed in 3 different modes: translation (left), rotation (middle), scaling (right).

To customize this gizmo, for example, by hiding the z-axis for all its handles, the settings must be modified as follows:

Example

const transformGizmo = new ParamateControls.TransformGizmo(
                                            viewport,
                                            controls,
                                            { hasChildren: false,
                                              translateActiveZ: false,
                                              rotateActiveZ: false,
                                              scaleActiveZ: false },
                                            'main:modelMatrix');

Single TransformGizmo instance with custom settings displayed in 3 different modes: translation handle in Z-direction is disabled (left), rotation handle on Z-axis is disabled (middle), scaling handle in Z-direction is disabled (right).

Next, to establish a parent-child relationship between two gizmos, two TransformGizmo objects should be initialized in the following way:

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:

Two TransformGizmo instances with parent-child relationship: parent gizmo (deep green cone on the left), child gizmo (lime green cone on the right).

While the parent gizmo (purple cube) is offset from the origin by [5, 0, 5], the child gizmo (green cube) is translated by [15, 0, 15]. Now when the parent gizmo is moved, rotated, or scaled, the child gizmo will be moved, rotated, or scaled as well. Moving the child gizmo doesn't affect the parent gizmo.

Two TransformGizmo instances with parent-child relationship after transformations: parent gizmo (deep green cone on the left), child gizmo (lime green cone on the right).

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:

TransformGizmo control with the styling applied.

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 ]