Add lever and jump pad components with activation logic

This commit is contained in:
2025-04-25 22:41:35 +02:00
parent 9b2ca61163
commit 8959fd4b9f
323 changed files with 12844 additions and 18 deletions

View File

@@ -0,0 +1,23 @@
class_name SS2D_Action
extends RefCounted
## Base class for all plugin actions.
##
## UndoRedo system will call [method do] and [method undo].
# @virtual
## Returns string to be used as a name in editor History tab.
func get_name() -> String:
return "UntitledAction"
# @virtual
## Do action here.
func do() -> void:
pass
# @virtual
## Undo action here.
func undo() -> void:
pass

View File

@@ -0,0 +1,56 @@
extends SS2D_Action
## ActionAddCollisionNodes
var _shape: SS2D_Shape
var _saved_index: int
var _saved_pos: Vector2
func _init(shape: SS2D_Shape) -> void:
_shape = shape
func get_name() -> String:
return "Add Collision Nodes"
func do() -> void:
_saved_index = _shape.get_index()
_saved_pos = _shape.position
var owner := _shape.owner
var static_body := StaticBody2D.new()
static_body.position = _shape.position
_shape.position = Vector2.ZERO
_shape.get_parent().add_child(static_body, true)
static_body.owner = owner
_shape.get_parent().remove_child(_shape)
static_body.add_child(_shape, true)
_shape.owner = owner
var poly: CollisionPolygon2D = CollisionPolygon2D.new()
static_body.add_child(poly, true)
poly.owner = owner
# TODO: Make this a option at some point
poly.modulate.a = 0.3
poly.visible = false
_shape.collision_polygon_node_path = _shape.get_path_to(poly)
func undo() -> void:
var owner := _shape.owner
var parent := _shape.get_parent()
var grandparent := _shape.get_parent().get_parent()
parent.remove_child(_shape)
grandparent.remove_child(parent)
parent.free()
grandparent.add_child(_shape)
_shape.owner = owner
grandparent.move_child(_shape, _saved_index)
_shape.position = _saved_pos

View File

@@ -0,0 +1,44 @@
extends SS2D_Action
## ActionAddPoint
const ActionInvertOrientation := preload("res://addons/rmsmartshape/actions/action_invert_orientation.gd")
var _invert_orientation: ActionInvertOrientation
var _commit_update: bool
var _shape: SS2D_Shape
var _key: int
var _position: Vector2
var _idx: int
func _init(shape: SS2D_Shape, position: Vector2, idx: int = -1, commit_update: bool = true) -> void:
_shape = shape
_position = position
_commit_update = commit_update
_idx = _shape.adjust_add_point_index(idx)
_key = _shape.reserve_key()
_invert_orientation = ActionInvertOrientation.new(shape)
func get_name() -> String:
return "Add Point at (%d, %d)" % [_position.x, _position.y]
func do() -> void:
_shape.begin_update()
_key = _shape.add_point(_position, _idx, _key)
_invert_orientation.do()
if _commit_update:
_shape.end_update()
func undo() -> void:
_shape.begin_update()
_invert_orientation.undo()
_shape.remove_point(_key)
_shape.end_update()
func get_key() -> int:
return _key

View File

@@ -0,0 +1,40 @@
extends SS2D_Action
## ActionCloseShape
const ActionInvertOrientation := preload("res://addons/rmsmartshape/actions/action_invert_orientation.gd")
var _invert_orientation: ActionInvertOrientation
var _shape: SS2D_Shape
var _key: int
var _performed: bool
func _init(shape: SS2D_Shape) -> void:
_shape = shape
_invert_orientation = ActionInvertOrientation.new(shape)
func get_name() -> String:
return "Close Shape"
func do() -> void:
_performed = _shape.can_close()
if _performed:
_shape.begin_update()
_key = _shape.close_shape(_key)
_invert_orientation.do()
_shape.end_update()
func undo() -> void:
if _performed:
_shape.begin_update()
_invert_orientation.undo()
_shape.remove_point(_key)
_shape.end_update()
func get_key() -> int:
return _key

View File

@@ -0,0 +1,41 @@
extends SS2D_Action
## ActionCutEdge
##
## A delegate action that selects an action to perform based on the edge
## location and shape state.
var ActionOpenShape := preload("res://addons/rmsmartshape/actions/action_open_shape.gd")
var ActionDeletePoint := preload("res://addons/rmsmartshape/actions/action_delete_point.gd")
var ActionSplitShape := preload("res://addons/rmsmartshape/actions/action_split_shape.gd")
var _shape: SS2D_Shape
var _action: SS2D_Action
func _init(shape: SS2D_Shape, key_edge_start: int, key_edge_end: int) -> void:
_shape = shape
var key_first: int = shape.get_point_key_at_index(0)
var key_last: int = shape.get_point_key_at_index(shape.get_point_count()-1)
if _shape.is_shape_closed():
_action = ActionOpenShape.new(shape, key_edge_start)
elif key_edge_start == key_first:
_action = ActionDeletePoint.new(shape, key_edge_start)
elif key_edge_end == key_last:
_action = ActionDeletePoint.new(shape, key_edge_end)
else:
_action = ActionSplitShape.new(shape, key_edge_start)
func get_name() -> String:
return _action.get_name()
func do() -> void:
_action.do()
func undo() -> void:
_action.undo()

View File

@@ -0,0 +1,45 @@
extends SS2D_Action
## ActionDeleteControlPoint
enum PointType {POINT_IN, POINT_OUT}
const ActionInvertOrientation := preload("res://addons/rmsmartshape/actions/action_invert_orientation.gd")
var _invert_orientation: ActionInvertOrientation
var _shape: SS2D_Shape
var _key: int
var _point_type: PointType
var _old_value: Vector2
func _init(shape: SS2D_Shape, key: int, point_type: PointType) -> void:
_shape = shape
_key = key
_point_type = point_type
_old_value = shape.get_point_in(key) if _point_type == PointType.POINT_IN else shape.get_point_out(key)
_invert_orientation = ActionInvertOrientation.new(shape)
func get_name() -> String:
return "Delete Control Point " + ("In" if _point_type == PointType.POINT_IN else "Out")
func do() -> void:
_shape.begin_update()
if _point_type == PointType.POINT_IN:
_shape.set_point_in(_key, Vector2.ZERO)
else:
_shape.set_point_out(_key, Vector2.ZERO)
_invert_orientation.do()
_shape.end_update()
func undo() -> void:
_shape.begin_update()
_invert_orientation.undo()
if _point_type == PointType.POINT_IN:
_shape.set_point_in(_key, _old_value)
else:
_shape.set_point_out(_key, _old_value)
_shape.end_update()

View File

@@ -0,0 +1,13 @@
extends "res://addons/rmsmartshape/actions/action_delete_points.gd"
## ActionDeletePoint
func _init(shape: SS2D_Shape, key: int, commit_update: bool = true) -> void:
var keys: PackedInt32Array = [key]
super(shape, keys, commit_update)
func get_name() -> String:
var pos := _shape.get_point_position(_keys[0])
return "Delete Point at (%d, %d)" % [pos.x, pos.y]

View File

