Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overhaul Node3D documentation #87440

Merged
merged 1 commit into from
Mar 17, 2025

Conversation

Mickeon
Copy link
Contributor

@Mickeon Mickeon commented Jan 21, 2024

Closes #87896
Closes #93651
May address godotengine/godot-docs#9930 (?)

Related to several other past efforts, but especially the Basis and Transform3D ones.

This PR aims to completely overhaul Node3D's class reference in an attempt to make it more easy to digest, as well as bring on par with the rest of the documentation.

Why? It generally suffers from the same issues highlighted in the past. The most notable of which being that a lot of descriptions are dull, succinct, or put the focus on the wrong subject:

  • "Set subgizmo selection for this node in the editor."
  • "Updates all the [Node3D] gizmos attached to this node."
  • "Transforms [param global_point] from world space to this node's local space."
  • "Rotates the local transformation around the X axis by angle in radians."

More specific notes:

  • Remove any leftover references to "Spatial" nodes from the class reference.
  • Modified to_local and to_global's descriptions to imply they do return something.
  • Elaborate on when visibility_changed is emitted.
    • The sentence is almost word-for-word from the way some NOTIFICATION constants are written in the Node class.
  • Revamp the descriptions of NOTIFICATION_TRANSFORM_CHANGED & similar.
    • "In order for [constant NOTIFICATION_TRANSFORM_CHANGED] to work, users first need to ask for it, with [method set_notify_local_transform]."
      a grand majority of Node3Ds will receive NOTIFICATION_TRANSFORM_CHANGED without needing for the "user" to opt-in. They need this otherwise they would not work.

This PR may contain commented XML. I use it as a point of reference or to symbolize alternatives of the same sentence. Even if this is a draft, feedback on things worth mentioning is still very welcome.

@Mickeon Mickeon force-pushed the doc-peeves-Node3D-glasses branch 3 times, most recently from 741226a to a8315c8 Compare January 21, 2024 13:55
Copy link
Contributor

@RedMser RedMser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One bit of the Node3D methods (and corresponding docs) always confused me as a user. I've added comments there, but am unsure about proper terminology.

</description>
</method>
<method name="rotate">
<return type="void" />
<param index="0" name="axis" type="Vector3" />
<param index="1" name="angle" type="float" />
<description>
Rotates the local transformation around axis, a unit [Vector3], by specified angle in radians.
Rotates this node's local [member transform] around the [param axis] by the given [param angle], in radians. The operation happens in local space.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From how I understand it, rotate and rotate_[xyz] specify the axis in global space (parent space? not sure about proper terminology), but both modify the local space transform. Whereas rotate_object_local also transforms the rotation axis into local space. Right now, both of these methods have the same description.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have kept these in mind for further testing. These methods have also always confused me so it would be nice to finally write something easier to understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to give closure, rotate is indeed in parent space (same as the transform property). If the position was anything but Vector3(0, 0, 0), the node would rotate and move around the parent.

Changes the node's position by the given offset [Vector3].
Note that the translation [param offset] is affected by the node's scale, so if scaled by e.g. [code](10, 1, 1)[/code], a translation by an offset of [code](2, 0, 0)[/code] would actually add 20 ([code]2 * 10[/code]) to the X coordinate.
<!-- Changes the node's position by the given offset [Vector3]. -->
Adds the given translation [param offset] to the node's [member position] in local space.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From how I understand it, translate specifies the offset in global space (parent space? not sure about proper terminology), but modifies the local space transform. Whereas translate_object_local also transforms the offset into local space. Right now, both of these methods have the same description.

@lostminds
Copy link

Node2D has a lot of the same properties as the 3D version, and often with very short descriptions in the docs. So if you add improved descriptions of the concepts in the Node3D versions perhaps some of them can be applied to Node2D as well? Like for example what the global_position and global_transform properties do and how they work.

@Mickeon
Copy link
Contributor Author

Mickeon commented Feb 4, 2024

