built more assets and started playing with foliage painting
This commit is contained in:
261
addons/dreadpon.spatial_gardener/gardener/debug_viewer.gd
Normal file
261
addons/dreadpon.spatial_gardener/gardener/debug_viewer.gd
Normal file
@@ -0,0 +1,261 @@
|
||||
@tool
|
||||
extends Node3D
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# A previewer for octree structure
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
const FunLib = preload("../utility/fun_lib.gd")
|
||||
const DponDebugDraw = preload("../utility/debug_draw.gd")
|
||||
const MMIOctreeManager = preload("../arborist/mmi_octree/mmi_octree_manager.gd")
|
||||
const MMIOctreeNode = preload("../arborist/mmi_octree/mmi_octree_node.gd")
|
||||
|
||||
|
||||
# How many/which plants we want to preview
|
||||
enum PlantViewModeFlags {
|
||||
VIEW_NONE = 0,
|
||||
VIEW_SELECTED_PLANT = 1,
|
||||
VIEW_ALL_ACTIVE_PLANTS = 2,
|
||||
VIEW_MAX = 3,
|
||||
}
|
||||
|
||||
# What parts of an octree we want to preview
|
||||
enum RenderModeFlags {
|
||||
DRAW_OCTREE_NODES = 101,
|
||||
DRAW_OCTREE_MEMBERS = 102,
|
||||
}
|
||||
|
||||
|
||||
var octree_MMIs:Array = []
|
||||
var active_plant_view_mode:int = PlantViewModeFlags.VIEW_NONE
|
||||
var active_render_modes:Array = [RenderModeFlags.DRAW_OCTREE_NODES]
|
||||
|
||||
var brush_active_plants:Array = []
|
||||
var prop_edit_selected_plant: int = -1
|
||||
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Debug view menu
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Create and initialize a debug view menu
|
||||
static func make_debug_view_menu():
|
||||
var debug_view_menu := MenuButton.new()
|
||||
debug_view_menu.text = "Gardener Debug Viewer"
|
||||
debug_view_menu.get_popup().hide_on_checkable_item_selection = false
|
||||
debug_view_menu.get_popup().hide_on_item_selection = false
|
||||
|
||||
for i in range(0, PlantViewModeFlags.size() - 1):
|
||||
debug_view_menu.get_popup().add_radio_check_item(PlantViewModeFlags.keys()[i].capitalize(), PlantViewModeFlags.values()[i])
|
||||
|
||||
debug_view_menu.get_popup().add_separator()
|
||||
|
||||
for i in range(0, RenderModeFlags.size()):
|
||||
debug_view_menu.get_popup().add_check_item(RenderModeFlags.keys()[i].capitalize(), RenderModeFlags.values()[i])
|
||||
|
||||
return debug_view_menu
|
||||
|
||||
|
||||
# Callback when flag is checked on a menu
|
||||
func flag_checked(debug_view_menu:MenuButton, flag:int):
|
||||
var flag_group = flag <= PlantViewModeFlags.VIEW_MAX
|
||||
if flag_group:
|
||||
active_plant_view_mode = flag
|
||||
else:
|
||||
if active_render_modes.has(flag):
|
||||
active_render_modes.erase(flag)
|
||||
else:
|
||||
active_render_modes.append(flag)
|
||||
|
||||
up_to_date_debug_view_menu(debug_view_menu)
|
||||
|
||||
|
||||
# Reset a menu to the current state of this DebugViewer
|
||||
func up_to_date_debug_view_menu(debug_view_menu:MenuButton):
|
||||
for i in range(0, debug_view_menu.get_popup().get_item_count()):
|
||||
debug_view_menu.get_popup().set_item_checked(i, false)
|
||||
|
||||
update_debug_view_menu_to_flag(debug_view_menu, active_plant_view_mode)
|
||||
for render_mode in active_render_modes:
|
||||
update_debug_view_menu_to_flag(debug_view_menu, render_mode)
|
||||
|
||||
|
||||
# Tick a flag in a menu
|
||||
# TODO Decide if this should be simplified and moved to up_to_date_debug_view_menu
|
||||
# Since flag checks happen in flag_checked anyways
|
||||
func update_debug_view_menu_to_flag(debug_view_menu:MenuButton, flag:int):
|
||||
var flag_group = flag <= PlantViewModeFlags.VIEW_MAX
|
||||
for i in range(0, debug_view_menu.get_popup().get_item_count()):
|
||||
var item_id = debug_view_menu.get_popup().get_item_id(i)
|
||||
var id_group = item_id <= PlantViewModeFlags.VIEW_MAX
|
||||
var opposite_state = !debug_view_menu.get_popup().is_item_checked(i)
|
||||
|
||||
if item_id == flag:
|
||||
if flag_group:
|
||||
debug_view_menu.get_popup().set_item_checked(i, true)
|
||||
else:
|
||||
debug_view_menu.get_popup().set_item_checked(i, opposite_state)
|
||||
elif flag_group == id_group && flag_group:
|
||||
debug_view_menu.get_popup().set_item_checked(i, false)
|
||||
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Brush active plants
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Keep a local copy of selected for brush plant indexes
|
||||
func set_brush_active_plant(is_brush_active, plant_index:int):
|
||||
if is_brush_active:
|
||||
if !brush_active_plants.has(plant_index):
|
||||
brush_active_plants.append(plant_index)
|
||||
else:
|
||||
if brush_active_plants.has(plant_index):
|
||||
brush_active_plants.erase(plant_index)
|
||||
brush_active_plants.sort()
|
||||
|
||||
|
||||
func reset_brush_active_plants():
|
||||
brush_active_plants = []
|
||||
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Selected for prop edit plants
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
func set_prop_edit_selected_plant(plant_index:int):
|
||||
prop_edit_selected_plant = plant_index
|
||||
|
||||
|
||||
func reset_prop_edit_selected_plant():
|
||||
prop_edit_selected_plant = -1
|
||||
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Debug redraw requests
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
func request_debug_redraw(octree_managers:Array):
|
||||
debug_redraw(octree_managers)
|
||||
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Drawing the structure
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Redraw every fitting octree
|
||||
func debug_redraw(octree_managers:Array):
|
||||
var used_octree_managers = []
|
||||
|
||||
match active_plant_view_mode:
|
||||
# Don't draw anything
|
||||
PlantViewModeFlags.VIEW_NONE:
|
||||
ensure_MMIs(0)
|
||||
# Draw only the plant selected for prop edit
|
||||
PlantViewModeFlags.VIEW_SELECTED_PLANT:
|
||||
if prop_edit_selected_plant >= 0:
|
||||
ensure_MMIs(1)
|
||||
used_octree_managers.append(octree_managers[prop_edit_selected_plant])
|
||||
else:
|
||||
ensure_MMIs(0)
|
||||
# Draw all brush active plants
|
||||
PlantViewModeFlags.VIEW_ALL_ACTIVE_PLANTS:
|
||||
ensure_MMIs(brush_active_plants.size())
|
||||
for plant_index in brush_active_plants:
|
||||
used_octree_managers.append(octree_managers[plant_index])
|
||||
|
||||
for i in range(0, used_octree_managers.size()):
|
||||
var MMI:MultiMeshInstance3D = octree_MMIs[i]
|
||||
var octree_mamager:MMIOctreeManager = used_octree_managers[i]
|
||||
debug_draw_node(octree_mamager.root_octree_node, MMI)
|
||||
|
||||
|
||||
func erase_all():
|
||||
ensure_MMIs(0)
|
||||
|
||||
|
||||
# Make sure there is an MMI for every octree we're about to draw
|
||||
# Passing 0 effectively erases any debug renders
|
||||
func ensure_MMIs(amount:int):
|
||||
if octree_MMIs.size() < amount:
|
||||
for i in range(octree_MMIs.size(), amount):
|
||||
var MMI = MultiMeshInstance3D.new()
|
||||
add_child(MMI)
|
||||
MMI.cast_shadow = false
|
||||
MMI.multimesh = MultiMesh.new()
|
||||
MMI.multimesh.transform_format = 1
|
||||
MMI.multimesh.use_colors = true
|
||||
MMI.multimesh.mesh = DponDebugDraw.generate_cube(Vector3.ONE, Color.WHITE)
|
||||
octree_MMIs.append(MMI)
|
||||
elif octree_MMIs.size() > amount:
|
||||
var MMI = null
|
||||
while octree_MMIs.size() > amount:
|
||||
MMI = octree_MMIs.pop_back()
|
||||
remove_child(MMI)
|
||||
MMI.queue_free()
|
||||
|
||||
|
||||
# Recursively draw an octree node
|
||||
func debug_draw_node(octree_node:MMIOctreeNode, MMI:MultiMeshInstance3D):
|
||||
var draw_node := active_render_modes.has(RenderModeFlags.DRAW_OCTREE_NODES)
|
||||
var draw_members := active_render_modes.has(RenderModeFlags.DRAW_OCTREE_MEMBERS)
|
||||
|
||||
# Reset the instance counts if this node is a root
|
||||
if !octree_node.parent:
|
||||
MMI.multimesh.instance_count = 0
|
||||
MMI.multimesh.visible_instance_count = 0
|
||||
set_debug_redraw_instance_count(octree_node, MMI, draw_node, draw_members)
|
||||
|
||||
var extents:Vector3
|
||||
var render_transform:Transform3D
|
||||
var index:int
|
||||
|
||||
if draw_node:
|
||||
extents = Vector3(octree_node.extent, octree_node.extent, octree_node.extent) * 0.999 * 2.0
|
||||
render_transform = Transform3D(Basis.IDENTITY.scaled(extents), octree_node.center_pos)
|
||||
index = MMI.multimesh.visible_instance_count
|
||||
MMI.multimesh.visible_instance_count += 1
|
||||
MMI.multimesh.set_instance_transform(index, render_transform)
|
||||
MMI.multimesh.set_instance_color(index, octree_node.debug_get_color())
|
||||
|
||||
if draw_members && octree_node.is_leaf:
|
||||
var member_extent = FunLib.get_setting_safe("dreadpons_spatial_gardener/debug/debug_viewer_octree_member_size", 0.0) * 0.5
|
||||
extents = Vector3(member_extent, member_extent, member_extent)
|
||||
var basis = Basis.IDENTITY.scaled(extents)
|
||||
for placeform in octree_node.get_placeforms():
|
||||
render_transform = Transform3D(basis, placeform[0])
|
||||
index = MMI.multimesh.visible_instance_count
|
||||
MMI.multimesh.visible_instance_count += 1
|
||||
MMI.multimesh.set_instance_transform(index, render_transform)
|
||||
MMI.multimesh.set_instance_color(index, Color.WHITE)
|
||||
|
||||
for child in octree_node.child_nodes:
|
||||
debug_draw_node(child, MMI)
|
||||
|
||||
|
||||
# Recursively set the appropriate instance count for an MMI
|
||||
func set_debug_redraw_instance_count(octree_node:MMIOctreeNode, MMI:MultiMeshInstance3D, draw_node:bool, draw_members:bool):
|
||||
if draw_node:
|
||||
MMI.multimesh.instance_count += 1
|
||||
|
||||
if octree_node.is_leaf && draw_members:
|
||||
MMI.multimesh.instance_count += octree_node.member_count()
|
||||
|
||||
for child in octree_node.child_nodes:
|
||||
set_debug_redraw_instance_count(child, MMI, draw_node, draw_members)
|
||||
Reference in New Issue
Block a user