@@ -0,0 +1,88 @@
extends SS2D_Action
## ActionDeletePoints
const TUP := preload("res://addons/rmsmartshape/lib/tuple.gd")
const ActionInvertOrientation := preload("res://addons/rmsmartshape/actions/action_invert_orientation.gd")
var _invert_orientation: ActionInvertOrientation
const ActionCloseShape := preload("res://addons/rmsmartshape/actions/action_close_shape.gd")
var _close_shape: ActionCloseShape
var _shape: SS2D_Shape
var _keys: PackedInt32Array
var _indicies: PackedInt32Array
var _positions: PackedVector2Array
var _points_in: PackedVector2Array
var _points_out: PackedVector2Array
var _properties: Array[SS2D_VertexProperties]
var _constraints: Array[Dictionary]
var _was_closed: bool
var _commit_update: bool
func _init(shape: SS2D_Shape, keys: PackedInt32Array, commit_update: bool = true) -> void:
_shape = shape
_invert_orientation = ActionInvertOrientation.new(shape)
_close_shape = ActionCloseShape.new(shape)
_commit_update = commit_update
for k in keys:
add_point_to_delete(k)
func get_name() -> String:
return "Delete Points %s" % [_keys]
func do() -> void:
_shape.begin_update()
_was_closed = _shape.is_shape_closed()
var first_run := _positions.size() == 0
for k in _keys:
if first_run:
_indicies.append(_shape.get_point_index(k))
_positions.append(_shape.get_point_position(k))
_points_in.append(_shape.get_point_in(k))
_points_out.append(_shape.get_point_out(k))
_properties.append(_shape.get_point_properties(k))
_shape.remove_point(k)
if _was_closed:
_close_shape.do()
_invert_orientation.do()
if _commit_update:
_shape.end_update()
func undo() -> void:
_shape.begin_update()
_invert_orientation.undo()
if _was_closed:
_close_shape.undo()
for i in range(_keys.size()-1, -1, -1):
_shape.add_point(_positions[i], _indicies[i], _keys[i])
_shape.set_point_in(_keys[i], _points_in[i])
_shape.set_point_out(_keys[i], _points_out[i])
_shape.set_point_properties(_keys[i], _properties[i])
# Restore point constraints.
for i in range(_keys.size()-1, -1, -1):
for tuple: Vector2i in _constraints[i]:
_shape.set_constraint(tuple[0], tuple[1], _constraints[i][tuple])
_shape.end_update()
func add_point_to_delete(key: int) -> void:
_keys.push_back(key)
var constraints := _shape.get_point_array().get_point_constraints(key)
# Save point constraints.
_constraints.append(constraints)
for tuple: Vector2i in constraints:
var constraint: SS2D_Point_Array.CONSTRAINT = constraints[tuple]
if constraint == SS2D_Point_Array.CONSTRAINT.NONE:
continue
var key_other := SS2D_IndexTuple.get_other_value(tuple, key)
if constraint & SS2D_Point_Array.CONSTRAINT.ALL:
if not _keys.has(key_other):
add_point_to_delete(key_other)

View File

@@ -0,0 +1,33 @@
extends SS2D_Action
## ActionInvertOrientation
var _shape: SS2D_Shape
var _performed: bool
func _init(shape: SS2D_Shape) -> void:
_shape = shape
func get_name() -> String:
return "Invert Orientation"
func do() -> void:
_performed = should_invert_orientation(_shape)
if _performed:
_shape.invert_point_order()
func undo() -> void:
if _performed:
_shape.invert_point_order()
func should_invert_orientation(s: SS2D_Shape) -> bool:
if s == null:
return false
if not s.is_shape_closed():
return false
return not s.are_points_clockwise() and s.get_point_count() >= 3

View File

@@ -0,0 +1,26 @@
extends SS2D_Action
## ActionMakeShapeUnique
var _shape: SS2D_Shape
var _old_array: SS2D_Point_Array
var _new_array: SS2D_Point_Array
func _init(shape: SS2D_Shape) -> void:
_shape = shape
_old_array = shape.get_point_array()
_new_array = _shape.get_point_array().clone(true)
func get_name() -> String:
return "Make Shape Unique"
func do() -> void:
_shape.set_point_array(_new_array)
func undo() -> void:
_shape.set_point_array(_old_array)

View File

@@ -0,0 +1,43 @@
extends SS2D_Action
## ActionMoveControlPoints
var _shape: SS2D_Shape
var _keys: PackedInt32Array
var _old_points_in: PackedVector2Array
var _old_points_out: PackedVector2Array
var _new_points_in: PackedVector2Array
var _new_points_out: PackedVector2Array
func _init(s: SS2D_Shape, keys: PackedInt32Array,
old_points_in: PackedVector2Array, old_points_out: PackedVector2Array) -> void:
_shape = s
_keys = keys
_old_points_in = old_points_in
_old_points_out = old_points_out
for key in _keys:
_new_points_in.append(_shape.get_point_in(key))
_new_points_out.append(_shape.get_point_out(key))
func get_name() -> String:
return "Move Control Point"
func do() -> void:
_assign_points_in_out(_keys, _new_points_in, _new_points_out)
func undo() -> void:
_assign_points_in_out(_keys, _old_points_in, _old_points_out)
func _assign_points_in_out(keys: PackedInt32Array, in_positions: PackedVector2Array, out_positions: PackedVector2Array) -> void:
_shape.begin_update()
for i in keys.size():
if _shape.get_point_in(keys[i]) != in_positions[i]:
_shape.set_point_in(keys[i], in_positions[i])
if _shape.get_point_out(keys[i]) != out_positions[i]:
_shape.set_point_out(keys[i], out_positions[i])
_shape.end_update()

View File

@@ -0,0 +1,44 @@
extends SS2D_Action
## ActionMoveVerticies
const ActionInvertOrientation := preload("res://addons/rmsmartshape/actions/action_invert_orientation.gd")
var _invert_orientation: ActionInvertOrientation
var _shape: SS2D_Shape
var _keys: PackedInt32Array
var _old_positions: PackedVector2Array
var _new_positions: PackedVector2Array
func _init(s: SS2D_Shape, keys: PackedInt32Array, old_positions: PackedVector2Array) -> void:
_shape = s
_keys = keys.duplicate()
_old_positions = old_positions.duplicate()
_new_positions = PackedVector2Array()
for k in _keys:
_new_positions.append(_shape.get_point_position(k))
_invert_orientation = ActionInvertOrientation.new(_shape)
func get_name() -> String:
if _keys.size() == 1:
return "Move Vertex to (%d, %d)" % [_new_positions[0].x, _new_positions[0].y]
else:
return "Move Verticies"
func do() -> void:
_shape.begin_update()
for i in _keys.size():
_shape.set_point_position(_keys[i], _new_positions[i])
_invert_orientation.do()
_shape.end_update()
func undo() -> void:
_shape.begin_update()
_invert_orientation.undo()
for i in range(_keys.size() - 1, -1, -1):
_shape.set_point_position(_keys[i], _old_positions[i])
_shape.end_update()

View File

@@ -0,0 +1,31 @@
extends SS2D_Action
## ActionOpenShape
var _shape: SS2D_Shape
var _cut_idx: int
var _closing_key: int
func _init(shape: SS2D_Shape, edge_start_key: int) -> void:
_shape = shape
_cut_idx = shape.get_point_index(edge_start_key)
func get_name() -> String:
return "Open Shape"
func do() -> void:
_shape.begin_update()
var last_idx: int = _shape.get_point_count() - 1
_closing_key = _shape.get_point_key_at_index(last_idx)
_shape.open_shape_at_edge(_cut_idx)
_shape.end_update()
func undo() -> void:
_shape.begin_update()
_shape.undo_open_shape_at_edge(_cut_idx, _closing_key)
_shape.end_update()

View File

@@ -0,0 +1,44 @@
extends SS2D_Action
## ActionSetPivot
var _shape: SS2D_Shape
var _new_pos: Vector2
var _old_pos: Vector2
func _init(s: SS2D_Shape, pos: Vector2) -> void:
_shape = s
_new_pos = pos
_old_pos = _shape.global_position
func get_name() -> String:
return "Set Pivot"
func do() -> void:
_set_pivot(_new_pos)
func undo() -> void:
_set_pivot(_old_pos)
func _set_pivot(shape_position: Vector2) -> void:
var shape_gt: Transform2D = _shape.get_global_transform()
_shape.global_position = shape_position
_shape.begin_update()
_shape.disable_constraints()
for i in _shape.get_point_count():
var key: int = _shape.get_point_key_at_index(i)
var point: Vector2 = _shape.get_point_position(key)
_shape.set_point_position(key, _shape.to_local(shape_gt * point))
_shape.enable_constraints()
_shape.end_update()

