aboutsummaryrefslogtreecommitdiff
path: root/game/addons/zylann.hterrain/hterrain_chunk.gd
diff options
context:
space:
mode:
Diffstat (limited to 'game/addons/zylann.hterrain/hterrain_chunk.gd')
-rw-r--r--game/addons/zylann.hterrain/hterrain_chunk.gd125
1 files changed, 125 insertions, 0 deletions
diff --git a/game/addons/zylann.hterrain/hterrain_chunk.gd b/game/addons/zylann.hterrain/hterrain_chunk.gd
new file mode 100644
index 0000000..400a057
--- /dev/null
+++ b/game/addons/zylann.hterrain/hterrain_chunk.gd
@@ -0,0 +1,125 @@
+@tool
+
+var cell_origin_x := 0
+var cell_origin_y := 0
+
+var _visible : bool
+# This is true when the chunk is meant to be displayed.
+# A chunk can be active and hidden (due to the terrain being hidden).
+var _active : bool
+
+var _pending_update : bool
+
+var _mesh_instance : RID
+# Need to keep a reference so that the mesh RID doesn't get freed
+# TODO Use RID directly, no need to keep all those meshes in memory
+var _mesh : Mesh = null
+
+
+# TODO p_parent is HTerrain, can't add type hint due to cyclic reference
+func _init(p_parent: Node3D, p_cell_x: int, p_cell_y: int, p_material: Material):
+ assert(p_parent is Node3D)
+ assert(typeof(p_cell_x) == TYPE_INT)
+ assert(typeof(p_cell_y) == TYPE_INT)
+ assert(p_material is Material)
+
+ cell_origin_x = p_cell_x
+ cell_origin_y = p_cell_y
+
+ var rs := RenderingServer
+
+ _mesh_instance = rs.instance_create()
+
+ if p_material != null:
+ rs.instance_geometry_set_material_override(_mesh_instance, p_material.get_rid())
+
+ var world := p_parent.get_world_3d()
+ if world != null:
+ rs.instance_set_scenario(_mesh_instance, world.get_scenario())
+
+ _visible = true
+ # TODO Is this needed?
+ rs.instance_set_visible(_mesh_instance, _visible)
+
+ _active = true
+ _pending_update = false
+
+
+func _notification(p_what: int):
+ if p_what == NOTIFICATION_PREDELETE:
+ if _mesh_instance != RID():
+ RenderingServer.free_rid(_mesh_instance)
+ _mesh_instance = RID()
+
+
+func is_active() -> bool:
+ return _active
+
+
+func set_active(a: bool):
+ _active = a
+
+
+func is_pending_update() -> bool:
+ return _pending_update
+
+
+func set_pending_update(p: bool):
+ _pending_update = p
+
+
+func enter_world(world: World3D):
+ assert(_mesh_instance != RID())
+ RenderingServer.instance_set_scenario(_mesh_instance, world.get_scenario())
+
+
+func exit_world():
+ assert(_mesh_instance != RID())
+ RenderingServer.instance_set_scenario(_mesh_instance, RID())
+
+
+func parent_transform_changed(parent_transform: Transform3D):
+ assert(_mesh_instance != RID())
+ var local_transform := Transform3D(Basis(), Vector3(cell_origin_x, 0, cell_origin_y))
+ var world_transform := parent_transform * local_transform
+ RenderingServer.instance_set_transform(_mesh_instance, world_transform)
+
+
+func set_mesh(mesh: Mesh):
+ assert(_mesh_instance != RID())
+ if mesh == _mesh:
+ return
+ RenderingServer.instance_set_base(_mesh_instance, mesh.get_rid() if mesh != null else RID())
+ _mesh = mesh
+
+
+func set_material(material: Material):
+ assert(_mesh_instance != RID())
+ RenderingServer.instance_geometry_set_material_override( \
+ _mesh_instance, material.get_rid() if material != null else RID())
+
+
+func set_visible(visible: bool):
+ assert(_mesh_instance != RID())
+ RenderingServer.instance_set_visible(_mesh_instance, visible)
+ _visible = visible
+
+
+func is_visible() -> bool:
+ return _visible
+
+
+func set_aabb(aabb: AABB):
+ assert(_mesh_instance != RID())
+ RenderingServer.instance_set_custom_aabb(_mesh_instance, aabb)
+
+
+func set_render_layer_mask(mask: int):
+ assert(_mesh_instance != RID())
+ RenderingServer.instance_set_layer_mask(_mesh_instance, mask)
+
+
+func set_cast_shadow_setting(setting: int):
+ assert(_mesh_instance != RID())
+ RenderingServer.instance_geometry_set_cast_shadows_setting(_mesh_instance, setting)
+