That's the idea! One thing at the time. I decided to tackle Node3D first because it's fresh on the mind after both #87175 and #87334.

@Mickeon Mickeon force-pushed the doc-peeves-Node3D-glasses branch from d828b4c to 656493d Compare March 7, 2024 16:11
@Mickeon
Copy link
Contributor Author

Mickeon commented Mar 7, 2024

I have updated the PR with just... more. I am still not fully happy on what is here, as there's a constant fear of losing important information through all of this. So this is still gonna be WIP for a bit more time until I come back with a fresher mind and answers to some questions.

Comment on lines 54 to 61
<!-- Returns the parent [Node3D], or [code]null[/code] if no parent exists, the parent is not a [Node3D], or [member top_level] is [code]true[/code]. -->
Returns the parent [Node3D] that directly affects this node's [member global_transform]. Returns [code]null[/code] if no parent exists, the parent is not a [Node3D], or [member top_level] is [code]true[/code].
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HEAVY indecision between these two. Above is entirely correct, but does not explain why this method exists.

Comment on lines 8 to 9
The [Node3D] node is the base representation of a node in 3D space. All other 3D nodes inherit from this class.
Affine operations (rotate, scale, translate) happen in parent's local coordinate system, unless the [Node3D]'s [member top_level] is [code]true[/code]. Affine operations in this coordinate system correspond to direct affine operations on the [Node3D]'s transform. The word local below refers to this coordinate system. The coordinate system that is attached to the [Node3D] object itself is referred to as object-local coordinate system.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Affine, direct Affine operations... 😖

</member>
<member name="visibility_parent" type="NodePath" setter="set_visibility_parent" getter="get_visibility_parent" default="NodePath(&quot;&quot;)">
Defines the visibility range parent for this node and its subtree. The visibility parent must be a GeometryInstance3D. Any visual instance will only be visible if the visibility parent (and all of its visibility ancestors) is hidden by being closer to the camera than its own [member GeometryInstance3D.visibility_range_begin]. Nodes hidden via the [member Node3D.visible] property are essentially removed from the visibility dependency tree, so dependent instances will not take the hidden node or its ancestors into account.
Path to the visibility range parent for this node and its descendants. The visibility parent must be a [GeometryInstance3D].
Any visual instance will only be visible if the visibility parent (and all of its visibility ancestors) is hidden by being closer to the camera than its own [member GeometryInstance3D.visibility_range_begin]. Nodes hidden via the [member Node3D.visible] property are essentially removed from the visibility dependency tree, so dependent instances will not take the hidden node or its descendants into account.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still find a bit difficult to understand what this is for, despite my best efforts.

Copy link
Member

@fire fire Mar 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be related to hlod lod systems. Let me know if you need more keywords

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would certainly be nice to get more information about it. But changing this description can also be done in a separate PR.

@Mickeon
Copy link
Contributor Author

Mickeon commented Jun 30, 2024

Marking this as ready to be lynched by anyone more savvy than me, no beating around the bush.

Copy link
Member

@kleonc kleonc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only skimmed through, added some brief notes. Please fix these "local space (relative to the parent)".

AFAIK "local" in Godot's properties/method names always refer to object-local, not to parent-local. Docs should be consistent with this.
If there are some exceptions that I'm not aware of, please point to them. 🙂

[b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GlobalScope.deg_to_rad].
[b]Note:[/b] Be aware that "Spatial" nodes are now called "Node3D" starting with Godot 4. Any Godot 3.x references to "Spatial" nodes refer to "Node3D" in Godot 4.
The [Node3D] node is the base representation of a node in 3D space. All other 3D nodes inherit from this class.
Affine operations (rotate, scale, translate) happen in parent's local coordinate system, unless the [Node3D]'s [member top_level] is [code]true[/code]. Affine operations in this coordinate system correspond to direct affine operations on the [Node3D]'s [member transform]. The word local below refers to this coordinate system. The coordinate system that is attached to the [Node3D] object itself is referred to as object-local coordinate system.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should avoid using the word "local" for multiple things. See @kleonc's comments.