View File

@@ -0,0 +1,10 @@
extends "res://addons/rmsmartshape/actions/action_add_point.gd"
## ActionSplitCurve
func _init(shape: SS2D_Shape, idx: int, gpoint: Vector2, xform: Transform2D, commit_update: bool = true) -> void:
super._init(shape, xform.affine_inverse() * gpoint, idx, commit_update)
func get_name() -> String:
return "Split Curve at (%d, %d)" % [_position.x, _position.y]

View File

@@ -0,0 +1,74 @@
extends SS2D_Action
## ActionSplitShape
##
## How it's done:
## 1. First, the shape is copied and added to the scene tree.
## 2. Then, points of the splitted shape are deleted from first point to split point.
## 3. Finally, points of the original shape are deleted from the point after split point to last point.
const ActionDeletePoints := preload("res://addons/rmsmartshape/actions/action_delete_points.gd")
var _delete_points_from_original: ActionDeletePoints
var _shape: SS2D_Shape
var _splitted: SS2D_Shape
var _splitted_collision: CollisionPolygon2D
var _split_idx: int
func _init(shape: SS2D_Shape, split_point_key: int) -> void:
assert(shape.is_shape_closed() == false)
_shape = shape
_split_idx = shape.get_point_index(split_point_key)
_splitted = null
_splitted_collision = null
_delete_points_from_original = null
func get_name() -> String:
return "Split Shape"
func do() -> void:
if not is_instance_valid(_splitted):
_splitted = _shape.clone()
_splitted.begin_update()
for i in range(0, _split_idx + 1):
_splitted.remove_point_at_index(0)
_splitted.end_update()
_shape.get_parent().add_child(_splitted, true)
_splitted.set_owner(_shape.get_tree().get_edited_scene_root())
# Add a collision shape node if the original shape has one.
if (not _shape.collision_polygon_node_path.is_empty() and _shape.has_node(_shape.collision_polygon_node_path)):
var collision_polygon_original := _shape.get_node(_shape.collision_polygon_node_path) as CollisionPolygon2D
if not is_instance_valid(_splitted_collision):
_splitted_collision = CollisionPolygon2D.new()
_splitted_collision.visible = collision_polygon_original.visible
_splitted_collision.modulate = collision_polygon_original.modulate
collision_polygon_original.get_parent().add_child(_splitted_collision, true)
_splitted_collision.set_owner(collision_polygon_original.get_tree().get_edited_scene_root())
_splitted.collision_polygon_node_path = _splitted.get_path_to(_splitted_collision)
if _delete_points_from_original == null:
var delete_keys := PackedInt32Array()
for i in range(_shape.get_point_count() - 1, _split_idx, -1):
delete_keys.append(_shape.get_point_key_at_index(i))
_delete_points_from_original = ActionDeletePoints.new(_shape, delete_keys)
_delete_points_from_original.do()
func undo() -> void:
_splitted.set_owner(null)
_splitted.get_parent().remove_child(_splitted)
if is_instance_valid(_splitted_collision):
_splitted_collision.set_owner(null)
_splitted_collision.get_parent().remove_child(_splitted_collision)
_delete_points_from_original.undo()
func _notification(what: int) -> void:
if what == NOTIFICATION_PREDELETE:
if is_instance_valid(_splitted) and _splitted.get_parent() == null:
_splitted.queue_free()
if is_instance_valid(_splitted_collision) and _splitted_collision.get_parent() == null:
_splitted_collision.queue_free()

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://5wllxq74p8kq"
path="res://.godot/imported/asset_library_icon-new.png-60877ecd9837f02c48423d4ec08e9284.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/asset_library_icon-new.png"
dest_files=["res://.godot/imported/asset_library_icon-new.png-60877ecd9837f02c48423d4ec08e9284.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cbde02owb6iuu"
path="res://.godot/imported/asset_library_icon.png-57d4f9e357cb3293fe7f718c0ef3633c.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/asset_library_icon.png"
dest_files=["res://.godot/imported/asset_library_icon.png-57d4f9e357cb3293fe7f718c0ef3633c.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View File

@@ -0,0 +1,12 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<path d="m8 1a3 3 0 0 0-3 3 3 3 0 0 0 2 2.8262v0.17383h-2v2h2v3.8984a5 5 0 0 1-3.8281-3.6035l-1.9336 0.51758a7 7 0 0 0 6.7617 5.1875 7 7 0 0 0 6.7617-5.1875l-1.9375-0.51953a5 5 0 0 1-3.8242 3.6035v-3.8965h2v-2h-2v-0.17578a3 3 0 0 0 2-2.8242 3 3 0 0 0-3-3zm0 2a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1z" fill="#a5b7f3" fill-opacity=".98824"/>
</svg>

After

Width:  |  Height:  |  Size: 821 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b2h8c634u1120"
path="res://.godot/imported/Anchor.svg-1c23ca67e353b480fc5d8186bb0064b9.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/Anchor.svg"
dest_files=["res://.godot/imported/Anchor.svg-1c23ca67e353b480fc5d8186bb0064b9.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="4" height="4" rx="1" fill="#e0e0e0"/><path d="M1.5 5.5 4 8l-2.5 2.5m13 0L12 8l2.5-2.5m-4-4L8 4 5.5 1.5m0 13L8 12l2.5 2.5" fill="none" stroke-width="1.5" stroke-linejoin="round" stroke="#e0e0e0"/></svg>

After

Width:  |  Height:  |  Size: 310 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://byx10wt6pl1vo"
path="res://.godot/imported/CenterView.svg-f5e9c7178a59ab586ba9d8fac61799bc.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/CenterView.svg"
dest_files=["res://.godot/imported/CenterView.svg-f5e9c7178a59ab586ba9d8fac61799bc.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1 @@
<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4 6-4 6 4" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1044.4)"/></svg>

After

Width:  |  Height:  |  Size: 243 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://umo7sgb6w70s"
path="res://.godot/imported/InterpLinear.svg-c9d61ab817f2809471482a31f06cda10.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/InterpLinear.svg"
dest_files=["res://.godot/imported/InterpLinear.svg-c9d61ab817f2809471482a31f06cda10.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,34 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://cjgo8gf0cp441"
path="res://.godot/imported/SourceCodeVariable-Roman.ttf-cb1e4f55679e973e90075716efcdf601.fontdata"
[deps]
source_file="res://addons/rmsmartshape/assets/SourceCodeVariable-Roman.ttf"
dest_files=["res://.godot/imported/SourceCodeVariable-Roman.ttf-cb1e4f55679e973e90075716efcdf601.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=1
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://8r4xp6j0ro3y"
path="res://.godot/imported/closed_shape.png-c1d349f5c2caecc40ec65e52f86a8145.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/closed_shape.png"
dest_files=["res://.godot/imported/closed_shape.png-c1d349f5c2caecc40ec65e52f86a8145.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bjbq000i2n7qd"
path="res://.godot/imported/freehand.png-de4c7fa877a42fa4776ee9cd166cdabd.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/freehand.png"
dest_files=["res://.godot/imported/freehand.png-de4c7fa877a42fa4776ee9cd166cdabd.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://h0jpajdrldwm"
path="res://.godot/imported/icon.png-cf4ff9c0f4595c1f390bb463008250b4.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon.png"
dest_files=["res://.godot/imported/icon.png-cf4ff9c0f4595c1f390bb463008250b4.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View File

@@ -0,0 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
<path d="m14 1050.4h-12v-12h12l-6 6z" fill="none" stroke="#a5b7f3" stroke-linejoin="round" stroke-opacity=".98824" stroke-width="2"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 281 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c3n1j5ybtgjit"
path="res://.godot/imported/icon_collision_polygon_2d.svg-d52c533e615c0baed724848cec175fe6.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_collision_polygon_2d.svg"
dest_files=["res://.godot/imported/icon_collision_polygon_2d.svg-d52c533e615c0baed724848cec175fe6.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,7 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
<path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/>
<path transform="translate(0 1036.4)" d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm6 5v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2z" fill="#84ffb1"/>
<path transform="translate(0 1036.4)" d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" fill="#f5f5f5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 605 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://qf0hmmvirgbn"
path="res://.godot/imported/icon_curve_create.svg-24c8317cfb8ced81d4c832ca7b3310d5.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_curve_create.svg"
dest_files=["res://.godot/imported/icon_curve_create.svg-24c8317cfb8ced81d4c832ca7b3310d5.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,7 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
<path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/>
<path d="m5 1039.4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm4.8789 5.4648-1.4141 1.4141 2.1211 2.1211-2.1211 2.1211 1.4141 1.4141l2.1211-2.1211 2.1211 2.1211 1.4141-1.4141-2.1211-2.1211 2.1211-2.1211-1.4141-1.4141-2.1211 2.1211z" fill="#ff8484"/>
<path d="m13 1039.4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" fill="#f5f5f5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 685 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ce2cbowctirhc"
path="res://.godot/imported/icon_curve_delete.svg-9121c11be9a22040b2d567743d44ead0.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_curve_delete.svg"
dest_files=["res://.godot/imported/icon_curve_delete.svg-9121c11be9a22040b2d567743d44ead0.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,7 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
<path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/>
<path transform="translate(0 1036.4)" d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm3 5l3.291 8 0.94726-2.8203 1.8828 1.8828 0.94336-0.94141-1.8848-1.8828 2.8203-0.94726-8-3.291z" fill="#84c2ff"/>
<path transform="translate(0 1036.4)" d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" fill="#f5f5f5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 665 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://crjuwuq4vp15w"
path="res://.godot/imported/icon_curve_edit.svg-bd7d5e1af7c72f4525dff1d79ad0af94.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_curve_edit.svg"
dest_files=["res://.godot/imported/icon_curve_edit.svg-bd7d5e1af7c72f4525dff1d79ad0af94.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#A5B7F3;}
.st1{fill:#F5F5F5;}
</style>
<path class="st0" d="M11.4,7.7c-2.7,1.8-1.9,4.6-3.8,6.7c-1.1,1.2-2.7,1.1-6,0.3c-0.2-0.1-0.4-0.1-0.6-0.2c0,0-0.6,0.6-0.4,0.7
C2,15.6,6.2,17,8.4,14.8c2.6-2.6,1.3-6.3,5.7-6.4C18.5,8.2,14.2,5.9,11.4,7.7z"/>
<path class="st1" d="M3,13.4l-1.1-0.8l-1.1,1.8l-0.2-2.7l1.7,0l1.2,0.9l6.8-8.1L10,1.2l-7.3,9.9l1.4-5l3.5-5.5l3-0.1l0.2,3.2
l0.4-0.4L11,0.1L7.4,0.2L0.2,11.6L0.5,15L3,13.4z"/>
</svg>

After

Width:  |  Height:  |  Size: 805 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://da64iqyjipw4f"
path="res://.godot/imported/icon_editor_freehand.svg-4eb5cac550480a5ffb50b9c62fba3af1.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_editor_freehand.svg"
dest_files=["res://.godot/imported/icon_editor_freehand.svg-4eb5cac550480a5ffb50b9c62fba3af1.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1 @@
<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><path d="m-3.035534-10.106602h6.071068v6.071068h-6.071068z" fill="#fefefe" stroke="#000" stroke-linecap="square" transform="matrix(-.70710678 .70710678 -.70710678 -.70710678 0 0)"/></svg>

After

Width:  |  Height:  |  Size: 271 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ccnyogs0qbq8b"
path="res://.godot/imported/icon_editor_handle.svg-ace1b9f89612a442855e8ad0888fdf3e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_editor_handle.svg"
dest_files=["res://.godot/imported/icon_editor_handle.svg-ace1b9f89612a442855e8ad0888fdf3e.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.5
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,5 @@
<svg width="10" height="10" version="1.1" viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
<circle cx="5" cy="5" r="5" fill-opacity=".29412"/>
<circle cx="5" cy="5" r="4" fill="#474747"/>
<path d="m4 2v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#84ffb1"/>
</svg>

After

Width:  |  Height:  |  Size: 262 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ci73r1ncmyrrw"
path="res://.godot/imported/icon_editor_handle_add.svg-7258971e5edcfe4396b7b9c27c0ba1cc.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_editor_handle_add.svg"
dest_files=["res://.godot/imported/icon_editor_handle_add.svg-7258971e5edcfe4396b7b9c27c0ba1cc.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.5
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1 @@
<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><path d="m1.5-8.5h7v7h-7z" fill="#fefefe" stroke="#000" stroke-linecap="square" transform="rotate(90)"/></svg>

After

Width:  |  Height:  |  Size: 194 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cycko7tpd5xk5"
path="res://.godot/imported/icon_editor_handle_bezier.svg-b0150f05772e8974a66bc735765e0aeb.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_editor_handle_bezier.svg"
dest_files=["res://.godot/imported/icon_editor_handle_bezier.svg-b0150f05772e8974a66bc735765e0aeb.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.5
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1 @@
<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><circle cx="5" cy="5" fill="#fefefe" r="2.75" stroke="#000" stroke-linecap="square"/></svg>

After

Width:  |  Height:  |  Size: 175 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dgcshah05p0bm"
path="res://.godot/imported/icon_editor_handle_control.svg-8383942d01a7ee5e839992ed99e53aaf.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_editor_handle_control.svg"
dest_files=["res://.godot/imported/icon_editor_handle_control.svg-8383942d01a7ee5e839992ed99e53aaf.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.5
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,3 @@
<svg width="14" height="14" viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
<path d="m-3.035534-10.106602h6.071068v6.071068h-6.071068z" fill="#8ff" stroke="#000" stroke-linecap="square" transform="matrix(-.70710678 .70710678 -.70710678 -.70710678 0 0)"/>
</svg>

After

Width:  |  Height:  |  Size: 272 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dh3vdfbsl5o65"
path="res://.godot/imported/icon_editor_handle_selected.svg-356ef806610ee2a60b5838a989f58598.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_editor_handle_selected.svg"
dest_files=["res://.godot/imported/icon_editor_handle_selected.svg-356ef806610ee2a60b5838a989f58598.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.25
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,4 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path d="m6 0v4.4199a4.2662 4.0576 0 0 0 -1.709 1.5801h-4.291v4h4.2949a4.2662 4.0576 0 0 0 1.7051 1.582v4.418h4v-4.4199a4.2662 4.0576 0 0 0 1.709 -1.5801h4.291v-4h-4.2949a4.2662 4.0576 0 0 0 -1.7051 -1.582v-4.418z" fill="#fff" fill-opacity=".70588"/>
<path d="m7 1v3.0605a4.2662 4.0576 0 0 1 1 -0.11914 4.2662 4.0576 0 0 1 1 0.11914v-3.0605h-2zm1 4.0801a2.9201 2.9201 0 0 0 -2.9199 2.9199 2.9201 2.9201 0 0 0 2.9199 2.9199 2.9201 2.9201 0 0 0 2.9199 -2.9199 2.9201 2.9201 0 0 0 -2.9199 -2.9199zm-7 1.9199v2h2.8691a4.2662 4.0576 0 0 1 -0.13477 -1 4.2662 4.0576 0 0 1 0.13672 -1h-2.8711zm11.131 0a4.2662 4.0576 0 0 1 0.13477 1 4.2662 4.0576 0 0 1 -0.13672 1h2.8711v-2h-2.8691zm-5.1309 4.9395v3.0605h2v-3.0605a4.2662 4.0576 0 0 1 -1 0.11914 4.2662 4.0576 0 0 1 -1 -0.11914z" fill="#ff8484"/>
</svg>

After

Width:  |  Height:  |  Size: 894 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c18veogqnx5ht"
path="res://.godot/imported/icon_editor_position.svg-1f6e1977293add549ed436510f8834c1.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_editor_position.svg"
dest_files=["res://.godot/imported/icon_editor_position.svg-1f6e1977293add549ed436510f8834c1.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 0v3h-3v2h3v4h-3v2h3v3h2v-9h9v-2h-3v-3h-2v3h-4v-3zm4 13v2h2v-2zm6 0v2h2v-2z" fill="#e0e0e0"/><path d="m11 7a4 4 0 0 0 -4 4v2h2v-2a2 2 0 0 1 2-2 2 2 0 0 1 2 2v2h2v-2a4 4 0 0 0 -4-4z" fill="#fff" fill-opacity=".68627"/></svg>

After

Width:  |  Height:  |  Size: 317 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bojrgd0r131xh"
path="res://.godot/imported/icon_editor_snap.svg-f0374ecd8cb313d78a2acb46b093a7f1.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_editor_snap.svg"
dest_files=["res://.godot/imported/icon_editor_snap.svg-f0374ecd8cb313d78a2acb46b093a7f1.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon_width_handle.svg-55d6fdc3b3c08e53dc0bed806d2f0a8f.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_width_handle.svg"
dest_files=[ "res://.import/icon_width_handle.svg-55d6fdc3b3c08e53dc0bed806d2f0a8f.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon_width_handle0.svg-9a486a252970ecb72608cabecc20a9f6.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_width_handle0.svg"
dest_files=[ "res://.import/icon_width_handle0.svg-9a486a252970ecb72608cabecc20a9f6.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon_width_handle1.svg-a1da7c369cb74b89d2283c3679312805.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_width_handle1.svg"
dest_files=[ "res://.import/icon_width_handle1.svg-a1da7c369cb74b89d2283c3679312805.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon_width_handle2.svg-b02ee2da69342d687c1fd9680123e834.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_width_handle2.svg"
dest_files=[ "res://.import/icon_width_handle2.svg-b02ee2da69342d687c1fd9680123e834.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon_width_handle3.svg-3dcf9d2b715a3978009539d7a6640342.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_width_handle3.svg"
dest_files=[ "res://.import/icon_width_handle3.svg-3dcf9d2b715a3978009539d7a6640342.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon_width_handle4.svg-47fd86c3a89419c03da7bc2def15fbfa.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/icon_width_handle4.svg"
dest_files=[ "res://.import/icon_width_handle4.svg-47fd86c3a89419c03da7bc2def15fbfa.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 KiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b350jwt2tgchl"
path="res://.godot/imported/light1-1.png-433fe7882cc83fa28e02c4948a40f886.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/light1-1.png"
dest_files=["res://.godot/imported/light1-1.png-433fe7882cc83fa28e02c4948a40f886.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://olmio6gxe5d6"
path="res://.godot/imported/meta_shape.png-462cb0c943fa311edd3a47aeb27824d9.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/meta_shape.png"
dest_files=["res://.godot/imported/meta_shape.png-462cb0c943fa311edd3a47aeb27824d9.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cpg65u2v4mthq"
path="res://.godot/imported/open_shape.png-f18727d78226e221aef881edda953bbd.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/assets/open_shape.png"
dest_files=["res://.godot/imported/open_shape.png-f18727d78226e221aef881edda953bbd.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/shape.png-00d53041e0aeffe00cc49849dfbcc65f.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/shape.png"
dest_files=[ "res://.import/shape.png-00d53041e0aeffe00cc49849dfbcc65f.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=false
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/shape_anchor.png-c4527dad8f7093abc2088dd0157f0c72.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rmsmartshape/shape_anchor.png"
dest_files=[ "res://.import/shape_anchor.png-c4527dad8f7093abc2088dd0157f0c72.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@@ -0,0 +1,33 @@
@tool
extends Node
class_name SS2D_Common_Functions
static func sort_z(a, b) -> bool:
if a.z_index < b.z_index:
return true
return false
static func sort_int_ascending(a: int, b: int) -> bool:
if a < b:
return true
return false
static func sort_int_descending(a: int, b: int) -> bool:
if a < b:
return false
return true
static func to_vector3(vector: Vector2) -> Vector3:
return Vector3(vector.x, vector.y, 0)
static func merge_arrays(arrays: Array) -> Array:
var new_array := []
for array: Array in arrays:
for v: Variant in array:
new_array.push_back(v)
return new_array

View File

@@ -0,0 +1,47 @@
# SmartShape2D - Controls and Hotkeys
<!-- TODO: Likely, outdated. Should this even be covered in such detail? -->
## Controls - Point Create
- Add Point
- Left Click Anywhere in the viewport
- Leave Point Create Mode
- ESCAPE
## Controls - Point Edit
- Add Point
- Either:
- Hold ALT and Left Click Anywhere in the viewport
- Click on an edge between two points
- Grab closest point
- Hold CTRL
- Cycle through texture indices of a point
- Mouseover a point and MOUSEWHEEL up or down to increment / decrement the texture index
- Flip texture
- Mouseover a point and press SPACE
- Change texture width property
- Mouseover a point, hold SHIFT, then MOUSEWHEEL up or down to increment / decrement the texture width
- Add Bezier curve
- Mouseover a point, hold SHIFT, then click and drag to create control points on the point
- Create New Shape
- Hold SHFT + ALT and click
- The location of the click will be the the first point of a newly created Shape Node
### Overlap
When multiple points and edges overlap, it can be ambiguous what clicking will do.
SmartShape adheres the following rules:
- If a control point overlaps a vertex, the control point takes priority
- If a control point or vertex overlaps an edge:
- Clicking will move the control point or vert
- Clicking while holding ALT will create new point on the edge

View File

@@ -0,0 +1,47 @@
# SmartShape2D - FAQ
<!-- TODO: Outdated. -->
## Why aren't my textures repeating?
If your textures aren't repeating and look something like this:
![Non-Repeating-Texture-IMG](./imgs/faq-texture-repeat.png)
The issue is most likely that you need to set the texture's import options in Godot:
![Import-Texture-Settings](./imgs/faq-texture-repeat-import.png)
## Why isn't my shape updaing when I change the Light Mask?
Each shape is currently rendered by multiple-subnodes (Children Node2Ds).
Their owner isn't set, making them invisible in the editor (unless you have debug mode on).
Unfortunately, there is no accessible signal when changing the Light Mask setting in editor.
That means changing the Light Mask setting in editor won't trigger the children nodes to change THIER Light Mask
The Shape nodes CAN update their children's light mask, they just need to be triggered to do it manually.
If you update the shape in any way, the shape will update its children's light mask.
When playing the game, the render Node children are regenerated, ensuring that the light mask will be set
correctly.
The actual shape has set\_light\_mask overloaded, so changing the light\_mask in code should work without issue
If you need to manually tell the shape to update its rendering, call the set\_as\_dirty() method
If anyone has any insights on this issue, please feel free to open an issue on this subject
and let us know how we might be able to fix it
## Why does changing the width look so ugly?
Changing the width of the quads generally looks best with welding turned off.
If welding is on, you can still change the width of the quads, but you may need to play with it a bit.
It's best that you change the width gradually in small increments instead of sharply.
Sharply changing the width will result in odd looking shapes.
[Non-perspective rendering to a non-parallelogram is kinda tough](http://reedbeta.com/blog/quadrilateral-interpolation-part-1/)
If anyone has any insights on this issue, please feel free to open an issue on this subject
and let us know how we might be able to fix it

View File

@@ -0,0 +1,40 @@
# Using SmartShape2D with Godot 4
Godot 4 moved `repeat` for textures as an import option to a per-node option. On how to make textures repeat and
set normal maps see [section below.](#repeating-textures-and-normal-textures-with-canvastexture)
By default, **shape resources are shared** when the shape is copy-pasted. Editing points will edit every copy of that shape.
To make point geometry unique, press **"Make Unique"** property button in Geometry property group in the inspector:
![Making Shape Geometry Unique](imgs/godot4-make-points-unique.png)
## Repeating Textures and Normal Textures with CanvasTexture
CanvasItem, the base class of Node2D has a Texture section with `repeat`. If you aren't using a normal, you can set it here.
By default, this setting is inherited by children nodes so you could set it on a parent node (assuming all the children need
repeating textures or it's easier to disable for a few specific nodes than turn it on for most).
![Creating CanvasTexture](imgs/canvas-item-repeat.png)
Normal textures are no longer set in a material resource.
To set normal textures, you can create a `CanvasTexture` resource in the inspector on any property, that allows setting a `Texture2D`.
![Creating CanvasTexture](imgs/godot4-create-texture-res.png)
`CanvasTexture` allows you to assign diffuse texture and normal map texture, as well as set textures to `repeat`:
![Assigning Texture, Normal Map and Setting Repeat flag](img/../imgs/godot4-assign-normal-tex.png)
## Converting Projects from Godot 3.x
Scene files with shapes saved in Godot 3.x should load in Godot 4 project. However, you may encounter some issues. Here is a list of expected problems:
1. Textures are looking weird, not repeated.
2. Normal textures are not used.
Please read the section on [how to set repeat and use normal textures in Godot 4](#repeating-textures-and-normal-textures-with-canvastexture).
## Removed Features
- The Godot 4 version of this addon does not support 1.x RMSmartShape2D nodes anymore.
- SS2D_Shape_Meta node was removed, since its functionality is available copy-pasted shapes by default.

View File

@@ -0,0 +1,20 @@
# SmartShape2D - Install
## Asset Library
- After installing the plugin, you may encounter an error, this is normal.
- You need to restart Godot before using the plugin.
## Manual Install
- Clone the repository at https://github.com/SirRamEsq/SmartShape2D.
- Move the "addons/rmsmartshape" folder to your project's "addons" folder.
- Open your project in Godot to have the addon install.
- After installing the plugin, you may encounter an error, this is normal.
- Restart Godot.
## Activate Plugin
- After Installing the plugin, activate the plugin by navigating to `Project -> Project Settings... -> Plugins`
![Activate Plugin](./imgs/PluginActivate.png)

View File

@@ -0,0 +1,60 @@
# Normals
## Default Normals
Even if you assign normal textures to your Edge Material, the normals will look wrong.
For example, consider the following image:
![Normals Wrong](./imgs/NormalWrong.png)
The normals in the image clearly don't line up with where the light is actually coming from.
## Encoding Normal data in the canvas_item Vertex Shader Color Parameter
As SmartShape renders the edges, the textures and their normal textures are also rotated.
This will result in incorrect normals.
To solve this, we can use a shader to correctly calculate the normals.
The tricky part lies in how few ways there are to pass data to a canvasItem shader on a per-vertex basis.
See here for the full list:
https://docs.godotengine.org/en/stable/tutorials/shading/shading_reference/canvas_item_shader.html#doc-canvas-item-shader
Fortunately, the COLOR parameter can be used for this purpose.
The COLOR ENCODING paramter of an Edge Material can be used to choose what data is encoded in the
Vertex Shader's Color Parameter.
If we set the COLOR ENCODING value to "Normals", we get this:
![Normals wrong with weird diffuse colors](./imgs/NormalColors.png)
Ok, so now the normals still look wrong, but the colors look wrong too. Great.
There is one final step before our normals will be correct. We need to decode the normal data in a shader.
## Writing a Shader
You'll want to assign a new shader to the Edge Material's material property.
This shader will determine how each edge is rendered.
Here's a sample shader to decode our normal data and set our actual color to that of our diffuse texture:
```glsl
shader_type canvas_item;
varying mat2 NORMAL_MATRIX;
void vertex() {
NORMAL_MATRIX = mat2(COLOR.rg, COLOR.ba)*2.0 - mat2(vec2(1.0), vec2(1.0));
}
void fragment() {
NORMAL.xy = NORMAL_MATRIX*NORMAL.xy;
COLOR = texture(TEXTURE, UV);
}
```
After assigning this shader the the Edge Material's material property, our normals finally look right:
![Normals Correct](./imgs/NormalCorrect.png)

View File

@@ -0,0 +1,136 @@
# SmartShape2D - QuickStart
---
![Finished Image](./imgs/Inpsector-EdgeMaterialsNormalRange.png)
If you feel like your workflow with SmartShape2D is a little bit slow, try reading [Controls and Hotkeys](./Controls.md). The hotkeys may help you work with the tool more effectively.
## Basic understanding
SmartShapes work similarly to [tilesets](https://docs.godotengine.org/en/latest/tutorials/2d/using_tilesets.html) but are not bound to a grid. They can be used to create polygons and even organic shapes. This allows for level design akin to [Rayman Legends](https://youtu.be/WFu1utKAZ18?si=_33TaErpHSh-r732&t=916) (based on the UbiArt Framework).
Each SmartShape is made up of multiple textures that are responsible for rendering different aspects like corners or edges:
![Texture Breakdown](./imgs/smartshape_textures_breakdown.png)
## Creating a Shape
<!-- TODO: Outdated, including screenshots. -->
- First, instance a node of either:
- SS2D_Shape_Open
- **SS2D_Shape_Closed**
- **We'll use a closed shape for this Quickstart demo**
- SS2D_Shape_Base cannot be instanced directly
- SS2D_Shape_Anchor is a node that attaches to a shape
- The following Nodes are legacy nodes and are deprecated:
- RMSmartShape2D
- RMSmartShape2DAnchor
![Nodes](./imgs/NewNode-SS2D_Nodes.png)
## Editing the Shape
- After creating the shape node, make sure it's selected and the toolbar appears and is in Point Edit mode
- ![Toolbar Default State](./imgs/Toolbar-PointEdit.png)
- Hold ALT and Left Click on the viewport to add points
- If this is a closed shape, the polygon will close after adding the 3rd point
- You should now have a shape consisting of a few points and lines:
![Toolbar Default State](./imgs/ShapeClosed-Untextured.png)
## Setting the Fill Texture of the Shape (Closed Shape only)
- To give it some life, we'll want to edit the "Shape Material" in the Inspector
- Under "Shape Material" Expand "Fill Textures" and you'll see an empty array
- Set the Array's size to '1'
- Assign a texture to the newly created slot in the array
- After assigning the shape should now have a valid texture
- If nothing happens after setting the texture, try to force the shape to update by adjusting one of the points
- **Note that "Fill Textures" does not affect open shapes at all**
- If you want to add a normal_texture, you would add it using the "Fill Texture Normals" property
![Fill Texture Set](./imgs/ShapeClosed-FillTextured.png)
## Texturing the Edges
- This where the rubber hits the road, the real meat of the tool
- Under "Shape Material" add an element to the "Edge Meta Materials" property
- Shape Material -> Edge Meta Materials
- Set the resource of the newly created element to "SS2D_Material_Edge_Metadata"
- Unfortunately, due to Godot limitations, every avaiable resource will offered to you instead of the one you want
- The options are alphabetized though, which helps in finding the resource you want
- Expand the first element of the "Edge Meta Materials" that you just set
- Shape Material -> Edge Meta Materials -> element 1
- Set the value of the "Edge Material" property to a new resource of type "SS2D_Material_Edge"
- Shape Material -> Edge Meta Materials -> element 1 -> Edge Material
- Expand "Edge Material" that you just set
- Add an element to "Textures" and assign the texture to one that you want to use as an edge
- The shape's edges should now update using the texture you set
- If nothing happens after setting the texture, try to force the shape to update by adjusting one of the points
- If you want to add a normal_texture, you would add it using the "Texture Normals" property
- Godot should now look something like this:
![Inspector](./imgs/Inpsector-EdgeMaterial.png)
### Corners
- If your shape has sharp 90-degree corners, the texture can look a bit warped in those places
- You can specify a unique texture to use for inner and outer corners for each Edge Material
- The following Edge Material properties are used for corners
- Textures Corner Inner
- Texture Normals Corner Inner
- Textures Corner Outer
- Texture Normals Corner Outer
- See how the addition of outer corner textures improves the square created earlier
![Inspector](./imgs/Inpsector-EdgeMaterialCornerOuter.png)
### Multiple Edge Materials in One Edge
- You can add as many Edge Meta Materials as you want to a Shape Material, each with their own Edge Material
- For instance, you can add an additional egde with a rock texture (and its own set of corner textures) and have it render behind the grass
- To have it render behind the grass, Set the Z index of the meta material
![Inspector](./imgs/Inpsector-EdgeMaterials2.png)
### Normal Range
- Each Meta material has a Normal Range
- The Normal Range indicates when a texture should be rendered
- If the normal range is 0 - 360 or 0 - 0, then any angle is considered in range and the edge will always render
- Angle "0" is Facing directly Right
- Angle "90" is Facing directly Up
- Angle "180" is Facing directly Left
- Angle "270" is Facing directly Down
- If you wanted to, for example:
- Have rocks display on the bottom part of the shape only
- Have grass display on the sides and top of the shape only
- You could:
- Set the grass Normal Range to 0 - 180
- Set the rock Normal Range to 181 - 359
![Inspector](./imgs/Inpsector-EdgeMaterialsNormalRange.png)
### Material Overrides
- Using Material Overrides will allow you to change how specific edges are rendered
- For Example, to prevent the left edge from rendering, we'll do the following:
- Select the edge edit button from the toolbar ![](./imgs/icon_edge.png)
- Right Click the left edge of the shape
- Press the "Material Override" Button
- Uncheck the "Render" Checkbox
![Edge NoRender](./imgs/EdgeEdit-NoRender.png)
- You can use material overrrides to also specify a specific material for a single edge
- For example, Checking Render and choosing the "Rock" Edge Material will cause the edge to render as rocks, even though the NormalRange configuration would otherwise have it render as grass
### Multiple Textures
- If more than one texture is specified for an Edge Material, you can specify which texture should be used
- Enter Point Edit mode, mouseover a point, and scroll up or down to change the texture index
## Anchoring Nodes to the Shape
- To anchor nodes directly to the SmartShape2D node, use SmartSahpeAnchor2D
- You can then make nodes children to the anchor

View File

@@ -0,0 +1,115 @@
# SmartShape2D - Resources
<!-- TODO: Not all properties are covered. -->
## Shape Materials
Shape materials provide all the texture and collision information needed by the SmartShape nodes.
Once a shape material is defined, it can be easily reused by any number of SmartShape2D nodes.
- Edge Meta Materials
- An array of resources of type SS2D_Material_Edge_Metadata
- Fill Textures
- Used as the texture for the inside of the polygon for Closed Shapes
- Currently, only the first texture can be used, multiple textures may be supported at a later date
- Normal Textures
- In Godot 4, you can set normal textures with `CanvasTexture` resource.
- Fill Texture Z Index
- Each Edge Meta Material has a ZIndex indicating which edges are drawn first
- This sets the ZIndex for the fill texture
- This allows the user to draw the fill texture in front of some edges or behind others
- Fill Mesh Offset
- The Offset of the Fill Mesh
- Can be used to grow / shrink the fill mesh
- Render Offset
- Every edge in the shape will be offset by this amount
- Weld
- Whether or not to weld the last quad of an edge with the first quad of the next edge
## Edge Meta Material
An Edge Meta Material doesn't contain the actual textures used to render an edge like **Edge Material** does.
Instead, this resource contains a single **Edge Material** and describes how and when to render the edge.
- Normal Range
- The angles at which an edge is allowed to be rendered
- Weld
- Whether or not to weld the quads in this edge
- Taper Sharp Corners
- Edge vertices sharper than 90° that aren't rendered as corners, will be tapered and not welded
- Will not work properly on shapes with curves
- Render
- Whether or not this edge is visible
- Z Index
- Dictates the order in which edges are drawn
- Offset
- Offset of the edge
- Can use a positive or negative value to draw the edges closer or further from the shape
## Normal Range
The Normal Range indicates when a texture should be rendered.
Each shape will compare the Surface Normal of an edge to the Normal Range in each Edge Meta Material.
If the edge's Normal is inside a Meta Material's Normal Range, the Meta Material's Edge Material is rendered.
![NormalRangeVisual](./imgs/AngleExplaination.png)
- A Normal Range is specified in Degrees
- If the normal range is 0 - 360 or 0 - 0, any angle is considered in range and the edge will always render
- Angle "0" is Facing directly Right
- Angle "90" is Facing directly Up
- Angle "180" is Facing directly Left
- Angle "270" is Facing directly Down
## Edge Material
The actual textures used to define an edge
### Textures
- The primary textures used for the edge
- At least one texture must be defined
- Example: ![Grass](./imgs/grass.png)
### Taper Textures
These textures will be used as the first or last quad in an edge.
They're named "Taper Textures" because the purpose is to show the edge "tapering off"
- Textures_Taper_Left is the first quad in an edge
- Example: ![Grass Taper Left](./imgs/grass-taper-left.png)
- Textures_Taper_Right is the final quad in an edge
- Example: ![Grass Taper Right](./imgs/grass-taper-right.png)
### Corner Textures
These textures will be used when the edge forms a sharp corner (80 degrees - 100 degrees)
These are used because corners can look warped when using only regular textures
- Texture_Corner_Inner is used when the corner forms an inner corner
- Example: ![Grass Corner Inner](./imgs/grass-corner-inner.png)
- Texture_Corner_Outer is used when the corner forms an outer angle
- Example: ![Grass Corner Outer](./imgs/grass-corner-outer.png)
### Normal Texture and Repeat
To use normal textures, you can create a `CanvasTexture` resource in the inspector on any property,
that allows to set a texture. There you can assign your texture and your normal texture, as well as set
those to `repeat`.
### Repeat Textures
See previous section.
### Fit Mode
Most likely, the textures you use will not *perfectly* fit the polygon.
This setting allows you to determine how SmartShape will rectify this.
Differt options may look better or worse depending on the art-style.
- Sqush and Stretch
- Texture will be mutated
- Either slightly squished or stretched to fit the polygon
- Crop
- Texture will not be mutated
- Texture will simply be cropped when changing from one texture to the next

View File

@@ -0,0 +1,88 @@
# SmartShape2D - Shapes
Each shape consists of a set of points. You can directly edit either the points or the edges between the points in the viewport.
Shapes are configured to use a [Shape Material](./Resources.md#ShapeMaterial) which determines how the shape is rendered.
A shape can be open or closed. Each new shape starts open. To close a shape, simply add a point on top of the first one.
## Properties
> 🛈 Most properties now have documentation comments.
<!-- TODO: this is incomplete - not all properties are here -->
### Editor Debug
- Will show the bounding box for each quad in the mesh of edges.
- Can be helpful to illustrate why a shape doesn't look the way you expect.
### Flip Edges
- Will flip the edges of the shape (invert y).
### Render Edges
- Whether or not the edges of the shape should be rendered.
### Collision Size
- Size of the collision shape.
### Collision Offset
- Offset of where the collision shape starts and ends.
- A **positive** value offsets the collision shape **outwards**.
- A **negative** value offsets the collision shape **inwards**.
### Tessellation Stages
- Number of stages in the curve tessellation process (Uses Curve2D Internally).
- First Param in Curve2D.tessellate.
- See [Curve2D Documentation](https://docs.godotengine.org/en/3.2/classes/class_curve2d.html#class-curve2d-method-tessellate).
### Tessellation Tolerence
- Tolerence Degrees in the curve tessellation process (Uses Curve2D Internally).
- Second Param in Curve2D.tessellate.
- See [Curve2D Documentation](https://docs.godotengine.org/en/3.2/classes/class_curve2d.html#class-curve2d-method-tessellate).
### Collision Generation Method
- Controls which method should be used to generate the collision shape.
- See also in-engine documentation.
### Collision Update Mode
- Controls when to update collisions.
- See also in-engine documentation.
### Curve Bake Interval
- Bake interval value for Curve2D.
- See [Curve2D Documentation](https://docs.godotengine.org/en/3.2/classes/class_curve2d.html#class-curve2d-property-bake-interval).
### Collision Polygon Node Path
- The path to the CollisionShape that the SmartShape will use for collision.
- Is Autoset when pressing the generate collision button.
### Shape Material
- The material that this shape will use to render itself.
- For backwards compatibility `fill_texture_z_index` defaults to `-10`. Set this to `0` and enable `fill_texture_show_behind_parent` in order to preserve Godot's normal z-sorting when layering with other nodes.
### Points
- **There is no need to edit this property by hand, but you can if you'd like.**
- Contains all of the points and meta-data for the points contained in this shape.
- This data structure is updated as you manipulate the shape.
### Material Overrides
- **There is no need to edit this property by hand, but you can if you'd like.**
- When an edge is given a "Material Override" the data for that edge is stored here.
- This data structure is updated as you manipulate the shape.
![EdgeData Popup](./imgs/EdgeEdit-MaterialOverride.png)

View File

@@ -0,0 +1,53 @@
# SmartShape2D - Toolbar
![Toolbar Default State](./imgs/Toolbar-PointEdit.png)
<!-- TODO: Incomplete set of tools presented here. -->
## Create Mode
- In this mode you can start creating a new shape.
- Left-Click anywhere to add a new point.
- Press ESCAPE to exit create mode.
- Hold down ALT and Left-Click to create a point between the two points closest to your mouse.
## Point Mode
- In this mode you can add, delete, and move all of the points that make up a shape
- To **Add** a new point to the shape:
- Hold down ALT and Left-Click anywhere on the viewport to add a point between the two points closest to your mouse.
- Left-Click on an edge between two points.
- To **Move** a point, Left-Click on any point and drag
- To **Delete** a point, Right-Click on any point
- To set the **Control Points** of a point (for curves), hold **Shift**, Left Click on any point and drag
- After the Control Points have been set, you can edit them individually by Left-Clicking and dragging
- You can delete control points by right clicking them
- To make an empty clone SmartShape2D, hold down ALT + SHIFT and Left-Click anywhere in the viewport.
## Edge Mode
- In this mode you can Move Eges and choose how specific edges are rendered
- To **Move** an Edge, Left Click and Drag the Edge
- To **Change an Edges Rendering**, right click the edge and press "**Material Override**"
![EdgeData Popup](./imgs/EdgeEdit-MaterialOverride.png)
- This popup allows you to **change how edges are rendered**
- **Render** will toggle whether or not this edge will be drawn with Edge Materials
- **Set Material** allows you to choose a specific Edge Material to use to render this edge
## Origin Set
- This tool allows you to set the origin of any SmartShape
- To **Set the Origin** Left Click anywhere on the viewport
## Generate Collision
- If you want your shape to have collision, press this button to autogenerate the collision nodes
- The shape will be made a child of a newly created **StaticBody2D**
- A sibling node, **CollisionPolygon2D** will also be created and added to the SceneTree
- The "Collision Polygon" parameter of the Shape will be set to this sibling **CollisionPolygon2D**
## Snapping
When Moving / Adding points, snapping will cause the positions of the points to snap to the grid. This works the same as Godot's built-in snapping.
You can have snapping either use Global Space, or space relative to the shape's origin.

View File

@@ -0,0 +1,117 @@
# Version History
## 2.x
### 2.2
January 4th 2021
### Fix
- Fix for crash that would occur when points were aligned *just* right
- See issue 66
+ https://github.com/SirRamEsq/SmartShape2D/issues/66
### Features
- Each Edge Material can now have a Material (Shader)
- Each Edge Material Meta can have a z-index and z-as-relative set
- See issue 64
+ https://github.com/SirRamEsq/SmartShape2D/issues/64
### 2.1
December 14th 2020
#### Significant Changes from 2.0
- Improved Width handling
- Improved Welding
- Rendering is now achieved by having multiple child-nodes each render a piece of the shape
+ Previously, all the rendering was done by the shape node
+ Improves performance
+ Fixes lighting bugs
- Point Creation mode reimplemented
+ Mode active by default
+ Can be exited by pressing ESC
- Several usability additions
+ Hotkey for grabbing closest point
+ Hotkey for creating new shape at point
+ Width Grabber for closest point
+ Preview for adding points
- Several Bug fixes and issues closed
#### New Features
- Meta Shapes Introduced
- "Fit mode" added to edge material
+ Can either squash and stretch the texture or crop it
#### Minor Changes
- Changes to GUI Theme
+ More in line with standard Godot
- Add windows scripts for running unit tests
- Changed default snap settings to 8x8 pixels
### 2.0
September 7th 2020
#### Significant Changes from 1.0
- Edge Textures are no longer determined by a cardinal direction (UP, DOWN, LEFT, RIGHT)
- Instead, a starting and ending normal angle is specified for each edge
- Textures are now defined per-edge instead of per-shape
#### New Features
- Taper textures
- Instead of simply ending, the user can have an edge "taper-off"
- Editing by Edges
- Material Overrides
#### Internal Changes
- Completely overhauled everything
- A rudimentary constraint system is in place
- Closed shapes will add a point when closing, then constrain the added point's position to the first point
- Points are no longer refered to by index, they are refered to by keys
- This enables points to have relationships that aren't affected when:
- Adding/Removing a point
- Changing orientation of the poly
- Many Unit and Integration tests
- Refactored original working code to better support testing
- Kept original scripts and classes from version 1.0 to ease importing
## 1.x
### Changes in 1.3
This update primarily fixes bugs and improves existing features to be more usable.
#### Changes
- Merged top/left/right/bottom offset into one variable. render offset
#### Fixes
- Input bugs
- Edge Flipping
- Polygon orientation bugs
- Quad Welding
- Corer quad generation and welding
- Collision variables in the RMSmartShapeMaterial working as intended
### Changes in 1.2
#### Tweaks
- Refactoring
- Toolbar takes less space
- Minor bug fixes
#### New Features
- Bezier Curves!
- Hold shift on a control point to create a curve
- Corner Quads!
- Both inner and outer corner quads are now generated
- Textures can be speciied for each direction of both inner and outer quads
- Edge Moving!
- Can move an edge (two points) by pressing SHIFT in move mode and dragging the edge
### Changes in 1.1
- Refactoring
- Fixed Errors Occuring when Texture Arrays are size '0' but not null
- Fixed sync between texture, flip, and width indicies
- Would sometimes share a single array between the 3 vars
- Are all unique now
- Snapping
- More informative toolbar
### Changes in 1.0
- Fixed many debug errors reported related to indexing beyond array sizes
- Fixed control point wrapping of RMSmartShapeAnchor2D nodes anchored to RMSmartShape2D nodes.
- Tested on newly released 3.2 Godot.
### Changes in 0.91
- Edges are calculated in relationship to object space instead of screen space
- Added option to allow user to let the object recalculate edges based on screen space.
- Fixed uv calculations for flipped textures.
- Fixed uv bug for edge sections less than half the size of texture width
- Added option to allow for a RMSmartShapeAnchor to mimic scale of monitored node
- Removed sections of code related to clockwise versus clockwise checks, very specifically regarding the direction of texture edges.
- Corrected normal texture bug for fill and edge rendering

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Some files were not shown because too many files have changed in this diff Show More