└── addons └── planet2d ├── icons ├── PlanetLayer.svg ├── PlanetLayer.svg.import ├── PlanetLayers.svg └── PlanetLayers.svg.import ├── palette ├── cosine_generator.gd ├── palette_generator.gd └── palette_gradient.gd ├── planet.gdshader ├── planet_layer.gd ├── planet_layers.gd ├── plugin.cfg └── plugin.gd /addons/planet2d/icons/PlanetLayer.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 27 | 61 | 76 | 77 | 96 | 105 | 109 | 116 | 142 | 146 | 147 | -------------------------------------------------------------------------------- /addons/planet2d/icons/PlanetLayer.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://b4yitophtuce5" 6 | path="res://.godot/imported/PlanetLayer.svg-ffadbba9170efb82a4910e12c61fbbbd.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://addons/planet2d/icons/PlanetLayer.svg" 14 | dest_files=["res://.godot/imported/PlanetLayer.svg-ffadbba9170efb82a4910e12c61fbbbd.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | svg/scale=1.0 36 | editor/scale_with_editor_scale=false 37 | editor/convert_colors_with_editor_theme=false 38 | -------------------------------------------------------------------------------- /addons/planet2d/icons/PlanetLayers.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 27 | 61 | 76 | 77 | 96 | 105 | 109 | 116 | 142 | 146 | 147 | -------------------------------------------------------------------------------- /addons/planet2d/icons/PlanetLayers.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bi21foirwb2mh" 6 | path="res://.godot/imported/PlanetLayers.svg-640ac274a582f0c56fbffaa642f9eb4d.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://addons/planet2d/icons/PlanetLayers.svg" 14 | dest_files=["res://.godot/imported/PlanetLayers.svg-640ac274a582f0c56fbffaa642f9eb4d.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | svg/scale=1.0 36 | editor/scale_with_editor_scale=false 37 | editor/convert_colors_with_editor_theme=false 38 | -------------------------------------------------------------------------------- /addons/planet2d/palette/cosine_generator.gd: -------------------------------------------------------------------------------- 1 | class_name CosineGenerator extends PaletteGenerator 2 | 3 | @export var offset := Vector3(): 4 | set = _set_offset 5 | @export var amplitude := Vector3(): 6 | set = _set_amplitude 7 | @export var frequency := Vector3(): 8 | set = _set_frequency 9 | @export var phase := Vector3(): 10 | set = _set_phase 11 | 12 | @export var alpha_enabled := false: 13 | set = _set_alpha_enabled 14 | @export var alpha := Vector4(): 15 | set = _set_alpha 16 | 17 | func _generate_1d(t:float, offset:float, amplitude:float, frequency:float, phase:float)->float: 18 | return offset + amplitude * cos(2 * PI * (frequency * t + phase)) 19 | 20 | func generate_color(t:float)->Color: 21 | return Color( 22 | _generate_1d(t, offset.x, amplitude.x, frequency.x, phase.x), 23 | _generate_1d(t, offset.y, amplitude.y, frequency.y, phase.y), 24 | _generate_1d(t, offset.z, amplitude.z, frequency.z, phase.z), 25 | _generate_1d(t, alpha.x, alpha.y, alpha.z, alpha.w) if alpha_enabled else 1.0, 26 | ) 27 | 28 | func generate(gradient:Gradient): 29 | for i in gradient.get_point_count(): 30 | var t := gradient.get_offset(i) 31 | var color := generate_color(t) 32 | gradient.set_color(i, color) 33 | 34 | func _set_offset(v:Vector3)->void: 35 | if offset == v: return 36 | offset = v 37 | emit_changed() 38 | 39 | func _set_amplitude(v:Vector3)->void: 40 | if amplitude == v: return 41 | amplitude = v 42 | emit_changed() 43 | 44 | func _set_frequency(v:Vector3)->void: 45 | if frequency == v: return 46 | frequency = v 47 | emit_changed() 48 | 49 | func _set_phase(v:Vector3)->void: 50 | if phase == v: return 51 | phase = v 52 | emit_changed() 53 | 54 | func _set_alpha_enabled(v:bool)->void: 55 | if alpha_enabled == v: return 56 | alpha_enabled = v 57 | emit_changed() 58 | 59 | func _set_alpha(a:Vector4)->void: 60 | if alpha == a: return 61 | alpha = a 62 | emit_changed() 63 | -------------------------------------------------------------------------------- /addons/planet2d/palette/palette_generator.gd: -------------------------------------------------------------------------------- 1 | class_name PaletteGenerator extends Resource 2 | 3 | func generate_color(t:float)->Color: 4 | return Color() 5 | 6 | func generate(gradient:Gradient)->void: 7 | pass 8 | -------------------------------------------------------------------------------- /addons/planet2d/palette/palette_gradient.gd: -------------------------------------------------------------------------------- 1 | class_name PaletteGradient extends Gradient 2 | 3 | @export var generator:PaletteGenerator: 4 | set = _set_generator 5 | @export var resolution:int: 6 | set = _set_resolution 7 | 8 | func _get_color(offset:float)->Color: 9 | return generator.generate_color(offset) if generator else Color() 10 | 11 | func create_resolution(resolution:int)->void: 12 | while get_point_count() > 2: remove_point(0) 13 | set_offset(0, 0.0) 14 | set_color(0, _get_color(0.0)) 15 | set_offset(1, 1.0) 16 | set_color(1, _get_color(1.0)) 17 | var step := 1.0 / float(resolution) 18 | for i in (resolution - 2): 19 | var offset := (i + 1) * step 20 | add_point(offset, generator.generate_color(offset) if generator else Color()) 21 | 22 | func apply()->void: 23 | generator.generate(self) 24 | 25 | func _set_generator(g:PaletteGenerator)->void: 26 | if generator: 27 | generator.changed.disconnect(_on_generator_changed) 28 | 29 | generator = g 30 | 31 | if generator: 32 | apply() 33 | generator.changed.connect(_on_generator_changed) 34 | 35 | func _set_resolution(r:int)->void: 36 | create_resolution(r) 37 | 38 | func _on_generator_changed()->void: 39 | apply() 40 | -------------------------------------------------------------------------------- /addons/planet2d/planet.gdshader: -------------------------------------------------------------------------------- 1 | shader_type canvas_item; 2 | render_mode unshaded; 3 | 4 | const float PI2 = PI / 2.0; 5 | const vec3 UP = vec3(0.0, 0.0, 1.0); 6 | 7 | uniform vec2 texture_scale = vec2(0.5, 0.5); 8 | uniform vec2 texture_offset = vec2(0.0, 0.0); 9 | 10 | uniform vec3 atmosphere_color = vec3(1.0, 1.0, 1.0); 11 | uniform float atmosphere_intensity = 0.0; 12 | 13 | uniform vec3 light_color = vec3(1.0, 1.0, 1.0); 14 | uniform vec3 light_direction = vec3(0.0, 0.0, 1.0); 15 | uniform float light_minimum = 0.0; 16 | uniform float light_maximum = 1.0; 17 | 18 | uniform vec3 specular_color = vec3(1.0, 1.0, 1.0); 19 | uniform float specular_intensity = 0.1; 20 | uniform float specular_shininess = 1.0; 21 | 22 | uniform float fade = 0.0; 23 | 24 | uniform bool pixelize_enabled = false; 25 | uniform float pixelize_scale = 1.0; 26 | 27 | float z_from_xy(vec2 vector) { 28 | return sqrt(1.0 - vector.x * vector.x - vector.y * vector.y); 29 | } 30 | 31 | vec2 transform_uv(vec2 uv, vec2 texel) { 32 | // Center uv coordinates 33 | uv = (uv - vec2(0.5, 0.5)) * 2.0; 34 | // Quantize UV resolution 35 | vec2 resolution = (1.0 / texel) * pixelize_scale; 36 | return mix(uv, round(uv * resolution) / resolution, float(pixelize_enabled)); 37 | } 38 | 39 | vec2 spherical_distort(vec2 uv) { 40 | // Spherical Displacement 41 | float radius = length(uv); 42 | float displacement_scale = (radius != 0.0 ? asin(radius) / radius : 0.0) / PI2; 43 | vec2 displacement = uv * displacement_scale; 44 | return (displacement + texture_offset) * texture_scale; 45 | } 46 | 47 | mat3 generate_normal_matrix(vec3 normal) { 48 | vec3 T = normalize(cross(normal, vec3(normal.z, -normal.y, -normal.x))); 49 | vec3 B = normalize(cross(normal, T)); 50 | vec3 N = normal; 51 | return mat3(T, B, N); 52 | } 53 | 54 | vec3 atmospherics(vec3 color, vec3 normal) { 55 | // Atmospherics 56 | float atmospheric_coefficient = 1.0 - max(dot(normal, UP), 0.0); 57 | float atmospheric_density = mix(atmosphere_intensity, 1.0, atmospheric_coefficient); 58 | 59 | return mix(color, atmosphere_color, atmospheric_density); 60 | } 61 | 62 | vec3 get_diffuse(vec3 normal, vec3 light_normal, vec3 color) { 63 | // Diffuse 64 | float light_dot = max(dot(normal, light_normal), 0.0); 65 | float diffuse_coefficient = mix(light_minimum, light_maximum, light_dot); 66 | return (color * diffuse_coefficient) * light_color; 67 | } 68 | 69 | vec3 get_specular(vec3 normal, vec3 light_normal, float shininess) { 70 | // Specular 71 | shininess = mix(1.0, specular_shininess * specular_shininess, shininess); 72 | float reflect_dot = dot(reflect(-light_normal, normal), UP); 73 | float specular_coefficient = specular_intensity * pow(max(0.0, reflect_dot), shininess); 74 | return (specular_color * specular_coefficient) * light_color; 75 | } 76 | 77 | void fragment() { 78 | vec2 uv = transform_uv(UV, TEXTURE_PIXEL_SIZE); 79 | vec3 normal = vec3(uv, z_from_xy(uv)); 80 | float radius = length(uv); 81 | 82 | vec3 light_normal = normalize(light_direction); 83 | 84 | // Spherical Displacement 85 | vec2 displaced_uv = spherical_distort(uv); 86 | 87 | // Get inputs from samplers 88 | vec4 input_color = texture(TEXTURE, displaced_uv); 89 | vec4 input_shininess = texture(SPECULAR_SHININESS_TEXTURE, displaced_uv); 90 | vec3 input_normal = texture(NORMAL_TEXTURE, displaced_uv).xyz * 2.0 - 1.0; 91 | input_normal.xy = -input_normal.yx; 92 | 93 | // Adjust Normal to Normal Map 94 | mat3 normal_matrix = generate_normal_matrix(normal); 95 | vec3 displaced_normal = normal_matrix * input_normal; 96 | 97 | float light_dot = smoothstep(-0.4, 0.0, dot(normal, light_normal)); 98 | float global_light = mix(light_minimum, light_maximum, light_dot); 99 | 100 | vec3 diffuse = get_diffuse(displaced_normal, light_normal, input_color.rgb); 101 | vec3 specular = get_specular(displaced_normal, light_normal, input_shininess.r); 102 | 103 | COLOR.rgb = (diffuse + specular) * global_light; 104 | 105 | float fade_texels = length(TEXTURE_PIXEL_SIZE) * fade; 106 | float alpha = 1.0 - smoothstep(1.0 - fade_texels, 1.0, radius); 107 | COLOR.a = alpha * input_color.a; 108 | } 109 | -------------------------------------------------------------------------------- /addons/planet2d/planet_layer.gd: -------------------------------------------------------------------------------- 1 | @icon("res://addons/planet2d/icons/PlanetLayer.svg") 2 | class_name PlanetLayer extends Sprite2D 3 | 4 | ## A Sprite2D with a [ShaderMaterial] (using [constant PlanetLayerShader]), a spherical distort shader with additional lighting effects. 5 | ## 6 | ## Any [Texture2D] can be attached to this Sprite2D and it will spherically distort it, with lighting effects. 7 | ## To have the effect of spinning, modify the [member texture_offset] to scroll the texture. If using [NoiseTexture2D], consider using [member NoiseTexture2D.color_ramp] to give more interesting results. 8 | 9 | ## Spherical distort and lighting shader 10 | const PlanetLayerShader := preload("res://addons/planet2d/planet.gdshader") 11 | 12 | @export_group("Texture", "texture_") 13 | 14 | ## Scales texture itself in the spherical rendering. At [1.0], texture repetition could be visible at texture boundaries. [0.5] ensures no repetition is visible. 15 | ## This will affect the range of [member texture_offset]. When set to [0.5], the range of [member texture_offset] becomes [0.0 - 2.0]. 16 | @export var texture_scale := Vector2(0.5, 0.5): 17 | set(ts): 18 | texture_scale = ts 19 | material.set_shader_parameter("texture_scale", texture_scale) 20 | 21 | ## The amount to scroll the texture by. The value is in UV coordinates, [0.0 - 1.0] is a full texture size scroll, if [member texture_scale] is 1.0. 22 | @export var texture_offset := Vector2(): 23 | set(to): 24 | texture_offset = to 25 | material.set_shader_parameter("texture_offset", texture_offset * texture_offset_scale) 26 | 27 | ## Scales the effect of [member texture_offset]. A higher scale will result in faster scrolling for the same offset. 28 | @export var texture_offset_scale := 1.0: 29 | set(tos): 30 | texture_offset_scale = tos 31 | material.set_shader_parameter("texture_offset", texture_offset * texture_offset_scale) 32 | 33 | @export_group("Atmosphere", "atmosphere_") 34 | 35 | ## Color of the atmosphere, primarily at the edges of the sphere at low values. Gives a fog effect. 36 | @export var atmosphere_color := Color(1.0, 1.0, 1.0): 37 | set(ac): 38 | atmosphere_color = ac 39 | material.set_shader_parameter("atmosphere_color", atmosphere_color) 40 | 41 | ## Controls the density of the atmosphere. At higher values, the texture itself will become invisible as it is enveloped by the atmosphere. 42 | @export var atmosphere_intensity := 0.0: 43 | set(ai): 44 | atmosphere_intensity = ai 45 | material.set_shader_parameter("atmosphere_intensity", atmosphere_intensity) 46 | 47 | @export_group("Light", "light_") 48 | 49 | ## Color of the light affecting this layer. 50 | @export var light_color := Color(1.0, 1.0, 1.0): 51 | set(lc): 52 | light_color = lc 53 | material.set_shader_parameter("light_color", light_color) 54 | 55 | ## The direction to the light source. This vector is normalized in the shader. 56 | @export var light_direction := Vector3(0.0, 0.0, 1.0): 57 | set(ld): 58 | light_direction = ld 59 | material.set_shader_parameter("light_direction", light_direction) 60 | 61 | ## Minimum light level. 62 | @export var light_minimum := 0.1: 63 | set(lm): 64 | light_minimum = lm 65 | material.set_shader_parameter("light_minimum", light_minimum) 66 | 67 | ## Maximum light level. 68 | @export var light_maximum := 1.0: 69 | set(lm): 70 | light_maximum = lm 71 | material.set_shader_parameter("light_maximum", light_maximum) 72 | 73 | @export_group("Specular", "specular_") 74 | 75 | ## Color of the specular effect. 76 | @export var specular_color := Color(1.0, 1.0, 1.0): 77 | set(sc): 78 | specular_color = sc 79 | material.set_shader_parameter("specular_color", specular_color) 80 | 81 | ## Specular intensity, or brightness. Reasonable values are from [0.0 - 1.0]. 82 | @export var specular_intensity := 0.2: 83 | set(si): 84 | specular_intensity = si 85 | material.set_shader_parameter("specular_intensity", specular_intensity) 86 | 87 | ## The shininess of the material. Lower values will result in very diffused specular highlights (ex: ground). Higher values will have a smaller highlight (ex: water). 88 | @export var specular_shininess := 1.0: 89 | set(ss): 90 | specular_shininess = ss 91 | material.set_shader_parameter("specular_shininess", specular_shininess) 92 | 93 | @export_group("Pixelize", "pixelize_") 94 | ## Enable planet rendering pixelization 95 | @export var pixelize_enabled := false: 96 | set(pe): 97 | pixelize_enabled = pe 98 | material.set_shader_parameter("pixelize_enabled", pixelize_enabled) 99 | 100 | ## Resolution scale of the render output. 0.5 means each pixel is 2x larger. 101 | @export var pixelize_scale := 1.0: 102 | set(ps): 103 | pixelize_scale = ps 104 | material.set_shader_parameter("pixelize_scale", pixelize_scale) 105 | 106 | func _init()->void: 107 | texture_repeat = CanvasItem.TEXTURE_REPEAT_ENABLED 108 | 109 | material = ShaderMaterial.new() 110 | material.shader = PlanetLayerShader 111 | 112 | func _ready()->void: 113 | update() 114 | 115 | ## Apply all parameters to the shader. Parameters should be applied as you set them, but in vector properties, you might need to update manually if setting member variables. 116 | func update()->void: 117 | material.set_shader_parameter("texture_scale", texture_scale) 118 | material.set_shader_parameter("texture_offset", texture_offset * texture_offset_scale) 119 | 120 | material.set_shader_parameter("atmosphere_color", atmosphere_color) 121 | material.set_shader_parameter("atmosphere_intensity", atmosphere_intensity) 122 | 123 | material.set_shader_parameter("light_color", light_color) 124 | material.set_shader_parameter("light_direction", light_direction) 125 | material.set_shader_parameter("light_minimum", light_minimum) 126 | material.set_shader_parameter("light_maximum", light_maximum) 127 | 128 | material.set_shader_parameter("specular_color", specular_color) 129 | material.set_shader_parameter("specular_intensity", specular_intensity) 130 | material.set_shader_parameter("specular_shininess", specular_shininess) 131 | 132 | material.set_shader_parameter("pixelize_enabled", pixelize_enabled) 133 | material.set_shader_parameter("pixelize_scale", pixelize_scale) 134 | -------------------------------------------------------------------------------- /addons/planet2d/planet_layers.gd: -------------------------------------------------------------------------------- 1 | @icon("res://addons/planet2d/icons/PlanetLayers.svg") 2 | class_name PlanetLayers extends Node2D 3 | 4 | ## A simple container to control child [PlanetLayer] node properties should reasonably be the same for a single planet. 5 | ## 6 | ## Also provides an easy way to have a spinning effect for all child [PlanetLayer] nodes. 7 | ## Use [method add_layer] and [method remove_layer] to register the [PlanetLayer] with this node. 8 | 9 | ## All child [PlanetLayer] nodes. 10 | var layers:Array[PlanetLayer] = [] 11 | 12 | ## Sets the spin mode, applied at this node's [method _process] event. Must have a non-zero [member spin] vector set to have any effect. 13 | @export var is_spinning := false 14 | ## Speed of the spinning. The values are effectively delta [member PlanetLayer.texture_offset] per second. 15 | @export var spin := Vector2() 16 | 17 | ## Controls the [member PlanetLayer.texture_offset] of all child [PlanetLayer] nodes. 18 | @export var texture_offset := Vector2(): 19 | set(to): 20 | texture_offset = to 21 | set_parameter("texture_offset", texture_offset) 22 | 23 | @export_group("Light", "light_") 24 | ## Controls the [member PlanetLayer.light_color] of all child [PlanetLayer] nodes. 25 | @export var light_color := Color(1.0, 1.0, 1.0): 26 | set(lc): 27 | light_color = lc 28 | set_parameter("light_color", light_color) 29 | 30 | ## Controls the [member PlanetLayer.light_direction] of all child [PlanetLayer] nodes. 31 | @export var light_direction := Vector3(0.0, 0.0, 1.0): 32 | set(ld): 33 | light_direction = ld 34 | set_parameter("light_direction", light_direction) 35 | 36 | ## Controls the [member PlanetLayer.light_minimum] of all child [PlanetLayer] nodes. 37 | @export var light_minimum := 0.0: 38 | set(lm): 39 | light_minimum = lm 40 | set_parameter("light_minimum", light_minimum) 41 | 42 | ## Controls the [member PlanetLayer.light_maximum] of all child [PlanetLayer] nodes. 43 | @export var light_maximum := 1.0: 44 | set(lm): 45 | light_maximum = lm 46 | set_parameter("light_maximum", light_maximum) 47 | 48 | @export_group("Pixelize", "pixelize_") 49 | ## Enable planet rendering pixelization 50 | @export var pixelize_enabled := false: 51 | set(pe): 52 | pixelize_enabled = pe 53 | set_parameter("pixelize_enabled", pixelize_enabled) 54 | 55 | ## Resolution scale of the render output. 0.5 means each pixel is 2x larger. 56 | @export var pixelize_scale := 1.0: 57 | set(ps): 58 | pixelize_scale = ps 59 | set_parameter("pixelize_scale", pixelize_scale) 60 | 61 | func _ready()->void: 62 | for c in get_children(): 63 | if not c is PlanetLayer: 64 | continue 65 | layers.push_back(c as PlanetLayer) 66 | update() 67 | 68 | func _process(delta): 69 | if is_spinning: 70 | texture_offset += spin * delta 71 | 72 | ## Applies all properties to all child [PlanetLayer] nodes. 73 | func update()->void: 74 | set_parameter("texture_offset", texture_offset) 75 | 76 | set_parameter("light_color", light_color) 77 | set_parameter("light_direction", light_direction) 78 | set_parameter("light_minimum", light_minimum) 79 | set_parameter("light_maximum", light_maximum) 80 | 81 | set_parameter("pixelize_enabled", pixelize_enabled) 82 | set_parameter("pixelize_scale", pixelize_scale) 83 | 84 | ## Utility method to set a property on child [PlanetLayer] nodes. 85 | func set_parameter(name:String, value:Variant)->void: 86 | for l in layers: 87 | l.set(name, value) 88 | 89 | ## Utility method to set a Shader uniform on child [PlanetLayer] nodes. 90 | func set_shader_parameter(name:String, value:Variant)->void: 91 | for l in layers: 92 | l.material.set_shader_parameter(name, value) 93 | 94 | ## Add a new [PlanetLayer] to this node. It must not have a parent, as it is with [method Node.add_child]. 95 | func add_layer(layer:PlanetLayer)->void: 96 | if layers.has(layer) || layer.get_parent(): 97 | return 98 | 99 | add_child(layer) 100 | layers.push_back(layer) 101 | 102 | update() 103 | 104 | ## Remove a [PlanetLayer]. 105 | func remove_layer(layer:PlanetLayer)->void: 106 | if !layers.has(layer): 107 | return 108 | layers.erase(layer) 109 | remove_child(layer) 110 | -------------------------------------------------------------------------------- /addons/planet2d/plugin.cfg: -------------------------------------------------------------------------------- 1 | [plugin] 2 | 3 | name="Planet2D" 4 | description="Utility classes as a Shader wrapper to create pseudo-3D planets from 2D textures." 5 | author="PDeveloper" 6 | version="1.0" 7 | script="plugin.gd" 8 | -------------------------------------------------------------------------------- /addons/planet2d/plugin.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends EditorPlugin 3 | --------------------------------------------------------------------------------