Refactors grass and tree spawning for seed consistency
Updates grass and tree spawning to use the parent's RNG, ensuring consistent random generation based on the seed. This removes redundant RNG instances and ensures that grass and trees are generated predictably for a given cell.
This commit is contained in:
parent
e7337bede6
commit
33c525a3c0
2 changed files with 40 additions and 42 deletions
|
|
@ -1,54 +1,51 @@
|
|||
# GrassMultiMesh.gd
|
||||
extends MultiMeshInstance3D
|
||||
var mm: MultiMesh
|
||||
var parent_node: GrassController
|
||||
var rng: RandomClass = RandomClass.new()
|
||||
|
||||
static var grass_mesh: Mesh = null
|
||||
|
||||
func _ready() -> void:
|
||||
parent_node = get_parent() as GrassController
|
||||
if parent_node == null:
|
||||
Log.pr("Error: Parent node is not a GrassController!")
|
||||
|
||||
# Load mesh once and reuse
|
||||
if grass_mesh == null:
|
||||
grass_mesh = load("res://Stages/Test3D/assets/stylizedGrassMeshes/grass2_mesh.res")
|
||||
|
||||
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:
|
||||
if grass_mesh == null:
|
||||
Log.pr("Error: Could not load grass mesh")
|
||||
return
|
||||
|
||||
# Create new MultiMesh instance
|
||||
mm = MultiMesh.new()
|
||||
# Reuse existing MultiMesh if possible, or create new one
|
||||
if mm == null:
|
||||
mm = MultiMesh.new()
|
||||
mm.transform_format = MultiMesh.TRANSFORM_3D
|
||||
mm.mesh = grass_mesh
|
||||
|
||||
# Configure the MultiMesh
|
||||
mm.transform_format = MultiMesh.TRANSFORM_3D
|
||||
# Configure instance count
|
||||
mm.instance_count = parent_node.grass_instance_range
|
||||
mm.mesh = mesh
|
||||
|
||||
# Generate random positions for grass using seeded RNG
|
||||
# Generate positions using shared RNG
|
||||
for i in range(mm.instance_count):
|
||||
var random_pos = Vector3(
|
||||
rng.randf_range(-1.0, 1.0),
|
||||
parent_node.parent_node.rng.randf_range(-1.0, 1.0),
|
||||
0.0,
|
||||
rng.randf_range(-1.0, 1.0)
|
||||
parent_node.parent_node.rng.randf_range(-1.0, 1.0)
|
||||
)
|
||||
|
||||
var random_rotation = rng.randf_range(0.0, TAU)
|
||||
var random_rotation = parent_node.parent_node.rng.randf_range(0.0, TAU)
|
||||
var basis = Basis(Vector3.UP, random_rotation)
|
||||
|
||||
var random_scale = rng.randf_range(0.05, 0.3)
|
||||
var random_scale = parent_node.parent_node.rng.randf_range(0.05, 0.3)
|
||||
basis = basis.scaled(Vector3(random_scale, random_scale, random_scale))
|
||||
|
||||
var tx = Transform3D(basis, random_pos)
|
||||
mm.set_instance_transform(i, tx)
|
||||
|
||||
# Assign the MultiMesh to this node
|
||||
multimesh = mm
|
||||
cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
||||
|
|
|
|||
|
|
@ -5,21 +5,36 @@ extends Node3D
|
|||
@export var min_distance: float = 0.5
|
||||
var spawned_positions: Array[Vector3] = []
|
||||
var parent_ground_tile: GroundTile
|
||||
var rng: RandomClass = RandomClass.new()
|
||||
# Remove this line: var rng: RandomClass = RandomClass.new()
|
||||
|
||||
func _ready():
|
||||
parent_ground_tile = get_parent() as GroundTile
|
||||
|
||||
|
||||
func spawn_trees_for_cell(cell_info: CellDataResource):
|
||||
if not cell_info:
|
||||
return
|
||||
return
|
||||
|
||||
rng.set_seed(cell_info.cell_seed)
|
||||
# Use parent's RNG instead of creating new one
|
||||
if not parent_ground_tile or not parent_ground_tile.rng:
|
||||
return
|
||||
|
||||
var tree_count = max(0, cell_info.trees.size())
|
||||
spawn_trees(tree_count)
|
||||
|
||||
# Update all rng calls to use parent_ground_tile.rng:
|
||||
func get_random_position() -> Vector3:
|
||||
var x = parent_ground_tile.rng.randf_range(-spawn_area_size.x / 2, spawn_area_size.x / 2)
|
||||
var z = parent_ground_tile.rng.randf_range(-spawn_area_size.y / 2, spawn_area_size.y / 2)
|
||||
return Vector3(x, 0, z)
|
||||
|
||||
func spawn_tree_at_position(pos: Vector3):
|
||||
var random_index = parent_ground_tile.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
|
||||
tree_instance.rotation.y = parent_ground_tile.rng.randf() * TAU
|
||||
|
||||
func spawn_trees(tree_count: int):
|
||||
if tree_scenes.is_empty() or tree_count == 0:
|
||||
return
|
||||
|
|
@ -42,22 +57,8 @@ func spawn_trees(tree_count: int):
|
|||
|
||||
attempts += 1
|
||||
|
||||
# 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:
|
||||
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):
|
||||
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
|
||||
tree_instance.rotation.y = rng.randf() * TAU
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue