nature-sim/Entities/GroundTile/scripts/grass_multimesh.gd
Dan Baker 3959333534 Adds bushes and flowers to ground tiles
Implements bush and flower spawning on ground tiles based on vegetation density.
Adds new assets for bushes and flowers, and introduces multi-mesh rendering for optimized performance.
Introduces seasonal color variations for vegetation using a shader for bushes and materials for flowers and grass.
Refactors material application into a MaterialManager to handle material assignments over multiple frames.
Moves ground tile scripts into a subfolder.
Adds floating particles to test scene.
2025-06-29 10:58:18 +01:00

70 lines
2 KiB
GDScript

extends MultiMeshInstance3D
var mm: MultiMesh
var parent_node: GrassController
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:
return
if grass_mesh == null:
Log.pr("Error: Could not load grass mesh")
return
# 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
update_shader_parameter('top_color', ColorData.grass_materials[Season.current]['top'])
update_shader_parameter('bottom_color', ColorData.grass_materials[Season.current]['base'])
# Configure instance count
mm.instance_count = parent_node.grass_instance_range
# Get shared RNG from GroundTile
var rng = parent_node.parent_node.get_rng()
# Generate positions using shared RNG
for i in range(mm.instance_count):
var random_pos = Vector3(
rng.randf_range(-1.0, 1.0),
0.0,
rng.randf_range(-1.0, 1.0)
)
var random_rotation = rng.randf_range(0.0, TAU)
var basis = Basis(Vector3.UP, random_rotation)
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)
mm.set_instance_transform(i, tx)
multimesh = mm
cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
func update_shader_parameter(param_name: String, value) -> void:
if material_override == null:
Log.pr("Error: No material override found")
return
# Check if it's a ShaderMaterial
if material_override is ShaderMaterial:
var shader_material = material_override as ShaderMaterial
shader_material.set_shader_parameter(param_name, value)
else:
Log.pr("Error: Material override is not a ShaderMaterial")
return