Loads of crap

This commit is contained in:
Dan Baker 2025-06-26 14:46:23 +01:00
parent b5bf7619e6
commit 1dc768ad27
725 changed files with 15096 additions and 191 deletions

View file

@ -2,39 +2,23 @@
extends Node3D
class_name GrassController
# 229379
@onready var grass_multimesh: MultiMeshInstance3D = $GrassMultimesh
var parent_node: GroundTile = null
var grass_density: float = 0.5
var grass_instance_range: int = 10
signal grass_data_ready()
func _ready() -> void:
# Use call_deferred to ensure parent is fully ready
call_deferred("_setup_connections")
func _setup_connections() -> void:
parent_node = get_parent() as GroundTile
if parent_node == null:
Log.pr("Error: Parent node is not a GroundTile!")
return
parent_node.cell_info_updated.connect(_on_parent_data_changed)
# Check if cell_info already exists and process it
if parent_node.cell_info != null:
_on_parent_data_changed(parent_node.cell_info)
func _on_parent_data_changed(value):
func spawn_grass_for_cell(value):
if value == null:
return
grass_density = value.vegetation_density
update_grass_density()
grass_data_ready.emit()
if grass_multimesh and grass_multimesh.has_method("setup_multimesh"):
grass_multimesh.setup_multimesh()
func update_grass_density() -> void:
if parent_node == null or parent_node.rng == null:

View file

@ -1,31 +1,23 @@
# GrassMultiMesh.gd (assuming this is your MultiMeshInstance3D script)
# GrassMultiMesh.gd
extends MultiMeshInstance3D
var mm: MultiMesh
@onready var parent_node: GrassController
var parent_node: GrassController
var rng: RandomClass = RandomClass.new()
func _ready() -> void:
# Use call_deferred to ensure proper initialization order
call_deferred("_setup_connections")
func _setup_connections() -> void:
parent_node = get_parent() as GrassController
if parent_node == null:
Log.pr("Error: Parent node is not a GrassController!")
return
parent_node.grass_data_ready.connect(_on_grass_data_ready)
Log.pr("Connected to grass_data_ready signal")
func _on_grass_data_ready():
Log.pr("Received grass_data_ready signal, setting up multimesh")
setup_multimesh()
func setup_multimesh() -> void:
if parent_node == null:
Log.pr("Error: Parent node not available in setup_multimesh")
return
# Use the same RNG seed as the parent for consistency
if parent_node.parent_node and parent_node.parent_node.cell_info:
rng.set_seed(parent_node.parent_node.cell_info.cell_seed)
# Load the mesh resource directly
var mesh = load("res://Stages/Test3D/assets/stylizedGrassMeshes/grass2_mesh.res")
if mesh == null:
@ -40,20 +32,18 @@ func setup_multimesh() -> void:
mm.instance_count = parent_node.grass_instance_range
mm.mesh = mesh
Log.pr("Setting up MultiMesh with " + str(mm.instance_count) + " instances")
# Generate random positions for grass
# Generate random positions for grass using seeded RNG
for i in range(mm.instance_count):
var random_pos = Vector3(
randf_range(-1.0, 1.0),
rng.randf_range(-1.0, 1.0),
0.0,
randf_range(-1.0, 1.0)
rng.randf_range(-1.0, 1.0)
)
var random_rotation = randf_range(0.0, TAU)
var random_rotation = rng.randf_range(0.0, TAU)
var basis = Basis(Vector3.UP, random_rotation)
var random_scale = randf_range(0.05, 0.3)
var random_scale = rng.randf_range(0.05, 0.3)
basis = basis.scaled(Vector3(random_scale, random_scale, random_scale))
var tx = Transform3D(basis, random_pos)
@ -62,5 +52,3 @@ func setup_multimesh() -> void:
# Assign the MultiMesh to this node
multimesh = mm
cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
Log.pr("MultiMesh setup complete with " + str(multimesh.instance_count) + " instances")

View file

