Skip to content

Commit

Permalink
Make Transform2D/3D, Basis, and Quaternion docs more consistent
Browse files Browse the repository at this point in the history
  • Loading branch information
Mickeon committed Nov 25, 2024
1 parent cb411fa commit d7ded61
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 23 deletions.
23 changes: 15 additions & 8 deletions doc/classes/Basis.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@
<description>
The [Basis] built-in [Variant] type is a 3×3 [url=https://en.wikipedia.org/wiki/Matrix_(mathematics)]matrix[/url] used to represent 3D rotation, scale, and shear. It is frequently used within a [Transform3D].
A [Basis] is composed by 3 axis vectors, each representing a column of the matrix: [member x], [member y], and [member z]. The length of each axis ([method Vector3.length]) influences the basis's scale, while the direction of all axes influence the rotation. Usually, these axes are perpendicular to one another. However, when you rotate any axis individually, the basis becomes sheared. Applying a sheared basis to a 3D model will make the model appear distorted.
A [Basis] is [b]orthogonal[/b] if its axes are perpendicular to each other. A basis is [b]normalized[/b] if the length of every axis is [code]1[/code]. A basis is [b]uniform[/b] if all axes share the same length (see [method get_scale]). A basis is [b]orthonormal[/b] if it is both orthogonal and normalized, which allows it to only represent rotations. A basis is [b]conformal[/b] if it is both orthogonal and uniform, which ensures it is not distorted.
A [Basis] is:
- [b]orthogonal[/b] if its axes are perpendicular to each other;
- [b]normalized[/b] if the length of every axis is [code]1.0[/code];
- [b]uniform[/b] if all axes share the same length (see [method get_scale]);
- [b]orthonormal[/b] if it is both orthogonal and normalized, which allows it to only represent rotations;
- [b]conformal[/b] if it is both orthogonal and uniform, which ensures it is not distorted.
For a general introduction, see the [url=$DOCS_URL/tutorials/math/matrices_and_transforms.html]Matrices and transforms[/url] tutorial.
[b]Note:[/b] Godot uses a [url=https://en.wikipedia.org/wiki/Right-hand_rule]right-handed coordinate system[/url], which is a common standard. For directions, the convention for built-in types like [Camera3D] is for -Z to point forward (+X is right, +Y is up, and +Z is back). Other objects may use different direction conventions. For more information, see the [url=$DOCS_URL/tutorials/assets_pipeline/importing_3d_scenes/model_export_considerations.html#d-asset-direction-conventions]3D asset direction conventions[/url] tutorial.
[b]Note:[/b] The basis matrices are exposed as [url=https://www.mindcontrol.org/~hplus/graphics/matrix-layout.html]column-major[/url] order, which is the same as OpenGL. However, they are stored internally in row-major order, which is the same as DirectX.
Expand All @@ -24,7 +29,7 @@
<constructor name="Basis">
<return type="Basis" />
<description>
Constructs a [Basis] identical to the [constant IDENTITY].
Constructs a [Basis] identical to [constant IDENTITY].
[b]Note:[/b] In C#, this constructs a [Basis] with all of its components set to [constant Vector3.ZERO].
</description>
</constructor>
Expand Down Expand Up @@ -131,6 +136,7 @@
- The [member Vector3.y] contains the angle around the [member y] axis (yaw);
- The [member Vector3.z] contains the angle around the [member z] axis (roll).
The order of each consecutive rotation can be changed with [param order] (see [enum EulerOrder] constants). By default, the YXZ convention is used ([constant EULER_ORDER_YXZ]): Z (roll) is calculated first, then X (pitch), and lastly Y (yaw). When using the opposite method [method from_euler], this order is reversed.
[b]Note:[/b] This method assumes the basis is [i]uniform[/i] (all axes share the same length) (see [method get_scale]).
[b]Note:[/b] Euler angles are much more intuitive but are not suitable for 3D math. Because of this, consider using the [method get_rotation_quaternion] method instead, which returns a [Quaternion].
[b]Note:[/b] In the Inspector dock, a basis's rotation is often displayed in Euler angles (in degrees), as is the case with the [member Node3D.rotation] property.
</description>
Expand All @@ -145,7 +151,7 @@
<method name="get_scale" qualifiers="const">
<return type="Vector3" />
<description>
Returns the length of each axis of this basis, as a [Vector3]. If the basis is not sheared, this is the scaling factor. It is not affected by rotation.
Returns the length of each axis of this basis, as a [Vector3]. If the basis is not sheared, this value is the scaling factor. It is not affected by rotation.
[codeblocks]
[gdscript]
var my_basis = Basis(
Expand Down Expand Up @@ -242,8 +248,8 @@
<param index="0" name="axis" type="Vector3" />
<param index="1" name="angle" type="float" />
<description>
Returns this basis rotated around the given [param axis] by [param angle] (in radians). The [param axis] must be a normalized vector (see [method Vector3.normalized]).
Positive values rotate this basis clockwise around the axis, while negative values rotate it counterclockwise.
Returns a copy of this basis rotated around the given [param axis] by the given [param angle] (in radians).
The [param axis] must be a normalized vector (see [method Vector3.normalized]). If [param angle] is positive, the basis is rotated clockwise around the axis.
[codeblocks]
[gdscript]
var my_basis = Basis.IDENTITY
Expand Down Expand Up @@ -390,12 +396,12 @@
</members>
<constants>
<constant name="IDENTITY" value="Basis(1, 0, 0, 0, 1, 0, 0, 0, 1)">
The identity basis. This is a basis with no rotation, no shear, and its scale being [code]1[/code]. This means that:
The identity [Basis]. This is an orthonormal basis with no rotation, no shear, and not scaled. This also means that:
- The [member x] points right ([constant Vector3.RIGHT]);
- The [member y] points up ([constant Vector3.UP]);
- The [member z] points back ([constant Vector3.BACK]).
[codeblock]
var basis := Basis.IDENTITY
var basis = Basis.IDENTITY
print("| X | Y | Z")
print("| %s | %s | %s" % [basis.x.x, basis.y.x, basis.z.x])
print("| %s | %s | %s" % [basis.x.y, basis.y.y, basis.z.y])
Expand All @@ -406,7 +412,8 @@
# | 0 | 1 | 0
# | 0 | 0 | 1
[/codeblock]
This is identical to creating [constructor Basis] without any parameters. This constant can be used to make your code clearer, and for consistency with C#.
If a [Vector3] or another [Basis] is transformed (multiplied) by this constant, no transformation occurs.
[b]Note:[/b] In GDScript, this constant is equivalent to creating a [constructor Basis] without any arguments. It can be used to make your code clearer, and for consistency with C#.
</constant>
<constant name="FLIP_X" value="Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1)">
When any basis is multiplied by [constant FLIP_X], it negates all components of the [member x] axis (the X column).
Expand Down
5 changes: 3 additions & 2 deletions doc/classes/Quaternion.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<constructor name="Quaternion">
<return type="Quaternion" />
<description>
Constructs a [Quaternion] identical to the [constant IDENTITY].
Constructs a [Quaternion] identical to [constant IDENTITY].
[b]Note:[/b] In C#, this constructs a [Quaternion] with all of its components set to [code]0.0[/code].
</description>
</constructor>
Expand Down Expand Up @@ -129,7 +129,7 @@
<return type="bool" />
<param index="0" name="to" type="Quaternion" />
<description>
Returns [code]true[/code] if this quaternion and [param to] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component.
Returns [code]true[/code] if this quaternion and [param to] are approximately equal, by calling [method @GlobalScope.is_equal_approx] on each component.
</description>
</method>
<method name="is_finite" qualifiers="const">
Expand Down Expand Up @@ -232,6 +232,7 @@
<constant name="IDENTITY" value="Quaternion(0, 0, 0, 1)">
The identity quaternion, representing no rotation. This has the same rotation as [constant Basis.IDENTITY].
If a [Vector3] is rotated (multiplied) by this quaternion, it does not change.
[b]Note:[/b] In GDScript, this constant is equivalent to creating a [constructor Quaternion] without any arguments. It can be used to make your code clearer, and for consistency with C#.
</constant>
</constants>
<operators>
Expand Down
16 changes: 9 additions & 7 deletions doc/classes/Transform2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
<method name="affine_inverse" qualifiers="const">
<return type="Transform2D" />
<description>
Returns the inverted version of this transform. Unlike [method inverse], this method works with almost any basis, including non-uniform ones, but is slower. See also [method inverse].
Returns the inverted version of this transform. Unlike [method inverse], this method works with almost any basis, including non-uniform ones, but is slower.
[b]Note:[/b] For this method to return correctly, the transform's basis needs to have a determinant that is not exactly [code]0[/code] (see [method determinant]).
</description>
</method>
Expand Down Expand Up @@ -127,7 +127,7 @@
// Rotating the Transform2D in any way preserves its scale.
myTransform = myTransform.Rotated(Mathf.Tau / 2.0f);

GD.Print(myTransform.GetScale()); // Prints (2, 4, 8).
GD.Print(myTransform.GetScale()); // Prints (2, 4).
[/csharp]
[/codeblocks]
[b]Note:[/b] If the value returned by [method determinant] is negative, the scale is also negative.
Expand Down Expand Up @@ -191,7 +191,8 @@
<return type="Transform2D" />
<param index="0" name="angle" type="float" />
<description>
Returns a copy of the transform rotated by the given [param angle] (in radians).
Returns a copy of this transform rotated by the given [param angle] (in radians).
If [param angle] is positive, the transform is rotated clockwise.
This method is an optimized version of multiplying the given transform [code]X[/code] with a corresponding rotation transform [code]R[/code] from the left, i.e., [code]R * X[/code].
This can be seen as transforming with respect to the global/parent frame.
</description>
Expand Down Expand Up @@ -257,7 +258,7 @@
</members>
<constants>
<constant name="IDENTITY" value="Transform2D(1, 0, 0, 1, 0, 0)">
The identity [Transform2D]. A transform with no translation, no rotation, and its scale being [code]1[/code]. When multiplied by another [Variant] such as [Rect2] or another [Transform2D], no transformation occurs. This means that:
The identity [Transform2D]. This is a transform with no translation, no rotation, and not scaled. This also means that:
- The [member x] points right ([constant Vector2.RIGHT]);
- The [member y] points down ([constant Vector2.DOWN]).
[codeblock]
Expand All @@ -270,15 +271,16 @@
# | 1 | 0 | 0
# | 0 | 1 | 0
[/codeblock]
This is identical to creating [constructor Transform2D] without any parameters. This constant can be used to make your code clearer, and for consistency with C#.
If a [Vector2], a [Rect2], or another [Transform2D] is transformed (multiplied) by this constant, no transformation occurs.
[b]Note:[/b] In GDScript, this constant is equivalent to creating a [constructor Transform2D] without any arguments. It can be used to make your code clearer, and for consistency with C#.
</constant>
<constant name="FLIP_X" value="Transform2D(-1, 0, 0, 1, 0, 0)">
When any transform is multiplied by [constant FLIP_X], it negates all components of the [member x] axis (the X column).
When [constant FLIP_X] is multiplied by any basis, it negates the [member Vector2.x] component of all axes (the X row).
When [constant FLIP_X] is multiplied by any transform, it negates the [member Vector2.x] component of all axes (the X row).
</constant>
<constant name="FLIP_Y" value="Transform2D(1, 0, 0, -1, 0, 0)">
When any transform is multiplied by [constant FLIP_Y], it negates all components of the [member y] axis (the Y column).
When [constant FLIP_Y] is multiplied by any basis, it negates the [member Vector2.y] component of all axes (the Y row).
When [constant FLIP_Y] is multiplied by any transform, it negates the [member Vector2.y] component of all axes (the Y row).
</constant>
</constants>
<operators>
Expand Down
29 changes: 23 additions & 6 deletions doc/classes/Transform3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<constructor name="Transform3D">
<return type="Transform3D" />
<description>
Constructs a [Transform3D] identical to the [constant IDENTITY].
Constructs a [Transform3D] identical to [constant IDENTITY].
[b]Note:[/b] In C#, this constructs a [Transform3D] with its [member origin] and the components of its [member basis] set to [constant Vector3.ZERO].
</description>
</constructor>
Expand Down Expand Up @@ -78,8 +78,8 @@
<method name="inverse" qualifiers="const">
<return type="Transform3D" />
<description>
Returns the inverted version of this transform. See also [method Basis.inverse].
[b]Note:[/b] For this method to return correctly, the transform's [member basis] needs to be [i]orthonormal[/i] (see [method Basis.orthonormalized]). That means, the basis should only represent a rotation. If it does not, use [method affine_inverse] instead.
Returns the [url=https://en.wikipedia.org/wiki/Invertible_matrix]inverted version of this transform[/url]. See also [method Basis.inverse].
[b]Note:[/b] For this method to return correctly, the transform's [member basis] needs to be [i]orthonormal[/i] (see [method orthonormalized]). That means, the basis should only represent a rotation. If it does not, use [method affine_inverse] instead.
</description>
</method>
<method name="is_equal_approx" qualifiers="const">
Expand Down Expand Up @@ -118,7 +118,7 @@
<param index="1" name="angle" type="float" />
<description>
Returns a copy of this transform rotated around the given [param axis] by the given [param angle] (in radians).
The [param axis] must be a normalized vector.
The [param axis] must be a normalized vector (see [method Vector3.normalized]). If [param angle] is positive, the basis is rotated clockwise around the axis.
This method is an optimized version of multiplying the given transform [code]X[/code] with a corresponding rotation transform [code]R[/code] from the left, i.e., [code]R * X[/code].
This can be seen as transforming with respect to the global/parent frame.
</description>
Expand Down Expand Up @@ -181,8 +181,25 @@
</members>
<constants>
<constant name="IDENTITY" value="Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)">
A transform with no translation, no rotation, and its scale being [code]1[/code]. Its [member basis] is equal to [constant Basis.IDENTITY].
When multiplied by another [Variant] such as [AABB] or another [Transform3D], no transformation occurs.
The identity [Transform3D]. This is a transform with no translation, no rotation, and not scaled. Its [member basis] is equal to [constant Basis.IDENTITY]. This also means that:
- Its [member Basis.x] points right ([constant Vector3.RIGHT]);
- Its [member Basis.y] points up ([constant Vector3.UP]);
- Its [member Basis.z] points back ([constant Vector3.BACK]).
[codeblock]
var transform = Transform3D.IDENTITY
var basis = transform.basis
print("| X | Y | Z | Origin")
print("| %s | %s | %s | %s" % [basis.x.x, basis.y.x, basis.z.x, transform.origin.x])
print("| %s | %s | %s | %s" % [basis.x.y, basis.y.y, basis.z.y, transform.origin.y])
print("| %s | %s | %s | %s" % [basis.x.z, basis.y.z, basis.z.z, transform.origin.z])
# Prints:
# | X | Y | Z | Origin
# | 1 | 0 | 0 | 0
# | 0 | 1 | 0 | 0
# | 0 | 0 | 1 | 0
[/codeblock]
If a [Vector3], an [AABB], a [Plane], or another [Transform3D] is transformed (multiplied) by this constant, no transformation occurs.
[b]Note:[/b] In GDScript, this constant is equivalent to creating a [constructor Transform3D] without any arguments. It can be used to make your code clearer, and for consistency with C#.
</constant>
<constant name="FLIP_X" value="Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)">
[Transform3D] with mirroring applied perpendicular to the YZ plane. Its [member basis] is equal to [constant Basis.FLIP_X].
Expand Down

0 comments on commit d7ded61

Please sign in to comment.