Ground plane now takes up the camera frame

This commit is contained in:
hz
2025-11-07 14:18:47 -06:00
parent 631928c943
commit a5fc35fb0e
2 changed files with 47 additions and 3 deletions
+1
View File
@@ -43,6 +43,7 @@ columns = 10
rows = 10
cell_size = 1.0
ground_thickness = 0.4
ground_padding = null
show_grid_lines = true
grid_line_color = Color(0.2, 0.7, 1, 0.65)
+46 -3
View File
@@ -60,6 +60,17 @@ var _ground_thickness: float = 0.4
get:
return _ground_thickness
var _ground_padding: float = 20.0
@export_range(0.0, 200.0, 1.0) var ground_padding: float:
set(value):
value = max(value, 0.0)
if is_equal_approx(value, _ground_padding):
return
_ground_padding = value
_update_ground_assets()
get:
return _ground_padding
var _show_grid_lines: bool = true
@export var show_grid_lines: bool:
set(value):
@@ -137,19 +148,20 @@ func _rebuild_grid() -> void:
_generate_hex_grid()
_:
_generate_square_grid()
_update_ground_assets()
_update_grid_lines()
_update_highlight_mesh()
_update_camera_view()
_update_ground_assets()
emit_signal("grid_layout_changed", _cells)
func _update_ground_assets() -> void:
var required_size := _compute_required_ground_size()
if _ground_mesh and _ground_mesh.mesh is PlaneMesh:
var plane_mesh := _ground_mesh.mesh as PlaneMesh
plane_mesh.size = _grid_size
plane_mesh.size = required_size
if _ground_collision and _ground_collision.shape is BoxShape3D:
var box := _ground_collision.shape as BoxShape3D
box.size = Vector3(_grid_size.x, _ground_thickness, _grid_size.y)
box.size = Vector3(required_size.x, _ground_thickness, required_size.y)
func _generate_square_grid() -> void:
_hex_center_offset_local = Vector3.ZERO
@@ -354,6 +366,37 @@ func _update_camera_view() -> void:
var desired_position: Vector3 = target + offset_global
_camera.look_at_from_position(desired_position, target, Vector3.UP)
func _compute_required_ground_size() -> Vector2:
var base_half := Vector2(_grid_size.x * 0.5, _grid_size.y * 0.5)
var half_extents := base_half
if is_instance_valid(_camera) and not Engine.is_editor_hint():
var viewport := get_viewport()
if viewport:
var view_size: Vector2 = viewport.get_visible_rect().size
var corners := [
Vector2.ZERO,
Vector2(view_size.x, 0),
Vector2(0, view_size.y),
view_size
]
var plane_normal: Vector3 = global_transform.basis.y.normalized()
var plane_point: Vector3 = global_transform.origin
for corner in corners:
var origin := _camera.project_ray_origin(corner)
var direction := _camera.project_ray_normal(corner)
var denominator := plane_normal.dot(direction)
if abs(denominator) < 0.0001:
continue
var t := plane_normal.dot(plane_point - origin) / denominator
if t <= 0.0:
continue
var world_point := origin + direction * t
var local_point := to_local(world_point)
half_extents.x = max(half_extents.x, abs(local_point.x))
half_extents.y = max(half_extents.y, abs(local_point.z))
var padding_vec := Vector2.ONE * _ground_padding
return (half_extents + padding_vec) * 2.0
func _process(_delta: float) -> void:
if Engine.is_editor_hint():
return