@ -1,63 +1,37 @@
extends Node3D
# Array of tree scenes to randomly choose from
@export var tree_scenes: Array[PackedScene] = []
@export var spawn_area_size: Vector2 = Vector2(2.0, 2.0) # 2x2 area
@export var max_trees: int = 3 # Maximum possible trees
@export var min_distance: float = 0.5 # Minimum distance between trees
@export var spawn_area_size: Vector2 = Vector2(2.0, 2.0)
@export var max_trees: int = 3
@export var min_distance: float = 0.5
var spawned_positions: Array[Vector3] = []
var parent_ground_tile: GroundTile
var rng: RandomClass
var rng: RandomClass = RandomClass.new()
func _ready():
# Get reference to parent GroundTile
parent_ground_tile = get_parent() as GroundTile
if parent_ground_tile:
# Connect to the signal
parent_ground_tile.cell_info_updated.connect(_on_cell_info_updated)
# If cell_info already exists, spawn trees immediately
if parent_ground_tile.cell_info != null:
_on_cell_info_updated(parent_ground_tile.cell_info)
func _on_cell_info_updated(cell_info: CellDataResource):
# Initialize RNG with the cell's seed for consistent results
rng = RandomClass.new()
func spawn_trees_for_cell(cell_info: CellDataResource):
if not cell_info:
return
rng.set_seed(cell_info.cell_seed)
# Calculate number of trees based on vegetation_density
var tree_count = calculate_tree_count(cell_info.vegetation_density)
# Spawn the trees
var tree_count = max(0, cell_info.trees.size())
spawn_trees(tree_count)
func calculate_tree_count(vegetation_density: float) -> int:
if vegetation_density < 0.7:
return 0
# vegetation_density should be between 0.0 and 1.0
# Scale it to our max_trees range
var scaled_count = vegetation_density * max_trees
# Round to nearest integer, but ensure at least 0
return max(0, int(round(scaled_count)))
func spawn_trees(tree_count: int):
if tree_scenes.is_empty():
print("No tree scenes assigned!")
if tree_scenes.is_empty() or tree_count == 0:
return
if tree_count == 0:
print("No trees to spawn (vegetation_density too low)")
return
# Clear existing trees WITHOUT queue_free()
for child in get_children():
child.free() # Immediate cleanup instead of queue_free()
spawned_positions.clear()
# Clear any existing trees
clear_trees()
# Try to place trees
# Spawn new trees
var attempts = 0
var max_attempts = tree_count * 10 # Prevent infinite loops
var max_attempts = tree_count * 10
while spawned_positions.size() < tree_count and attempts < max_attempts:
var pos = get_random_position()
@ -67,39 +41,23 @@ func spawn_trees(tree_count: int):
spawned_positions.append(pos)
attempts += 1
print("Spawned ", spawned_positions.size(), " trees")
# Rest of your functions stay the same...
func get_random_position() -> Vector3:
var x = rng.randf_range(-spawn_area_size.x / 2, spawn_area_size.x / 2)
var z = rng.randf_range(-spawn_area_size.y / 2, spawn_area_size.y / 2)
return Vector3(x, 0, z)
func is_position_valid(pos: Vector3) -> bool:
# Check if position is too close to existing trees
for existing_pos in spawned_positions:
if pos.distance_to(existing_pos) < min_distance:
return false
return true
func spawn_tree_at_position(pos: Vector3):
# Pick a random tree scene using the seeded RNG
var random_index = rng.randi() % tree_scenes.size()
var random_tree_scene = tree_scenes[random_index]
var tree_instance = random_tree_scene.instantiate()
add_child(tree_instance)
tree_instance.position = pos
# Optional: Add some random rotation using seeded RNG
tree_instance.rotation.y = rng.randf() * TAU
func clear_trees():
# Remove all existing tree children
for child in get_children():
child.queue_free()
spawned_positions.clear()
# Call this if you want to respawn trees manually
func respawn_trees():
if parent_ground_tile and parent_ground_tile.cell_info:
_on_cell_info_updated(parent_ground_tile.cell_info)