In general, Godot's properties are parent-relative by default unless further qualified, where the word global qualifies it as fully global relative to the world space, and the word local qualifies it as relative to within the node's own transform. For the docs where we need to clarify this, let's use "parent-relative", not "local".

@Mickeon
Copy link
Contributor Author

Mickeon commented Nov 22, 2024

Given your recent review I'll revisit this soonish. The "local" distinction is bit overwhelming to think about, but I must pursue for the sake of a nicer class reference.

@Mickeon Mickeon force-pushed the doc-peeves-Node3D-glasses branch from 650faa8 to 763701a Compare November 23, 2024 18:47
@Mickeon Mickeon force-pushed the doc-peeves-Node3D-glasses branch from 1914168 to 286ef8d Compare November 30, 2024 21:51
@Mickeon
Copy link
Contributor Author

Mickeon commented Nov 30, 2024

I have updated to add "and preserves the position" where appropriate, as well as update translate and translate_object_local again.

Anyway, if we'd want to use e.g. "object-local" instead of just "local" then we should probably do so consequently across the whole docs. AFAICT currently we use just "local" to refer to the given object/node, so I'm saying let's keep using it.

Mhm. Hence my reluctance to say object-local space. If it needs to be clarified it needs to be done in one huge swoop across the docs.

  • I have handled similar descriptions as suggested, but the idea of saying "around the global [param axis] going through this node's origin" interests me. It sounds a whole lot easier to imagine the whole operation that way.

Again, nothing against clarifications. The purpose of the docs is not to be as concise as possible (while being correct). So if the descriptions can be made a little longer but easier to grasp for "a regular user" then sure it's welcomed (we'll try to keep them correct).

Problem here is that I'd have to give up on directly mentioning the basis otherwise the sentence doesn't make sense, and for consistency that may need to escalate for the surrounding descriptions as well.

Same as [method translate_object_local], for compatibility reasons. Prefer using it instead.

This sounds exactly like a deprecation message, but the method is not deprecated until we decide that separately. So it's a bit odd to do this right now.

@aaronfranke
Copy link
Member

@Mickeon Can you rebase this PR? There's a lot of good here, we should try to get this merged sometime soon.

@Mickeon
Copy link
Contributor Author

Mickeon commented Mar 15, 2025

Rebased after 8af5072 and d0c4219 . Wew, what a trip.

The descriptions affected were is_visible_in_tree and look_at. In particular, see #100991 (comment) too.

@Mickeon Mickeon modified the milestones: 4.x, 4.5 Mar 15, 2025
@Mickeon Mickeon added the cherrypick:4.4 Considered for cherry-picking into a future 4.4.x release label Mar 15, 2025
@Mickeon Mickeon force-pushed the doc-peeves-Node3D-glasses branch 2 times, most recently from 63cb24d to 21eec8d Compare March 16, 2025 14:48
@Mickeon Mickeon requested a review from aaronfranke March 16, 2025 14:48
@Mickeon Mickeon force-pushed the doc-peeves-Node3D-glasses branch from 21eec8d to 9e90205 Compare March 16, 2025 17:41
@Mickeon
Copy link
Contributor Author

Mickeon commented Mar 16, 2025

Pushed to address incorrect constants in the global_* properties

@Mickeon Mickeon force-pushed the doc-peeves-Node3D-glasses branch from 9e90205 to 106ec03 Compare March 16, 2025 18:40
@Mickeon Mickeon force-pushed the doc-peeves-Node3D-glasses branch from 01d3157 to fbdd298 Compare March 17, 2025 16:47
@Repiteo Repiteo merged commit 28102e6 into godotengine:master Mar 17, 2025
20 checks passed
@Repiteo
Copy link
Contributor

Repiteo commented Mar 17, 2025

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cherrypick:4.4 Considered for cherry-picking into a future 4.4.x release documentation enhancement
Projects
None yet
9 participants