From 8e957a745bec0e1187fadb84873edd51d1285c0c Mon Sep 17 00:00:00 2001
From: Cory Petkovsek <632766+TokisanGames@users.noreply.github.com>
Date: Wed, 29 Jan 2025 05:34:06 +0700
Subject: [PATCH] Update docs
---
Terrain3D.vcxproj | 1 +
Terrain3D.vcxproj.filters | 3 +
doc/api/class_terrain3d.rst | 291 +++++++++++-----------
doc/api/class_terrain3dcollision.rst | 328 +++++++++++++++++++++++++
doc/api/class_terrain3ddata.rst | 8 +-
doc/api/index.rst | 1 +
doc/build_docs.sh | 7 +-
doc/doc_classes/Terrain3D.xml | 42 ++--
doc/doc_classes/Terrain3DCollision.xml | 93 +++++++
doc/doc_classes/Terrain3DData.xml | 8 +-
doc/docs/collision.md | 38 ++-
doc/docs/games.md | 1 +
12 files changed, 636 insertions(+), 185 deletions(-)
create mode 100644 doc/api/class_terrain3dcollision.rst
create mode 100644 doc/doc_classes/Terrain3DCollision.xml
diff --git a/Terrain3D.vcxproj b/Terrain3D.vcxproj
index 8110ac12..54daea8a 100644
--- a/Terrain3D.vcxproj
+++ b/Terrain3D.vcxproj
@@ -239,6 +239,7 @@
+
diff --git a/Terrain3D.vcxproj.filters b/Terrain3D.vcxproj.filters
index 7f670238..504fb753 100644
--- a/Terrain3D.vcxproj.filters
+++ b/Terrain3D.vcxproj.filters
@@ -335,5 +335,8 @@
3. XML
+
+ 3. XML
+
\ No newline at end of file
diff --git a/doc/api/class_terrain3d.rst b/doc/api/class_terrain3d.rst
index 3b8a9f54..a4588f0c 100644
--- a/doc/api/class_terrain3d.rst
+++ b/doc/api/class_terrain3d.rst
@@ -19,7 +19,7 @@ Description
Terrain3D is a high performance, editable terrain system for Godot 4. It provides a clipmap based terrain that supports terrains from 64x64m up to 65.5x65.5km with multiple LODs, 32 textures, and editor tools for importing or creating terrains.
-This class handles mesh and collision generation, and management of the whole system. See `System Architecture `__ for design details.
+This class handles mesh generation, and management of the whole system. See `System Architecture `__ for design details.
.. rst-class:: classref-reftable-group
@@ -29,91 +29,95 @@ Properties
.. table::
:widths: auto
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | :ref:`Terrain3DAssets` | :ref:`assets` | |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | RenderingServer.ShadowCastingSetting | :ref:`cast_shadows` | ``1`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`collision_enabled` | ``true`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``int`` | :ref:`collision_layer` | ``1`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``int`` | :ref:`collision_mask` | ``1`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | :ref:`CollisionMode` | :ref:`collision_mode` | ``0`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``float`` | :ref:`collision_priority` | ``1.0`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``float`` | :ref:`cull_margin` | ``0.0`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | :ref:`Terrain3DData` | :ref:`data` | |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``String`` | :ref:`data_directory` | ``""`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``int`` | :ref:`debug_level` | ``0`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | GeometryInstance3D.GIMode | :ref:`gi_mode` | ``1`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | :ref:`Terrain3DInstancer` | :ref:`instancer` | |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``float`` | :ref:`label_distance` | ``0.0`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``int`` | :ref:`label_size` | ``48`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | :ref:`Terrain3DMaterial` | :ref:`material` | |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``int`` | :ref:`mesh_lods` | ``7`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``int`` | :ref:`mesh_size` | ``48`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``int`` | :ref:`mouse_layer` | ``32`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | :ref:`RegionSize` | :ref:`region_size` | ``256`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``int`` | :ref:`render_layers` | ``2147483649`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`save_16_bit` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_autoshader` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_checkered` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_colormap` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_control_angle` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_control_blend` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_control_scale` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_control_texture` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_grey` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_grid` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_heightmap` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_instancer_grid` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_navigation` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_region_grid` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_roughmap` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_texture_height` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_texture_normal` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_texture_rough` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``bool`` | :ref:`show_vertex_grid` | ``false`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``String`` | :ref:`version` | ``"1.0.0-dev"`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
- | ``float`` | :ref:`vertex_spacing` | ``1.0`` |
- +-----------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | :ref:`Terrain3DAssets` | :ref:`assets` | |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | RenderingServer.ShadowCastingSetting | :ref:`cast_shadows` | ``1`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | :ref:`Terrain3DCollision` | :ref:`collision` | |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``int`` | :ref:`collision_layer` | ``1`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``int`` | :ref:`collision_mask` | ``1`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | :ref:`CollisionMode` | :ref:`collision_mode` | ``1`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``float`` | :ref:`collision_priority` | ``1.0`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``int`` | :ref:`collision_radius` | ``64`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``int`` | :ref:`collision_shape_size` | ``16`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``float`` | :ref:`cull_margin` | ``0.0`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | :ref:`Terrain3DData` | :ref:`data` | |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``String`` | :ref:`data_directory` | ``""`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``int`` | :ref:`debug_level` | ``0`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | GeometryInstance3D.GIMode | :ref:`gi_mode` | ``1`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | :ref:`Terrain3DInstancer` | :ref:`instancer` | |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``float`` | :ref:`label_distance` | ``0.0`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``int`` | :ref:`label_size` | ``48`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | :ref:`Terrain3DMaterial` | :ref:`material` | |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``int`` | :ref:`mesh_lods` | ``7`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``int`` | :ref:`mesh_size` | ``48`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``int`` | :ref:`mouse_layer` | ``32`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | :ref:`RegionSize` | :ref:`region_size` | ``256`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``int`` | :ref:`render_layers` | ``2147483649`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`save_16_bit` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_autoshader` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_checkered` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_colormap` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_control_angle` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_control_blend` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_control_scale` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_control_texture` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_grey` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_grid` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_heightmap` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_instancer_grid` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_navigation` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_region_grid` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_roughmap` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_texture_height` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_texture_normal` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_texture_rough` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``bool`` | :ref:`show_vertex_grid` | ``false`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``String`` | :ref:`version` | ``"1.0.0-dev"`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
+ | ``float`` | :ref:`vertex_spacing` | ``1.0`` |
+ +-------------------------------------------------------------+----------------------------------------------------------------------------+-----------------+
.. rst-class:: classref-reftable-group
@@ -130,14 +134,14 @@ Methods
+-----------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``Camera3D`` | :ref:`get_camera`\ (\ ) |const| |
+-----------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
- | ``RID`` | :ref:`get_collision_rid`\ (\ ) |const| |
- +-----------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`Terrain3DEditor` | :ref:`get_editor`\ (\ ) |const| |
+-----------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``Vector3`` | :ref:`get_intersection`\ (\ src_pos\: ``Vector3``, direction\: ``Vector3``, gpu_mode\: ``bool`` = false\ ) |
+-----------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``EditorPlugin`` | :ref:`get_plugin`\ (\ ) |const| |
+-----------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | ``Vector3`` | :ref:`get_snapped_position`\ (\ ) |const| |
+ +-----------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``bool`` | :ref:`is_compatibility_mode`\ (\ ) |const| |
+-----------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`set_camera`\ (\ camera\: ``Camera3D``\ ) |
@@ -239,32 +243,6 @@ The region size is 1024 x 1024 meters, vertices, and pixels on Image maps.
The region size is 2048 x 2048 meters, vertices, and pixels on Image maps.
-.. rst-class:: classref-item-separator
-
-----
-
-.. _enum_Terrain3D_CollisionMode:
-
-.. rst-class:: classref-enumeration
-
-enum **CollisionMode**: :ref:`🔗`
-
-.. _class_Terrain3D_constant_FULL_GAME:
-
-.. rst-class:: classref-enumeration-constant
-
-:ref:`CollisionMode` **FULL_GAME** = ``0``
-
-Generates collision for all regions in game only.
-
-.. _class_Terrain3D_constant_FULL_EDITOR:
-
-.. rst-class:: classref-enumeration-constant
-
-:ref:`CollisionMode` **FULL_EDITOR** = ``1``
-
-Generates collision for all regions in the editor and in game.
-
.. rst-class:: classref-section-separator
----
@@ -308,18 +286,17 @@ Tells the renderer how to cast shadows from the terrain onto other objects. This
----
-.. _class_Terrain3D_property_collision_enabled:
+.. _class_Terrain3D_property_collision:
.. rst-class:: classref-property
-``bool`` **collision_enabled** = ``true`` :ref:`🔗`
+:ref:`Terrain3DCollision` **collision** :ref:`🔗`
.. rst-class:: classref-property-setget
-- |void| **set_collision_enabled**\ (\ value\: ``bool``\ )
-- ``bool`` **get_collision_enabled**\ (\ )
+- :ref:`Terrain3DCollision` **get_collision**\ (\ )
-If enabled, collision is generated according to the mode selected. By default collision is generated for all regions at run time only using the physics server. Also see :ref:`collision_mode`.
+The active :ref:`Terrain3DCollision` object.
.. rst-class:: classref-item-separator
@@ -336,7 +313,7 @@ If enabled, collision is generated according to the mode selected. By default co
- |void| **set_collision_layer**\ (\ value\: ``int``\ )
- ``int`` **get_collision_layer**\ (\ )
-The physics layers the terrain lives in. Also see :ref:`collision_mask`.
+Alias for :ref:`Terrain3DCollision.layer`.
.. rst-class:: classref-item-separator
@@ -353,7 +330,7 @@ The physics layers the terrain lives in. Also see :ref:`collision_mask`.
+Alias for :ref:`Terrain3DCollision.mask`.
.. rst-class:: classref-item-separator
@@ -363,18 +340,14 @@ The physics layers the terrain scans for colliding objects. Also see :ref:`colli
.. rst-class:: classref-property
-:ref:`CollisionMode` **collision_mode** = ``0`` :ref:`🔗`
+:ref:`CollisionMode` **collision_mode** = ``1`` :ref:`🔗`
.. rst-class:: classref-property-setget
-- |void| **set_collision_mode**\ (\ value\: :ref:`CollisionMode`\ )
-- :ref:`CollisionMode` **get_collision_mode**\ (\ )
+- |void| **set_collision_mode**\ (\ value\: :ref:`CollisionMode`\ )
+- :ref:`CollisionMode` **get_collision_mode**\ (\ )
-If collision is enabled, collision_mode specifies when and where collision is generated:
-
-\* FULL_GAME - all regions are generated at startup in game only.
-
-\* FULL_GAME - all regions are generated in the editor. Necessary for some 3rd party plugins to find the terrain. The collision mesh can also be made visible in the editor by enabling ``View Gizmos`` in the viewport menu.
+Alias for :ref:`Terrain3DCollision.mode`.
.. rst-class:: classref-item-separator
@@ -391,7 +364,41 @@ If collision is enabled, collision_mode specifies when and where collision is ge
- |void| **set_collision_priority**\ (\ value\: ``float``\ )
- ``float`` **get_collision_priority**\ (\ )
-The priority used to solve collisions. The higher priority, the lower the penetration of a colliding object.
+Alias for :ref:`Terrain3DCollision.priority`.
+
+.. rst-class:: classref-item-separator
+
+----
+
+.. _class_Terrain3D_property_collision_radius:
+
+.. rst-class:: classref-property
+
+``int`` **collision_radius** = ``64`` :ref:`🔗`
+
+.. rst-class:: classref-property-setget
+
+- |void| **set_collision_radius**\ (\ value\: ``int``\ )
+- ``int`` **get_collision_radius**\ (\ )
+
+Alias for :ref:`Terrain3DCollision.radius`.
+
+.. rst-class:: classref-item-separator
+
+----
+
+.. _class_Terrain3D_property_collision_shape_size:
+
+.. rst-class:: classref-property
+
+``int`` **collision_shape_size** = ``16`` :ref:`🔗`
+
+.. rst-class:: classref-property-setget
+
+- |void| **set_collision_shape_size**\ (\ value\: ``int``\ )
+- ``int`` **get_collision_shape_size**\ (\ )
+
+Alias for :ref:`Terrain3DCollision.shape_size`.
.. rst-class:: classref-item-separator
@@ -1052,18 +1059,6 @@ Returns the camera the terrain is currently snapping to.
----
-.. _class_Terrain3D_method_get_collision_rid:
-
-.. rst-class:: classref-method
-
-``RID`` **get_collision_rid**\ (\ ) |const| :ref:`🔗`
-
-Returns the RID of the active StaticBody.
-
-.. rst-class:: classref-item-separator
-
-----
-
.. _class_Terrain3D_method_get_editor:
.. rst-class:: classref-method
@@ -1138,6 +1133,18 @@ Returns the EditorPlugin connected to Terrain3D.
----
+.. _class_Terrain3D_method_get_snapped_position:
+
+.. rst-class:: classref-method
+
+``Vector3`` **get_snapped_position**\ (\ ) |const| :ref:`🔗`
+
+Returns the last position the terrain was centered on.
+
+.. rst-class:: classref-item-separator
+
+----
+
.. _class_Terrain3D_method_is_compatibility_mode:
.. rst-class:: classref-method
diff --git a/doc/api/class_terrain3dcollision.rst b/doc/api/class_terrain3dcollision.rst
new file mode 100644
index 00000000..9f3e4583
--- /dev/null
+++ b/doc/api/class_terrain3dcollision.rst
@@ -0,0 +1,328 @@
+:github_url: hide
+
+.. DO NOT EDIT THIS FILE!!!
+.. Generated automatically from Godot engine sources.
+.. Generator: https://github.com/godotengine/godot/tree/master/doc/tools/make_rst.py.
+.. XML source: https://github.com/godotengine/godot/tree/master/../_plugins/Terrain3D/doc/doc_classes/Terrain3DCollision.xml.
+
+.. _class_Terrain3DCollision:
+
+Terrain3DCollision
+==================
+
+**Inherits:** ``Object``
+
+.. rst-class:: classref-introduction-group
+
+Description
+-----------
+
+This class manages collision.
+
+.. rst-class:: classref-reftable-group
+
+Properties
+----------
+
+.. table::
+ :widths: auto
+
+ +-------------------------------------------------------------+-----------------------------------------------------------------+---------+
+ | ``int`` | :ref:`layer` | ``1`` |
+ +-------------------------------------------------------------+-----------------------------------------------------------------+---------+
+ | ``int`` | :ref:`mask` | ``1`` |
+ +-------------------------------------------------------------+-----------------------------------------------------------------+---------+
+ | :ref:`CollisionMode` | :ref:`mode` | ``1`` |
+ +-------------------------------------------------------------+-----------------------------------------------------------------+---------+
+ | ``float`` | :ref:`priority` | ``1.0`` |
+ +-------------------------------------------------------------+-----------------------------------------------------------------+---------+
+ | ``int`` | :ref:`radius` | ``64`` |
+ +-------------------------------------------------------------+-----------------------------------------------------------------+---------+
+ | ``int`` | :ref:`shape_size` | ``16`` |
+ +-------------------------------------------------------------+-----------------------------------------------------------------+---------+
+
+.. rst-class:: classref-reftable-group
+
+Methods
+-------
+
+.. table::
+ :widths: auto
+
+ +----------+---------------------------------------------------------------------------------------+
+ | |void| | :ref:`build`\ (\ ) |
+ +----------+---------------------------------------------------------------------------------------+
+ | |void| | :ref:`destroy`\ (\ ) |
+ +----------+---------------------------------------------------------------------------------------+
+ | ``RID`` | :ref:`get_rid`\ (\ ) |const| |
+ +----------+---------------------------------------------------------------------------------------+
+ | ``bool`` | :ref:`is_dynamic_mode`\ (\ ) |const| |
+ +----------+---------------------------------------------------------------------------------------+
+ | ``bool`` | :ref:`is_editor_mode`\ (\ ) |const| |
+ +----------+---------------------------------------------------------------------------------------+
+ | ``bool`` | :ref:`is_enabled`\ (\ ) |const| |
+ +----------+---------------------------------------------------------------------------------------+
+ | |void| | :ref:`update`\ (\ force\: ``bool`` = false\ ) |
+ +----------+---------------------------------------------------------------------------------------+
+
+.. rst-class:: classref-section-separator
+
+----
+
+.. rst-class:: classref-descriptions-group
+
+Enumerations
+------------
+
+.. _enum_Terrain3DCollision_CollisionMode:
+
+.. rst-class:: classref-enumeration
+
+enum **CollisionMode**: :ref:`🔗`
+
+.. _class_Terrain3DCollision_constant_DISABLED:
+
+.. rst-class:: classref-enumeration-constant
+
+:ref:`CollisionMode` **DISABLED** = ``0``
+
+No collision shapes will be generated.
+
+.. _class_Terrain3DCollision_constant_DYNAMIC_GAME:
+
+.. rst-class:: classref-enumeration-constant
+
+:ref:`CollisionMode` **DYNAMIC_GAME** = ``1``
+
+Collision shapes are generated around the camera as it moves; in game only.
+
+.. _class_Terrain3DCollision_constant_DYNAMIC_EDITOR:
+
+.. rst-class:: classref-enumeration-constant
+
+:ref:`CollisionMode` **DYNAMIC_EDITOR** = ``2``
+
+Collision shapes are generated around the camera as it moves; in the editor and in game. Enable ``View Gizmos`` in the viewport menu to see them.
+
+.. _class_Terrain3DCollision_constant_FULL_GAME:
+
+.. rst-class:: classref-enumeration-constant
+
+:ref:`CollisionMode` **FULL_GAME** = ``3``
+
+Collision shapes are generated for all regions in game only.
+
+.. _class_Terrain3DCollision_constant_FULL_EDITOR:
+
+.. rst-class:: classref-enumeration-constant
+
+:ref:`CollisionMode` **FULL_EDITOR** = ``4``
+
+Collision shapes are generated for all regions in the editor and in game. This mode is necessary for some 3rd party plugins to detect the terrain using collision. Enable ``View Gizmos`` in the viewport menu to see the collision mesh.
+
+.. rst-class:: classref-section-separator
+
+----
+
+.. rst-class:: classref-descriptions-group
+
+Property Descriptions
+---------------------
+
+.. _class_Terrain3DCollision_property_layer:
+
+.. rst-class:: classref-property
+
+``int`` **layer** = ``1`` :ref:`🔗`
+
+.. rst-class:: classref-property-setget
+
+- |void| **set_layer**\ (\ value\: ``int``\ )
+- ``int`` **get_layer**\ (\ )
+
+The physics layers the terrain lives on. Sets ``CollisionObject3D.collision_layer``. Also see :ref:`mask`.
+
+.. rst-class:: classref-item-separator
+
+----
+
+.. _class_Terrain3DCollision_property_mask:
+
+.. rst-class:: classref-property
+
+``int`` **mask** = ``1`` :ref:`🔗`
+
+.. rst-class:: classref-property-setget
+
+- |void| **set_mask**\ (\ value\: ``int``\ )
+- ``int`` **get_mask**\ (\ )
+
+The physics layers the physics body scans for colliding objects. Sets ``CollisionObject3D.collision_mask``. Also see :ref:`layer`.
+
+.. rst-class:: classref-item-separator
+
+----
+
+.. _class_Terrain3DCollision_property_mode:
+
+.. rst-class:: classref-property
+
+:ref:`CollisionMode` **mode** = ``1`` :ref:`🔗`
+
+.. rst-class:: classref-property-setget
+
+- |void| **set_mode**\ (\ value\: :ref:`CollisionMode`\ )
+- :ref:`CollisionMode` **get_mode**\ (\ )
+
+The selected mode determines if collision is generated and how. See :ref:`CollisionMode` for details.
+
+.. rst-class:: classref-item-separator
+
+----
+
+.. _class_Terrain3DCollision_property_priority:
+
+.. rst-class:: classref-property
+
+``float`` **priority** = ``1.0`` :ref:`🔗`
+
+.. rst-class:: classref-property-setget
+
+- |void| **set_priority**\ (\ value\: ``float``\ )
+- ``float`` **get_priority**\ (\ )
+
+The priority with which the physics server uses to solve collisions. The higher the priority, the lower the penetration of a colliding object. Sets ``CollisionObject3D.collision_priority``.
+
+.. rst-class:: classref-item-separator
+
+----
+
+.. _class_Terrain3DCollision_property_radius:
+
+.. rst-class:: classref-property
+
+``int`` **radius** = ``64`` :ref:`🔗`
+
+.. rst-class:: classref-property-setget
+
+- |void| **set_radius**\ (\ value\: ``int``\ )
+- ``int`` **get_radius**\ (\ )
+
+If :ref:`mode` is Dynamic, this is the distance range within which collision shapes will be generated.
+
+.. rst-class:: classref-item-separator
+
+----
+
+.. _class_Terrain3DCollision_property_shape_size:
+
+.. rst-class:: classref-property
+
+``int`` **shape_size** = ``16`` :ref:`🔗`
+
+.. rst-class:: classref-property-setget
+
+- |void| **set_shape_size**\ (\ value\: ``int``\ )
+- ``int`` **get_shape_size**\ (\ )
+
+If :ref:`mode` is Dynamic, this is the size of each collision shape.
+
+.. rst-class:: classref-section-separator
+
+----
+
+.. rst-class:: classref-descriptions-group
+
+Method Descriptions
+-------------------
+
+.. _class_Terrain3DCollision_method_build:
+
+.. rst-class:: classref-method
+
+|void| **build**\ (\ ) :ref:`🔗`
+
+Creates collision shapes and calls :ref:`update` to shape them. Calls :ref:`destroy` first, so it is safe to call this to fully rebuild collision any time.
+
+.. rst-class:: classref-item-separator
+
+----
+
+.. _class_Terrain3DCollision_method_destroy:
+
+.. rst-class:: classref-method
+
+|void| **destroy**\ (\ ) :ref:`🔗`
+
+Removes all collision shapes and frees any memory used.
+
+.. rst-class:: classref-item-separator
+
+----
+
+.. _class_Terrain3DCollision_method_get_rid:
+
+.. rst-class:: classref-method
+
+``RID`` **get_rid**\ (\ ) |const| :ref:`🔗`
+
+Returns the RID of the active StaticBody.
+
+.. rst-class:: classref-item-separator
+
+----
+
+.. _class_Terrain3DCollision_method_is_dynamic_mode:
+
+.. rst-class:: classref-method
+
+``bool`` **is_dynamic_mode**\ (\ ) |const| :ref:`🔗`
+
+Returns true if :ref:`mode` is ``Dynamic / Editor`` or ``Dynamic / Game``.
+
+.. rst-class:: classref-item-separator
+
+----
+
+.. _class_Terrain3DCollision_method_is_editor_mode:
+
+.. rst-class:: classref-method
+
+``bool`` **is_editor_mode**\ (\ ) |const| :ref:`🔗`
+
+Returns true if :ref:`mode` is ``Full / Editor`` or ``Dynamic / Editor``.
+
+.. rst-class:: classref-item-separator
+
+----
+
+.. _class_Terrain3DCollision_method_is_enabled:
+
+.. rst-class:: classref-method
+
+``bool`` **is_enabled**\ (\ ) |const| :ref:`🔗`
+
+Returns true if :ref:`mode` is not ``Disabled``.
+
+.. rst-class:: classref-item-separator
+
+----
+
+.. _class_Terrain3DCollision_method_update:
+
+.. rst-class:: classref-method
+
+|void| **update**\ (\ force\: ``bool`` = false\ ) :ref:`🔗`
+
+- If :ref:`mode` is Full, updates the existing collision shapes. If regions have been added or removed, set ``force`` to true or call :ref:`build` instead. Can be slow.
+
+- If :ref:`mode` is Dynamic, repositions collision shapes around the camera and recalculated ones not already in place, skipping those that are. Set ``force`` to true to recalculate all shapes. This is very fast, and can be updated at 60fps for little cost.
+
+.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
+.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
+.. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`
+.. |constructor| replace:: :abbr:`constructor (This method is used to construct a type.)`
+.. |static| replace:: :abbr:`static (This method doesn't need an instance to be called, so it can be called directly using the class name.)`
+.. |operator| replace:: :abbr:`operator (This method describes a valid operator to use with this type as left-hand operand.)`
+.. |bitfield| replace:: :abbr:`BitField (This value is an integer composed as a bitmask of the following flags.)`
+.. |void| replace:: :abbr:`void (No return value.)`
diff --git a/doc/api/class_terrain3ddata.rst b/doc/api/class_terrain3ddata.rst
index c526ba4c..0ec6badd 100644
--- a/doc/api/class_terrain3ddata.rst
+++ b/doc/api/class_terrain3ddata.rst
@@ -140,7 +140,7 @@ Methods
+----------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`load_directory`\ (\ directory\: ``String``\ ) |
+----------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
- | |void| | :ref:`load_region`\ (\ directory\: ``Vector2i``, region_location\: ``String``, update\: ``bool`` = true\ ) |
+ | |void| | :ref:`load_region`\ (\ region_location\: ``Vector2i``, directory\: ``String``, update\: ``bool`` = true\ ) |
+----------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`remove_region`\ (\ region\: :ref:`Terrain3DRegion`, update\: ``bool`` = true\ ) |
+----------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
@@ -150,7 +150,7 @@ Methods
+----------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`save_directory`\ (\ directory\: ``String``\ ) |
+----------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
- | |void| | :ref:`save_region`\ (\ directory\: ``Vector2i``, region_location\: ``String``, 16_bit\: ``bool`` = false\ ) |
+ | |void| | :ref:`save_region`\ (\ region_location\: ``Vector2i``, directory\: ``String``, 16_bit\: ``bool`` = false\ ) |
+----------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`set_color`\ (\ global_position\: ``Vector3``, color\: ``Color``\ ) |
+----------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
@@ -1047,7 +1047,7 @@ Loads all of the Terrain3DRegion files found in the specified directory. Then it
.. rst-class:: classref-method
-|void| **load_region**\ (\ directory\: ``Vector2i``, region_location\: ``String``, update\: ``bool`` = true\ ) :ref:`🔗`
+|void| **load_region**\ (\ region_location\: ``Vector2i``, directory\: ``String``, update\: ``bool`` = true\ ) :ref:`🔗`
Loads the specified region location file.
@@ -1109,7 +1109,7 @@ This saves all active regions into the specified directory.
.. rst-class:: classref-method
-|void| **save_region**\ (\ directory\: ``Vector2i``, region_location\: ``String``, 16_bit\: ``bool`` = false\ ) :ref:`🔗`
+|void| **save_region**\ (\ region_location\: ``Vector2i``, directory\: ``String``, 16_bit\: ``bool`` = false\ ) :ref:`🔗`
Saves the specified active region to the directory. See :ref:`Terrain3DRegion.save`.
diff --git a/doc/api/index.rst b/doc/api/index.rst
index 47fd33e1..cfc9ed7b 100644
--- a/doc/api/index.rst
+++ b/doc/api/index.rst
@@ -20,6 +20,7 @@ Variant types
class_variant
class_terrain3d
class_terrain3dassets
+ class_terrain3dcollision
class_terrain3ddata
class_terrain3deditor
class_terrain3dinstancer
diff --git a/doc/build_docs.sh b/doc/build_docs.sh
index 50fd0a9d..51d9fa23 100644
--- a/doc/build_docs.sh
+++ b/doc/build_docs.sh
@@ -5,17 +5,18 @@ REPO=`git rev-parse --show-toplevel`
pushd $REPO
-echo Running Godot to dump XML files
+echo --- Running Godot to dump XML files
cd $REPO/project
$GODOT --doctool ../doc --gdextension-docs
cd $REPO/doc
-echo Running make_rst.py to produce sphinx output
+echo --- Running make_rst.py to produce sphinx output
$MAKERST --verbose --filter Terrain3D --output api path doc_classes/ 2>&1 | egrep -v 'Unresolved (type|enum)'
+echo --- Generating html
make clean
-make html 2>&1 | grep -Pv 'WARNING: undefined label: (?!'\''class_terrain3d)' | egrep -v '(local id not found|copying images|writing output|reading sources)...'
+make html 2>&1 | grep -Pv 'WARNING: undefined label: (?!'\''class_terrain3d)' | egrep -v '(local id not found|copying images|writing output|reading sources|toctree contains reference .+api/class_variant)'
start _build/html/index.html
popd
diff --git a/doc/doc_classes/Terrain3D.xml b/doc/doc_classes/Terrain3D.xml
index dec7bb62..0711bd81 100644
--- a/doc/doc_classes/Terrain3D.xml
+++ b/doc/doc_classes/Terrain3D.xml
@@ -4,7 +4,7 @@
Terrain3D is a high performance, editable terrain system for Godot 4. It provides a clipmap based terrain that supports terrains from 64x64m up to 65.5x65.5km with multiple LODs, 32 textures, and editor tools for importing or creating terrains.
- This class handles mesh and collision generation, and management of the whole system. See [url=https://terrain3d.readthedocs.io/en/stable/docs/system_architecture.html]System Architecture[/url] for design details.
+ This class handles mesh generation, and management of the whole system. See [url=https://terrain3d.readthedocs.io/en/stable/docs/system_architecture.html]System Architecture[/url] for design details.
@@ -35,12 +35,6 @@
Returns the camera the terrain is currently snapping to.
-
-
-
- Returns the RID of the active StaticBody.
-
-
@@ -83,6 +77,12 @@
Returns the EditorPlugin connected to Terrain3D.
+
+
+
+ Returns the last position the terrain was centered on.
+
+
@@ -118,22 +118,26 @@
Tells the renderer how to cast shadows from the terrain onto other objects. This sets [code skip-lint]GeometryInstance3D.ShadowCastingSetting[/code] in the engine.
-
- If enabled, collision is generated according to the mode selected. By default collision is generated for all regions at run time only using the physics server. Also see [member collision_mode].
+
+ The active [Terrain3DCollision] object.
- The physics layers the terrain lives in. Also see [member collision_mask].
+ Alias for [member Terrain3DCollision.layer].
- The physics layers the terrain scans for colliding objects. Also see [member collision_layer].
+ Alias for [member Terrain3DCollision.mask].
-
- If collision is enabled, collision_mode specifies when and where collision is generated:
- * FULL_GAME - all regions are generated at startup in game only.
- * FULL_GAME - all regions are generated in the editor. Necessary for some 3rd party plugins to find the terrain. The collision mesh can also be made visible in the editor by enabling [code skip-lint]View Gizmos[/code] in the viewport menu.
+
+ Alias for [member Terrain3DCollision.mode].
- The priority used to solve collisions. The higher priority, the lower the penetration of a colliding object.
+ Alias for [member Terrain3DCollision.priority].
+
+
+ Alias for [member Terrain3DCollision.radius].
+
+
+ Alias for [member Terrain3DCollision.shape_size].
This margin is added to the vertical component of the terrain bounding box (AABB). The terrain already sets its AABB from [method Terrain3DData.get_height_range], which is calculated while sculpting. This setting only needs to be used if the shader has expanded the terrain beyond the AABB and the terrain meshes are being culled at certain viewing angles. This might happen from using [member Terrain3DMaterial.world_background] with NOISE and a height value larger than the terrain heights. This setting is similar to [code skip-lint]GeometryInstance3D.extra_cull_margin[/code], but it only affects the Y axis.
@@ -279,11 +283,5 @@
The region size is 2048 x 2048 meters, vertices, and pixels on Image maps.
-
- Generates collision for all regions in game only.
-
-
- Generates collision for all regions in the editor and in game.
-
diff --git a/doc/doc_classes/Terrain3DCollision.xml b/doc/doc_classes/Terrain3DCollision.xml
new file mode 100644
index 00000000..ef09956d
--- /dev/null
+++ b/doc/doc_classes/Terrain3DCollision.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+ This class manages collision.
+
+
+
+
+
+
+
+ Creates collision shapes and calls [method update] to shape them. Calls [method destroy] first, so it is safe to call this to fully rebuild collision any time.
+
+
+
+
+
+ Removes all collision shapes and frees any memory used.
+
+
+
+
+
+ Returns the RID of the active StaticBody.
+
+
+
+
+
+ Returns true if [member mode] is [code skip-lint]Dynamic / Editor[/code] or [code skip-lint]Dynamic / Game[/code].
+
+
+
+
+
+ Returns true if [member mode] is [code skip-lint]Full / Editor[/code] or [code skip-lint]Dynamic / Editor[/code].
+
+
+
+
+
+ Returns true if [member mode] is not [code skip-lint]Disabled[/code].
+
+
+
+
+
+
+ - If [member mode] is Full, updates the existing collision shapes. If regions have been added or removed, set [code skip-lint]force[/code] to true or call [method build] instead. Can be slow.
+ - If [member mode] is Dynamic, repositions collision shapes around the camera and recalculated ones not already in place, skipping those that are. Set [code skip-lint]force[/code] to true to recalculate all shapes. This is very fast, and can be updated at 60fps for little cost.
+
+
+
+
+
+ The physics layers the terrain lives on. Sets [code skip-lint]CollisionObject3D.collision_layer[/code]. Also see [member mask].
+
+
+ The physics layers the physics body scans for colliding objects. Sets [code skip-lint]CollisionObject3D.collision_mask[/code]. Also see [member layer].
+
+
+ The selected mode determines if collision is generated and how. See [enum CollisionMode] for details.
+
+
+ The priority with which the physics server uses to solve collisions. The higher the priority, the lower the penetration of a colliding object. Sets [code skip-lint]CollisionObject3D.collision_priority[/code].
+
+
+ If [member mode] is Dynamic, this is the distance range within which collision shapes will be generated.
+
+
+ If [member mode] is Dynamic, this is the size of each collision shape.
+
+
+
+
+ No collision shapes will be generated.
+
+
+ Collision shapes are generated around the camera as it moves; in game only.
+
+
+ Collision shapes are generated around the camera as it moves; in the editor and in game. Enable [code skip-lint]View Gizmos[/code] in the viewport menu to see them.
+
+
+ Collision shapes are generated for all regions in game only.
+
+
+ Collision shapes are generated for all regions in the editor and in game. This mode is necessary for some 3rd party plugins to detect the terrain using collision. Enable [code skip-lint]View Gizmos[/code] in the viewport menu to see the collision mesh.
+
+
+
diff --git a/doc/doc_classes/Terrain3DData.xml b/doc/doc_classes/Terrain3DData.xml
index f8e6dec7..4867170e 100644
--- a/doc/doc_classes/Terrain3DData.xml
+++ b/doc/doc_classes/Terrain3DData.xml
@@ -389,8 +389,8 @@
-
-
+
+
Loads the specified region location file.
@@ -430,8 +430,8 @@
-
-
+
+
Saves the specified active region to the directory. See [method Terrain3DRegion.save].
diff --git a/doc/docs/collision.md b/doc/docs/collision.md
index 0407e2bc..171c09a4 100644
--- a/doc/docs/collision.md
+++ b/doc/docs/collision.md
@@ -10,13 +10,13 @@ You should use raycasting only when you don't already know the X, Z of the colli
Collision is generated at runtime using the physics server. Regular PhysicsBodies will interact with this collision as expected. To detect ground height, use a [ray cast](https://docs.godotengine.org/en/stable/tutorials/physics/ray-casting.html). There is no collision outside of regions, so raycasts won't hit.
-Normally the editor doesn't generate collision, but some addons or other activities do need editor collision. To generate it, set `Terrain3D/Collision/Collision Mode`, or `Terrain3D.collision_mode`, to `Full / Editor`. You can run in game with this enabled.
+Normally the editor doesn't generate collision, but some addons or other activities do need editor collision. To generate it, set `Terrain3D/Collision/Collision Mode`, or `Terrain3D.collision.mode`, to `Full / Editor` or `Dynamic / Editor`. You can run in game with this enabled.
-This option will generate collision one time when enabled or at startup. If the terrain is sculpted afterwards, this collision will be inaccurate to the visual mesh until collision is disabled and enabled again. On a Core-i9 12900H, generating collision takes about 145ms per 1024m region, so updating it several times per second while sculpting is not practical. Currently all regions are regenerated, rather than only modified regions so it is not optimal. You can follow [PR#278](https://github.com/TokisanGames/Terrain3D/pull/278) for an improved system.
+Full mode will generate collision for all regions when enabled or at startup. It's a bit slow due to the amount of data. Dynamic mode will generate a small area around the camera and can be updated on the fly.
-See the [Terrain3D API](../api/class_terrain3d.rst) for various functions that configure the collision priority, layers, and mask.
+See the [Terrain3DCollision API](../api/class_terrain3dcollision.rst) for various functions to configure other properties like layers, mask, and priority.
-Finally, Godot Physics is far from perfect. If you have issues with raycasts or other physics calculations, try switching to Jolt. Also if your raycast is perfectly vertical, you can try angling it ever so slightly, or use get_height().
+Finally, Godot Physics is far from perfect. If you have issues with raycasts or other physics calculations, try switching to Jolt. Also if your raycast is perfectly vertical, you can try angling it ever so slightly, or use an option below.
## Raycasting Without Physics
@@ -65,16 +65,34 @@ However, note that `get_height()` above will [interpolate between vertices](http
## Additional Tips
-### Getting The Normal
+### Visualizing Collision
-After getting the height, you may also wish to get the normal with `Terrain3DData.get_normal(global_position)`. The normal is a Vector3 that points perpendulcar to the terrain face.
+To see the collision shape, first set `Terrain3D/Collision/Collision Mode` to `Full / Editor` or `Dynamic / Editor`.
+To see it in the editor, in the Godot `Perspective` menu, enable `View Gizmos`. Avoid using the Full option on slow systems.
-### Visualizing Collision
+To see debug collision in game, in the Godot `Debug` menu, enable `Visible Collision Shapes` and run the scene.
-To see the collision shape, first set `Terrain3D/Collision/Collision Mode` to `Full / Editor`.
-To see it in the editor, in the Godot `Perspective` menu, enable `View Gizmos`. Disable this option on slow systems.
+### Enemy Collision
-To see debug collision in game, in the Godot `Debug` menu, enable `Visible Collision Shapes` and run the scene.
+The easy approach is to give every enemy a capsule collision shape, and start creating your level. As you fill your level with terrain, rocks, caves, canyons, and dungeons, you'll quickly learn that this approach is terrible for performance.
+
+Your system will be brought to its knees when you have 5-10 enemies follow the player into a tight area with many faceted collision shapes. The physics server will need to calculate collisions against hundreds of faces in the area for each of the 10 character bodies.
+
+A better alternative is to use physics collision only for the player, and use raycasts for the enemies. This allows you to limit the collision checks to a few per enemy, regardless of how many collision faces there are.
+
+However both methods above require collision shapes where the enemy is. What if you want to have enemies stay on the ground when far from the camera, while using a dynamic collision mode?
+Have each enemy query `Terrain3DData.get_height()`, either in conjunction with checking height with a raycast or physics, or in place of. It could come right after applying gravity so it will snap back to the surface if it dips below.
+
+e.g.
+```
+ global_position.y -= gravity * p_delta
+ global_position.y = maxf(global_position.y, terrain.data.get_height(global_position))
+```
+
+
+### Retreiving The Normal
+
+After getting the height, you may also wish to get the normal with `Terrain3DData.get_normal(global_position)`. The normal is a Vector3 that points perpendulcar to the terrain face.
diff --git a/doc/docs/games.md b/doc/docs/games.md
index b47dbef9..e42bf878 100644
--- a/doc/docs/games.md
+++ b/doc/docs/games.md
@@ -7,6 +7,7 @@ Terrain3D is being used in the following games. To add yours, submit it to the #
|------|--------|-------------|
| [Out of the Ashes](https://store.steampowered.com/app/2296950/Out_of_the_Ashes/) | [Tokisan Games](https://twitter.com/TokisanGames) | Story driven medieval adventure
| [Memora Wanderer](https://store.steampowered.com/app/2937690/Memora_Wanderer/) | [Maytch](https://twitter.com/Maytch) | Cute nostalgic RPG
+| [Black Pellet](https://www.kickstarter.com/projects/raiseledwards/black-pellet) | [BlackPelletGame](https://x.com/BlackPelletGame) | Claymation, Western, TPS, Open world, Action-adventure
| [No Gasoline](https://store.steampowered.com/app/2835350/No_Gasoline/) | [Mount Retro](https://twitter.com/mountretro) | Co-Op/Solo, Adventure-Simulation-Puzzle
| [RotorSim](https://immaculate-lift-studio.itch.io/godot-flight-simulator-alpha) | [Immaculate Lift](https://www.youtube.com/channel/UC-9JixNs1FFE6T5DGwZ6O5Q) | Retro helicopter simulation
| [B&E Ski](https://www.youtube.com/watch?v=pD8Ea3utz9o) | [Penguin Milk](https://bande.ski/) | Skiing game