From 4bfbf641dc2b8aca8de9f86a9908063f39bd6e31 Mon Sep 17 00:00:00 2001 From: jacopograndi Date: Fri, 14 Jan 2022 13:04:34 +0100 Subject: . --- assets/addons/voxel-core/classes/voxel_set.gd | 234 ++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 assets/addons/voxel-core/classes/voxel_set.gd (limited to 'assets/addons/voxel-core/classes/voxel_set.gd') diff --git a/assets/addons/voxel-core/classes/voxel_set.gd b/assets/addons/voxel-core/classes/voxel_set.gd new file mode 100644 index 0000000..d0bccac --- /dev/null +++ b/assets/addons/voxel-core/classes/voxel_set.gd @@ -0,0 +1,234 @@ +tool +class_name VoxelSet, "res://addons/voxel-core/assets/classes/voxel_set.png" +extends Resource +# Library of Voxels used by VoxelObjects. + + + +## Signals +# Emitted on request_refresh +signal requested_refresh + + + +## Exported Variables +# Size of each tile in tiles in pixels +export var tile_size := Vector2(32.0, 32.0) setget set_tile_size + +# Texture used for tiles / uv mapping +export var tiles : Texture = null setget set_tiles + +# Materials used by voxels +export(Array, Material) var materials := [ + SpatialMaterial.new(), +] setget set_materials + + + +## Private Variables +# Voxels stored by their id +var _voxels := [] + +# Flag indicating whether _uv_scale, tile_size and tiles texture is set +var _uv_ready := false + +# World UV Scale, calculated on request_refresh +var _uv_scale := Vector2.ONE + + + +## Built-In Virtual Methods +func _get(property : String): + if property == "VOXELS": + return _voxels + + +func _set(property : String, value) -> bool: + if property == "VOXELS": + if typeof(value) == TYPE_DICTIONARY: + for key in value: + var voxel : Dictionary = value[key] + if voxel.has("vsn"): + Voxel.set_name(voxel, voxel["vsn"]) + voxel.erase("vsn") + _voxels.append(value[key]) + else: + _voxels = value + return true + return false + + +func _get_property_list(): + var properties = [] + + properties.append({ + "name": "VOXELS", + "type": TYPE_ARRAY, + "hint": PROPERTY_HINT_NONE, + "usage": PROPERTY_USAGE_STORAGE, + }) + + return properties + + + +## Public Methods +# Sets tile_size, calls on request_refresh by default +func set_tile_size(value : Vector2, refresh := true) -> void: + tile_size = Vector2( + floor(clamp(value.x, 1, 256)), + floor(clamp(value.y, 1, 256))) + + if refresh: + request_refresh() + + +# Sets tiles, calls on request_refresh by default +func set_tiles(value : Texture, refresh := true) -> void: + tiles = value + + if refresh: + request_refresh() + + +# Sets materials used by voxels in VoxelSet +func set_materials(values : Array, refresh := true) -> void: + for index in range(values.size()): + var material = values[index] + if is_instance_valid(material) and not (material is SpatialMaterial or material is ShaderMaterial): + printerr("VoxelSet : Expected Spatial or Shader material got " + str(material)) + values[index] = null + + if values.empty(): + materials.resize(1) + else: + materials = values + property_list_changed_notify() + + if refresh: + request_refresh() + + +# Returns VoxelSet material with id if present, otherwise returns null +func get_material(id : int) -> Material: + return materials[id] if id > -1 and id < materials.size() else null + + +# Returns number of voxels in VoxelSet +func size() -> int: + return _voxels.size() + + +# Returns true if VoxelSet has no voxels +func empty() -> bool: + return _voxels.empty() + + +# Returns true if VoxelSet has voxel with given id +func has_id(id : int) -> bool: + return id > -1 and id < _voxels.size() + + +# Returns true if VoxelSet has everything necessary for uv mapping +func uv_ready() -> bool: + return _uv_ready + + +# Returns the uv scale +func uv_scale() -> Vector2: + return _uv_scale + + +# Returns true if given id is valid +static func is_valid_id(id : int) -> bool: + return id > -1 + + +# Returns a list of all the voxel ids +# returns : Array : contained voxel ids +func get_ids() -> Array: + return range(_voxels.size()) + + +# Returns name associated with the given id, returns a empty string if id isn't found +func id_to_name(id : int) -> String: + return Voxel.get_name(get_voxel(id)) + + +# Returns the id of the voxel with the given name, returns -1 if not found +func name_to_id(name : String) -> int: + name = name.to_lower() + for id in get_ids(): + if id_to_name(id) == name: + return id + return -1 + + +# Appends voxel to end of VoxelSet +func add_voxel(voxel : Dictionary) -> void: + _voxels.append(voxel) + + +# Sets the voxel at given id +func set_voxel(id : int, voxel : Dictionary) -> void: + if not has_id(id): + printerr("VoxelSet : given id `" + str(id) + "` is out of range") + return + + _voxels[id] = voxel + + +# Insert voxel with given id +func insert_voxel(id : int, voxel : Dictionary) -> void: + if id < -1 and id > _voxels.size(): + printerr("VoxelSet : given id `" + str(id) + "` is out of range") + return + + _voxels.insert(id, voxel) + + +# Replaces all _voxels +func set_voxels(voxels : Array) -> void: + _voxels = voxels + + +# Gets voxel Dictionary by their id, returns an empty Dictionary if not found +func get_voxel(id : int) -> Dictionary: + return _voxels[id] if has_id(id) else {} + + +# Erase voxel from VoxelSet +func erase_voxel(id : int) -> void: + _voxels.remove(id) + + +# Erases all voxels in VoxelSet +func erase_voxels() -> void: + _voxels.clear() + + +# Should be called when noticable changes have been committed to voxels. +# Emits requested_refresh, calculates _uv_scale and updates _uv_ready +func request_refresh() -> void: + _uv_ready = is_instance_valid(tiles) + if _uv_ready: + _uv_scale = Vector2.ONE / (tiles.get_size() / tile_size) + else: + _uv_scale = Vector2.ONE + emit_signal("requested_refresh") + + +# Loads file's content as voxels +# NOTE: Reference Reader.gd for valid file imports +# source_file : String : Path to file to be loaded +# return int : int : Error code +func load_file(source_file : String, append := false) -> int: + var read := Reader.read_file(source_file) + var error : int = read.get("error", FAILED) + if error == OK: + if append: + for voxel in read["palette"]: + add_voxel(voxel) + else: + set_voxels(read["palette"]) + return error -- cgit v1.2.3-54-g00ecf