@tool extends Control class_name CloudsEditorController @export_category("Driver Tools") @export var CloudsStatusLabel : Label @export var CloudsActiveToggle : CheckButton @export var CloudsDriverRefresh : Button @export var CloudsDriverAccordianButton : AccordionButton @export_category("Mask Tools") @export var UseMaskToggle : CheckButton @export var MaskStatusLabel : Label @export var MaskFilePath : LineEdit @export var MaskResolution : SpinBox @export var MaskWidth : SpinBox @export_category("Draw Tools") @export var DrawWeightEnable : TextureButton @export var DrawColorEnable : TextureButton @export var DrawColorPicker : ColorPicker @export var DrawTools : Control @export var DrawSharpness : HSlider @export var DrawStrength : HSlider @export var compute_shader : RDShaderFile @export var DrawingColor : Color @export var InvertedDrawingColor : Color @export_range(100,50000,50) var DefaultBrushSize : float = 1000.0 @export_range(100,50000,50) var DefaultCloudsHeight : float = 2000.0 var driver : SunshineCloudsDriverGD var currentRoot : Node var currentDrawingMask : RID = RID() enum DRAWINGMODE {none, weight, color, setValue} var drawScale : float var currentCloudsHeight : float var currentDrawMode : DRAWINGMODE = DRAWINGMODE.none var drawingCurrently : bool = false var drawInverted : bool = false var drawBrushToolMaterial : BaseMaterial3D = preload("res://addons/SunshineClouds2/Dock/Materials/DrawBrushToolsMaterial.tres") var drawBrushToolPrefab : PackedScene = preload("res://addons/SunshineClouds2/Dock/CloudsDrawBrush.tscn") var drawBrushTool : MeshInstance3D #region Compute Variables var computeEnabled : bool = false var rd : RenderingDevice var shader : RID = RID() var pipeline : RID = RID() var uniform_set : RID var push_constants : PackedByteArray var last_image_data : PackedByteArray = [] #endregion var pause_updates : bool = false func _enter_tree() -> void: drawScale = DefaultBrushSize func _notification(what): if what == NOTIFICATION_PREDELETE and is_instance_valid(self): RenderingServer.call_on_render_thread(ClearCompute) func _process(delta: float) -> void: if (currentDrawMode != DRAWINGMODE.none): var selection = EditorInterface.get_selection() if (selection.get_selected_nodes().size() == 0): if (driver != null): selection.add_node(driver) if (currentDrawMode == DRAWINGMODE.color): drawBrushToolMaterial.albedo_color = DrawColorPicker.color if (drawingCurrently): RenderingServer.call_on_render_thread(ExecuteCompute.bindv([delta, false, Color.WHITE])) func InitialSceneLoad() -> void: var sceneRoot = await FindSceneNode() SceneChanged(sceneRoot) print("initial scene load") await get_tree().create_timer(0.5).timeout var version_info = Engine.get_version_info() var file = FileAccess.open("res://addons/SunshineClouds2/CloudsInc.txt", FileAccess.READ_WRITE) var content = file.get_as_text() var major_index = content.find("GODOT_VERSION_MAJOR") + 20 var minor_index = content.find("GODOT_VERSION_MINOR") + 20 if content[major_index] != str(version_info.major) || content[minor_index] != str(version_info.minor): print("Version conflict, updating and reimporting...") content[major_index] = str(version_info.major) content[minor_index] = str(version_info.minor) file.store_string(content) file.close() EditorInterface.get_resource_filesystem().reimport_files(["res://addons/SunshineClouds2/SunshineCloudsCompute.glsl", "res://addons/SunshineClouds2/SunshineCloudsPostCompute.glsl", "res://addons/SunshineClouds2/SunshineCloudsPreCompute.glsl"]) await get_tree().create_timer(0.1).timeout if driver != null && driver.clouds_resource != null: driver.clouds_resource.refresh_compute() print("Version change may cause some errors during first load, these should not impact functionality, if there is impacted functionality please report it to the creator of the plugin.") print("Version updated, launching normally.") else: print("Version correct, launching normally.") file.close() func RefreshSceneNode() -> void: var sceneRoot = await FindSceneNode() SceneChanged(sceneRoot) func FindSceneNode() -> Node: var editorInterface = EditorPlugin.new().get_editor_interface() var sceneRoot = editorInterface.get_edited_scene_root() var iterationcount: int = 300 #30 seconds of checking. while sceneRoot == null && iterationcount > 0: await get_tree().create_timer(0.1).timeout iterationcount -= 1 sceneRoot = editorInterface.get_edited_scene_root() return sceneRoot func SceneChanged(scene_root : Node): pause_updates = true DrawWeightEnable.button_pressed = false DrawColorEnable.button_pressed = false last_image_data = [] DisableDrawMode() currentRoot = scene_root driver = RetrieveCloudsDriver(scene_root) if (driver != null && driver.clouds_resource != null): driver.clouds_resource.maskDrawnRid = RID() MaskWidth.value = driver.clouds_resource.mask_width_km UseMaskToggle.button_pressed = driver.clouds_resource.extra_large_used_as_mask if ResourceLoader.exists(MaskFilePath.text): var image = ResourceLoader.load(MaskFilePath.text) as Image if image: print("retrieved mask scale") MaskResolution.value = image.get_width() pause_updates = false UpdateStatusDisplay() func RetrieveCloudsDriver(scene_root : Node) -> SunshineCloudsDriverGD: if (scene_root != null): for child in scene_root.get_children(): if child is SunshineCloudsDriverGD: return child var newDriver = RetrieveCloudsDriver(child) if (newDriver): return newDriver return null func UpdateStatusDisplay(): if (driver != null): CloudsActiveToggle.disabled = false CloudsActiveToggle.button_pressed = driver.update_continuously CloudsDriverRefresh.visible = false CloudsStatusLabel.text = "Clouds present" if ResourceLoader.exists(MaskFilePath.text): MaskStatusLabel.text = "Mask Detected: " + MaskFilePath.text DrawTools.visible = true else: MaskStatusLabel.text = "Mask Not Found." DrawTools.visible = false else: CloudsActiveToggle.disabled = true CloudsActiveToggle.button_pressed = false CloudsDriverRefresh.visible = true DrawTools.visible = false CloudsDriverAccordianButton.Open() CloudsStatusLabel.text = "Clouds not present" if driver != null && driver.clouds_resource != null: UseMaskToggle.disabled = false else: UseMaskToggle.disabled = true UseMaskToggle.button_pressed = false func UpdateMaskSettings(): if (pause_updates): return print("Update mask settings") if (driver != null && driver.clouds_resource != null): driver.clouds_resource.mask_width_km = MaskWidth.value driver.clouds_resource.extra_large_used_as_mask = UseMaskToggle.button_pressed if (!UseMaskToggle.button_pressed): driver.clouds_resource.extra_large_noise_patterns = ResourceLoader.load("res://addons/SunshineClouds2/NoiseTextures/ExtraLargeScaleNoise.tres") elif ResourceLoader.exists(MaskFilePath.text): driver.clouds_resource.extra_large_noise_patterns = ResourceLoader.load(MaskFilePath.text) InitializeMaskTexture() func InitializeMaskTexture(): #if (driver == null): #return if not rd: rd = RenderingServer.get_rendering_device() if not rd: return #currentDrawingMask = driver.clouds_resource.mask_rid #var useDriverData : bool = driver != null && driver.clouds_resource != null # print("initializing mask") if ResourceLoader.exists(MaskFilePath.text): print("loading mask") var image = ResourceLoader.load(MaskFilePath.text) as CompressedTexture2D if (!image || image.get_width() != MaskResolution.value): print(MaskFilePath.text) print("mask incorrect size found size:", image.get_width(), " desired:", MaskResolution.value) image = Image.create(MaskResolution.value, MaskResolution.value, false, Image.FORMAT_RGBAF) image.clear_mipmaps() image.save_exr(MaskFilePath.text) var editorFileSystem := EditorInterface.get_resource_filesystem() editorFileSystem.scan() else: var image = Image.create(MaskResolution.value, MaskResolution.value, false, Image.FORMAT_RGBAF) image.clear_mipmaps() image.save_exr(MaskFilePath.text) var editorFileSystem := EditorInterface.get_resource_filesystem() editorFileSystem.scan() #driver.clouds_resource.mask_rid = currentDrawingMask #driver.clouds_resource.extra_large_noise_patterns = ResourceLoader.load(MaskFilePath.text) #driver.clouds_resource.last_size = Vector2i.ZERO RenderingServer.call_on_render_thread(InitializeCompute) call_deferred("UpdateStatusDisplay") #region Draw mode #region Compute func InitializeCompute(): computeEnabled = false #if driver == null: #return #currentDrawingMask = driver.clouds_resource.mask_rid #if !currentDrawingMask.is_valid(): #return if not rd: rd = RenderingServer.get_rendering_device() if not rd: computeEnabled = false printerr("No rendering device on load.") return ClearCompute() if not compute_shader: compute_shader = ResourceLoader.load("res://addons/SunshineClouds2/Dock/MaskDrawingCompute.glsl") if not compute_shader: computeEnabled = false printerr("No Shader found for drawing tool.") ClearCompute() return var shader_spirv = compute_shader.get_spirv() shader = rd.shader_create_from_spirv(shader_spirv) if shader.is_valid(): pipeline = rd.compute_pipeline_create(shader) else: computeEnabled = false printerr("Shader failed to compile.") ClearCompute() return var uniforms_array : Array[RDUniform] = [] var newFormat : RDTextureFormat = RDTextureFormat.new() newFormat.format = RenderingDevice.DATA_FORMAT_R32G32B32A32_SFLOAT newFormat.height = MaskResolution.value newFormat.width = MaskResolution.value newFormat.usage_bits = RenderingDevice.TEXTURE_USAGE_STORAGE_BIT | RenderingDevice.TEXTURE_USAGE_SAMPLING_BIT | RenderingDevice.TEXTURE_USAGE_CAN_COPY_FROM_BIT var image : Image if ResourceLoader.exists(MaskFilePath.text): image = (ResourceLoader.load(MaskFilePath.text) as CompressedTexture2D).get_image() if image == null: image = Image.create(MaskResolution.value, MaskResolution.value, false, Image.FORMAT_RGBAF) currentDrawingMask = rd.texture_create(newFormat, RDTextureView.new(), [image.get_data()]) if (driver != null && driver.clouds_resource != null): driver.clouds_resource.update_mask(currentDrawingMask) var mask_uniform = RDUniform.new() mask_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE mask_uniform.binding = 0 mask_uniform.add_id(currentDrawingMask) uniforms_array.append(mask_uniform) uniform_set = rd.uniform_set_create(uniforms_array, shader, 0) computeEnabled = true func ClearCompute(): if rd: if shader.is_valid(): rd.free_rid(shader) shader = RID() if currentDrawingMask.is_valid(): rd.free_rid(currentDrawingMask) currentDrawingMask = RID() func ExecuteCompute(delta : float, setvalue : bool, setvalueColor : Color): if (!computeEnabled): return var resolution : float = MaskResolution.value var drawPosition : Vector2 = Vector2.ZERO var drawRadius = 0.0 if (!setvalue): drawPosition = Vector2(drawBrushTool.global_position.x, drawBrushTool.global_position.z) drawPosition = (drawPosition / (MaskWidth.value * 1000.0)) * resolution drawPosition += Vector2(resolution * 0.5, resolution * 0.5) drawRadius = (drawBrushTool.scale.x / (MaskWidth.value * 1000.0)) * resolution var groups = ceil(resolution / 32) + 1 var drawSharpness = DrawSharpness.value var drawStrength = DrawStrength.value * delta if (drawInverted): drawStrength = -drawStrength var editingtype : float = 0.0 if setvalue: editingtype = 2.0 elif currentDrawMode == DRAWINGMODE.color: editingtype = 1.0 var ms = StreamPeerBuffer.new() ms.put_float(drawPosition.x) ms.put_float(drawPosition.y) ms.put_float(drawRadius) ms.put_float(drawSharpness) ms.put_float(drawStrength) ms.put_float(editingtype) ms.put_float(resolution) ms.put_float(0.0) if (setvalue): ms.put_float(setvalueColor.r) ms.put_float(setvalueColor.g) ms.put_float(setvalueColor.b) ms.put_float(setvalueColor.a) else: ms.put_float(DrawColorPicker.color.r) ms.put_float(DrawColorPicker.color.g) ms.put_float(DrawColorPicker.color.b) ms.put_float(0.0) push_constants = ms.get_data_array() var compute_list = rd.compute_list_begin() rd.compute_list_bind_compute_pipeline(compute_list, pipeline) rd.compute_list_bind_uniform_set(compute_list, uniform_set, 0) rd.compute_list_set_push_constant(compute_list, push_constants, push_constants.size()) rd.compute_list_dispatch(compute_list, groups, groups, 1) rd.compute_list_end() await RenderingServer.frame_post_draw rd.texture_get_data_async(currentDrawingMask, 0, CompleteRetreval) func CompleteRetreval(data): last_image_data = data #for byte in data: #print(byte) #print("RetrevalComplete ", data) #var image = Image.create_from_data(MaskResolution.value, MaskResolution.value, false, Image.FORMAT_RGBAF, data) ##rd.texture_update(RenderingServer.texture_get_rd_texture(currentMask.get_rid()),0, data) #image.save_png(MaskFilePath.text) #var editorFileSystem := EditorInterface.get_resource_filesystem() #editorFileSystem.scan() #endregion func IterateCursorLocation(viewport_camera: Camera3D, event:InputEventMouse): if (is_instance_valid(driver) && driver.clouds_resource != null): currentCloudsHeight = (driver.clouds_resource.cloud_floor + driver.clouds_resource.cloud_ceiling) / 2.0 else: currentCloudsHeight = DefaultCloudsHeight var ray_origin = viewport_camera.project_ray_origin(event.position) var ray_dir = viewport_camera.project_ray_normal(event.position) var result : float = RetrieveTravelDistance(ray_origin, ray_dir) if (result == -1.0): drawBrushTool.visible = false else: drawBrushTool.visible = true drawBrushTool.global_position = ray_origin + ray_dir * result drawBrushTool.global_position.y = driver.clouds_resource.cloud_floor func BeginCursorDraw(): drawingCurrently = true func EndCursorDraw(): drawingCurrently = false func ScaleDrawingCircleUp(): drawScale = min(drawScale + (drawScale * 0.1), 100000.0) SetDrawScale() func ScaleDrawingCircleDown(): drawScale = max(drawScale - (drawScale * 0.1), 100.0) SetDrawScale() func DrawModeCancel(): DrawWeightEnable.button_pressed = false DrawColorEnable.button_pressed = false DisableDrawMode() func SetDrawScale(): if driver != null && driver.clouds_resource != null: drawBrushTool.scale = Vector3(drawScale, driver.clouds_resource.cloud_ceiling - driver.clouds_resource.cloud_floor, drawScale) else: drawBrushTool.scale = Vector3(drawScale, 1000.0, drawScale) #region Draw Mode Toggles func FloodFill(): var resultColor : Color = DrawColorPicker.color resultColor.a = DrawStrength.value / DrawStrength.max_value RenderingServer.call_on_render_thread(ExecuteCompute.bindv([0.0, true, resultColor])) await get_tree().create_timer(0.2).timeout call_deferred("DisableDrawMode") func DrawWeightToggled(): DrawColorEnable.button_pressed = false if DrawWeightEnable.button_pressed && EnableDrawMode(): currentDrawMode = DRAWINGMODE.weight else: DrawWeightEnable.button_pressed = false func DrawColorToggled(): DrawWeightEnable.button_pressed = false if DrawColorEnable.button_pressed && EnableDrawMode(): currentDrawMode = DRAWINGMODE.color else: DrawColorEnable.button_pressed = false func EnableDrawMode() -> bool: if (!computeEnabled): InitializeMaskTexture() if (!is_instance_valid(currentRoot)): return false drawBrushToolMaterial.albedo_color = DrawingColor if (!is_instance_valid(drawBrushTool)): drawBrushTool = drawBrushToolPrefab.instantiate() as MeshInstance3D currentRoot.add_child(drawBrushTool) SetDrawScale() return true func DisableDrawMode(): DrawColorEnable.button_pressed = false DrawWeightEnable.button_pressed = false currentDrawMode = DRAWINGMODE.none drawInverted = false if (drawingCurrently): Input.mouse_mode = Input.MOUSE_MODE_VISIBLE drawingCurrently = false if (is_instance_valid(drawBrushTool)): drawBrushTool.queue_free() drawBrushTool = null if (last_image_data.size() > 0): print("Saved image to disc") var image = Image.create_from_data(MaskResolution.value, MaskResolution.value, false, Image.FORMAT_RGBAF, last_image_data) image.save_exr(MaskFilePath.text) var editorFileSystem := EditorInterface.get_resource_filesystem() editorFileSystem.scan() last_image_data = [] if (driver != null && driver.clouds_resource != null): driver.clouds_resource.extra_large_noise_patterns = ResourceLoader.load(MaskFilePath.text) #endregion func SetDrawInvert(mode : bool): if (currentDrawMode == DRAWINGMODE.weight && drawInverted != mode): drawInverted = mode drawBrushToolMaterial.albedo_color = InvertedDrawingColor if drawInverted else DrawingColor #region draw tools helpers func RetrieveTravelDistance(pos : Vector3, dir :Vector3) -> float: var t : float = (currentCloudsHeight - pos.y) / dir.y if (dir.y == 0 || t < 0.0): return -1.0 return t * dir.length() #endregion #endregion #Updates func SetCloudsUpdating(): if (driver != null): driver.update_continuously = CloudsActiveToggle.button_pressed UpdateStatusDisplay() # # # # #@tool #extends MeshInstance3D #class_name WanderingTerrainDrawnStamp # # #@export var visibleColorMat : ShaderMaterial = preload("res://addons/WanderingTerrain/Materials/StampMaterials/EraseChunkVisibleColorMat.tres") #@export var highlightedColorMat : ShaderMaterial = preload("res://addons/WanderingTerrain/Materials/StampMaterials/EraseChunkHighlightedColorMat.tres") #@export var thisStampIndex : Vector2 #@export var currentHeightmapImageTexture: Texture2D #@export var currentColormapImageTexture: Texture2D #@export var currentSplatmapImageTexture: Texture2D #@export var currentMaterial : ShaderMaterial # #var newHeightmapImage : Image #var newColormapImage : Image #var newSplatmapImage : Image #var newHeightmapdrawingDirty : bool = false #var newColormapdrawingDirty : bool = false #var newSplatmapdrawingDirty : bool = false #var pixelChanged : bool = false # #enum DrawingUpdateMode {sculpting, colorpainting, splatpainting} # #var thisRect : Rect2 # # #func InitializeDrawnStamp(resolution : int, indexPosition : Vector2, position : Vector3, currentUpdateType : DrawingUpdateMode): #add_to_group("WanderingTerrainSculptingStamps", true); #thisStampIndex = indexPosition #global_position = position #currentMaterial = material_override.duplicate() #material_override = currentMaterial # #UpdateDrawnStamp(resolution, currentUpdateType) # #func SetVisible(): #currentMaterial.next_pass = visibleColorMat # #func SetHidden(): #currentMaterial.next_pass = null # #func Highlight(): #currentMaterial.next_pass = highlightedColorMat # #func Unhightlight(): #currentMaterial.next_pass = visibleColorMat # #func CheckHasAnyUpdate() -> bool: # #if (pixelChanged || currentHeightmapImageTexture != null || currentColormapImageTexture != null || currentSplatmapImageTexture != null): #return true # #return false # #func UpdateDrawnStamp(resolution : int, currentUpdateType : DrawingUpdateMode): # #match currentUpdateType: #DrawingUpdateMode.sculpting: # #if (newHeightmapImage == null || newHeightmapImage.get_width() != resolution): #if (currentHeightmapImageTexture != null && currentHeightmapImageTexture.get_width() == resolution): #newHeightmapImage = currentHeightmapImageTexture.get_image() #else: #currentHeightmapImageTexture = null #newHeightmapdrawingDirty = true #newHeightmapImage = Image.create(resolution, resolution, false, Image.FORMAT_RGF) #for x in resolution: #for y in resolution: #newHeightmapImage.set_pixel(x,y, Color(0.0,0.0,0.0,0.0)) # # #var imageTexture = ImageTexture.create_from_image(newHeightmapImage) #currentMaterial.set_shader_parameter("HeightMap", imageTexture) # #DrawingUpdateMode.colorpainting: # #if (newColormapImage == null || newColormapImage.get_width() != resolution): #if (currentColormapImageTexture != null && currentColormapImageTexture.get_width() == resolution): #newColormapImage = currentColormapImageTexture.get_image() #else: #currentColormapImageTexture = null #newColormapdrawingDirty = true #newColormapImage = Image.create(resolution, resolution, false, Image.FORMAT_RGBAF) #for x in resolution: #for y in resolution: #newColormapImage.set_pixel(x,y, Color(0.0,0.0,0.0,0.0)) # #var imageTexture = ImageTexture.create_from_image(newColormapImage) #currentMaterial.set_shader_parameter("ColorMap", imageTexture) #currentMaterial.set_shader_parameter("HasColorMap", true); # #DrawingUpdateMode.splatpainting: # #if (newSplatmapImage == null || newSplatmapImage.get_width() != resolution): #if (currentSplatmapImageTexture != null && currentSplatmapImageTexture.get_width() == resolution): #newSplatmapImage = currentSplatmapImageTexture.get_image() #else: #currentSplatmapImageTexture = null #newSplatmapdrawingDirty = true #newSplatmapImage = Image.create(resolution, resolution, false, Image.FORMAT_RGBAF) #for x in resolution: #for y in resolution: #newSplatmapImage.set_pixel(x,y, Color(0.0,0.0,0.0,0.0)) # #var imageTexture = ImageTexture.create_from_image(newSplatmapImage) #currentMaterial.set_shader_parameter("SplatMap", imageTexture) #currentMaterial.set_shader_parameter("HasSplatMap", true); # # #thisRect = Rect2(Vector2(global_position.x - resolution / 2, global_position.z - resolution / 2),Vector2(resolution, resolution)) # #func IsInsideRect(targetPosition : Vector2, stampRadius : float) -> bool: #if thisRect.has_point(targetPosition) || thisRect.has_point(targetPosition + (Vector2(global_position.x, global_position.z) - targetPosition).normalized() * stampRadius): #return true #return false # # # #func PackStamp(terrainController : WanderingTerrainController): #if (newHeightmapdrawingDirty && newHeightmapImage != null): #newHeightmapdrawingDirty = false #var resultingResource = await terrainController.Editor_SaveImageToOutputFolder(newHeightmapImage, name + "_height_savedstamp", "exr") #if (resultingResource != null): #currentHeightmapImageTexture = resultingResource #currentMaterial.set_shader_parameter("HeightMap", currentHeightmapImageTexture) # #if (newColormapdrawingDirty && newColormapImage != null): #newColormapdrawingDirty = false #var resultingResource = await terrainController.Editor_SaveImageToOutputFolder(newColormapImage, name + "_color_savedstamp", "exr") #if (resultingResource != null): #currentColormapImageTexture = resultingResource #currentMaterial.set_shader_parameter("ColorMap", currentColormapImageTexture) # #if (newSplatmapdrawingDirty && newSplatmapImage != null): #newSplatmapdrawingDirty = false #var resultingResource = await terrainController.Editor_SaveImageToOutputFolder(newSplatmapImage, name + "_splatmap_savedstamp", "exr") #if (resultingResource != null): #currentSplatmapImageTexture = resultingResource #currentMaterial.set_shader_parameter("SplatMap", currentSplatmapImageTexture) # #func ColorPainting_DrawOnImage(targetPosition : Vector3, stampRadius : float, stampImage : Image, power : float, color : Color, layer : DrawingUpdateMode): #var localPosition : Vector3 = targetPosition - global_position #var localPositionPixelSpace := Vector2(localPosition.x + 256, localPosition.z + 256) #var stampScale : float = stampImage.get_width() / stampRadius #var stampActualResolution : float = (stampImage.get_width() / stampScale) + 1 # #var stampPos : Vector2 = Vector2(localPositionPixelSpace.x, localPositionPixelSpace.y) #var stampTopCornerPos : Vector2 = Vector2(localPositionPixelSpace.x - stampActualResolution / 2, localPositionPixelSpace.y - stampActualResolution / 2 ) #var currentPos : Vector2 #var thisColor: Color #var stampAlpha: float #var hasNoAlpha = stampImage.detect_alpha() == Image.ALPHA_NONE # #var currentImage : Image #if (layer == DrawingUpdateMode.colorpainting): #newColormapdrawingDirty = true #currentImage = newColormapImage #else: #newSplatmapdrawingDirty = true #currentImage = newSplatmapImage # #for x in stampActualResolution: #if (stampTopCornerPos.x + x >= currentImage.get_width() || x * stampScale >= stampImage.get_width()): #break #for y in stampActualResolution: #if (stampTopCornerPos.y + y >= currentImage.get_height() || y * stampScale >= stampImage.get_width()): #break #currentPos.x = stampTopCornerPos.x + x #currentPos.y = stampTopCornerPos.y + y #if (currentPos.x < 0 || currentPos.y < 0): #continue # #thisColor = currentImage.get_pixelv(currentPos) #if (hasNoAlpha): #stampAlpha = stampImage.get_pixel(x * stampScale,y * stampScale).r #else: #stampAlpha = stampImage.get_pixel(x * stampScale,y * stampScale).a # #if (thisColor.a == 0): #thisColor.r = color.r #thisColor.g = color.g #thisColor.b = color.b # #thisColor.r = lerpf(thisColor.r, color.r, stampAlpha * power * 0.2) #thisColor.g = lerpf(thisColor.g, color.g, stampAlpha * power * 0.2) #thisColor.b = lerpf(thisColor.b, color.b, stampAlpha * power * 0.2) # ### Handles opacity, which always goes up. #thisColor.a = clampf(thisColor.a + (stampAlpha * abs(power) * 0.2), 0.0, 1.0) #currentImage.set_pixel(currentPos.x, currentPos.y, thisColor) #pixelChanged = true # #var imageTexture = ImageTexture.create_from_image(currentImage) # #if (layer == DrawingUpdateMode.colorpainting): #currentMaterial.set_shader_parameter("ColorMap", imageTexture) #newColormapImage = currentImage #else: #currentMaterial.set_shader_parameter("SplatMap", imageTexture) #newSplatmapImage = currentImage # #func ColorPainting_EraseOnImage(targetPosition : Vector3, stampRadius : float, stampImage : Image, power : float, layer : DrawingUpdateMode): #var localPosition : Vector3 = targetPosition - global_position #var localPositionPixelSpace := Vector2(localPosition.x + 256, localPosition.z + 256) #var stampScale : float = stampImage.get_width() / stampRadius #var stampActualResolution : float = (stampImage.get_width() / stampScale) + 1 # #var stampPos : Vector2 = Vector2(localPositionPixelSpace.x, localPositionPixelSpace.y) #var stampTopCornerPos : Vector2 = Vector2(localPositionPixelSpace.x - stampActualResolution / 2, localPositionPixelSpace.y - stampActualResolution / 2 ) #var currentPos : Vector2 #var thisColor: Color #var stampAlpha: float #var hasNoAlpha = stampImage.detect_alpha() == Image.ALPHA_NONE # #var currentImage : Image #if (layer == DrawingUpdateMode.colorpainting): #newColormapdrawingDirty = true #currentImage = newColormapImage #else: #newSplatmapdrawingDirty = true #currentImage = newSplatmapImage # #for x in stampActualResolution: #if (stampTopCornerPos.x + x >= currentImage.get_width() || x * stampScale >= stampImage.get_width()): #break #for y in stampActualResolution: #if (stampTopCornerPos.y + y >= currentImage.get_height() || y * stampScale >= stampImage.get_width()): #break #currentPos.x = stampTopCornerPos.x + x #currentPos.y = stampTopCornerPos.y + y #if (currentPos.x < 0 || currentPos.y < 0): #continue # #thisColor = currentImage.get_pixelv(currentPos) #if (hasNoAlpha): #stampAlpha = stampImage.get_pixel(x * stampScale,y * stampScale).r #else: #stampAlpha = stampImage.get_pixel(x * stampScale,y * stampScale).a # #thisColor.a = clampf(thisColor.a - stampAlpha * power * 0.2, 0.0, 1.0) # #currentImage.set_pixel(currentPos.x, currentPos.y, thisColor) # #var imageTexture = ImageTexture.create_from_image(currentImage) # #if (layer == DrawingUpdateMode.colorpainting): #currentMaterial.set_shader_parameter("ColorMap", imageTexture) #newColormapImage = currentImage #else: #currentMaterial.set_shader_parameter("SplatMap", imageTexture) #newSplatmapImage = currentImage # #func Sculpt_EraseOnImage(targetPosition : Vector3, stampRadius : float, stampImage : Image, power : float): #newHeightmapdrawingDirty = true # #var localPosition : Vector3 = targetPosition - global_position # #var localPositionPixelSpace := Vector2(localPosition.x + 256, localPosition.z + 256) #var stampScale : float = stampImage.get_width() / stampRadius #var stampActualResolution : float = (stampImage.get_width() / stampScale) + 1 #var hasNoAlpha = stampImage.detect_alpha() == Image.ALPHA_NONE # # #var stampPos : Vector2 = Vector2(localPositionPixelSpace.x, localPositionPixelSpace.y) #var stampTopCornerPos : Vector2 = Vector2(localPositionPixelSpace.x - stampActualResolution / 2, localPositionPixelSpace.y - stampActualResolution / 2 ) #var currentPos : Vector2 #var thisColor: Color #var stampAlpha: float # #for x in stampActualResolution: #if (stampTopCornerPos.x + x >= newHeightmapImage.get_width() || x * stampScale >= stampImage.get_width()): #break #for y in stampActualResolution: #if (stampTopCornerPos.y + y >= newHeightmapImage.get_height() || y * stampScale >= stampImage.get_width()): #break #currentPos.x = stampTopCornerPos.x + x #currentPos.y = stampTopCornerPos.y + y #if (currentPos.x < 0 || currentPos.y < 0): #continue # #thisColor = newHeightmapImage.get_pixelv(currentPos) #if (hasNoAlpha): #stampAlpha = stampImage.get_pixel(x * stampScale,y * stampScale).r #else: #stampAlpha = stampImage.get_pixel(x * stampScale,y * stampScale).a ##thisColor.r += (0.5 - thisColor.r) * stampAlpha * power * 0.2 #thisColor.g = clampf(thisColor.g - stampAlpha * power * 0.2, 0.0, 1.0) #newHeightmapImage.set_pixel(currentPos.x, currentPos.y, thisColor) # #var imageTexture = ImageTexture.create_from_image(newHeightmapImage) # #currentMaterial.set_shader_parameter("HeightMap", imageTexture) # #func Sculpt_SmoothOnImage(targetPosition : Vector3, stampRadius : float, stampImage : Image, power : float, worldScale : float): #newHeightmapdrawingDirty = true # #var localPosition : Vector3 = targetPosition - global_position # #var localPositionPixelSpace := Vector2(localPosition.x + 256, localPosition.z + 256) #var stampScale : float = stampImage.get_width() / stampRadius #var stampActualResolution : float = (stampImage.get_width() / stampScale) + 1 # #var stampPos : Vector2 = Vector2(localPositionPixelSpace.x, localPositionPixelSpace.y) #var stampTopCornerPos : Vector2 = Vector2(localPositionPixelSpace.x - stampActualResolution / 2, localPositionPixelSpace.y - stampActualResolution / 2 ) #var currentPos : Vector2 #var thisColor: Color #var stampAlpha: float #var heightValue : float = clamp((targetPosition.y) / worldScale, 0.0, 1.0) #var hasNoAlpha = stampImage.detect_alpha() == Image.ALPHA_NONE # #for x in stampActualResolution: #if (stampTopCornerPos.x + x >= newHeightmapImage.get_width() || x * stampScale >= stampImage.get_width()): #break #for y in stampActualResolution: #if (stampTopCornerPos.y + y >= newHeightmapImage.get_height() || y * stampScale >= stampImage.get_width()): #break #currentPos.x = stampTopCornerPos.x + x #currentPos.y = stampTopCornerPos.y + y #if (currentPos.x < 0 || currentPos.y < 0): #continue # #thisColor = newHeightmapImage.get_pixelv(currentPos) #if (hasNoAlpha): #stampAlpha = stampImage.get_pixel(x * stampScale,y * stampScale).r #else: #stampAlpha = stampImage.get_pixel(x * stampScale,y * stampScale).a #thisColor.r = clampf(thisColor.r + ((heightValue - thisColor.r) * stampAlpha * power * 0.2), 0.0, 1.0) #thisColor.g = clampf(thisColor.g + ((0.0 - thisColor.g) * stampAlpha * power * 0.05), 0.0, 1.0) # #newHeightmapImage.set_pixel(currentPos.x, currentPos.y, thisColor) #pixelChanged = true # #var imageTexture = ImageTexture.create_from_image(newHeightmapImage) # #currentMaterial.set_shader_parameter("HeightMap", imageTexture) # # #func Sculpt_DrawOnImage(targetPosition : Vector3, stampRadius : float, stampImage : Image, power : float, worldScale : float): #newHeightmapdrawingDirty = true # #var localPosition : Vector3 = targetPosition - global_position # #var localPositionPixelSpace := Vector2(localPosition.x + 256, localPosition.z + 256) #var stampScale : float = stampImage.get_width() / stampRadius #var stampActualResolution : float = (stampImage.get_width() / stampScale) + 1 # #var stampPos : Vector2 = Vector2(localPositionPixelSpace.x, localPositionPixelSpace.y) #var stampTopCornerPos : Vector2 = Vector2(localPositionPixelSpace.x - stampActualResolution / 2, localPositionPixelSpace.y - stampActualResolution / 2 ) #var currentPos : Vector2 #var thisColor: Color #var stampAlpha: float #var heightValue = clamp(targetPosition.y / worldScale, 0.0, 1.0) #var hasNoAlpha = stampImage.detect_alpha() == Image.ALPHA_NONE # #for x in stampActualResolution: #if (stampTopCornerPos.x + x >= newHeightmapImage.get_width() || x * stampScale >= stampImage.get_width()): #break #for y in stampActualResolution: #if (stampTopCornerPos.y + y >= newHeightmapImage.get_height() || y * stampScale >= stampImage.get_width()): #break #currentPos.x = stampTopCornerPos.x + x #currentPos.y = stampTopCornerPos.y + y #if (currentPos.x < 0 || currentPos.y < 0): #continue # #thisColor = newHeightmapImage.get_pixelv(currentPos) #if (hasNoAlpha): #stampAlpha = stampImage.get_pixel(x * stampScale,y * stampScale).r #else: #stampAlpha = stampImage.get_pixel(x * stampScale,y * stampScale).a ### Handles actual value. #if (thisColor.g == 0): #thisColor.r = heightValue #thisColor.r = clampf(thisColor.r + (stampAlpha * power * 0.05), 0.0, 1.0) ### Handles opacity, which always goes up. #thisColor.g = clampf(thisColor.g + (stampAlpha * abs(power) * 0.05), 0.0, 1.0) #newHeightmapImage.set_pixel(currentPos.x, currentPos.y, thisColor) #pixelChanged = true # #var imageTexture = ImageTexture.create_from_image(newHeightmapImage) # #currentMaterial.set_shader_parameter("HeightMap", imageTexture) # #func Sculpt_SetHeightOnImage(targetPosition : Vector3, stampRadius : float, stampImage : Image, heightValue : float, power : float, worldScale : float): #newHeightmapdrawingDirty = true # #var localPosition : Vector3 = targetPosition - global_position # #var localPositionPixelSpace := Vector2(localPosition.x + 256, localPosition.z + 256) #var stampScale : float = stampImage.get_width() / stampRadius #var stampActualResolution : float = (stampImage.get_width() / stampScale) + 1 # #var stampPos : Vector2 = Vector2(localPositionPixelSpace.x, localPositionPixelSpace.y) #var stampTopCornerPos : Vector2 = Vector2(localPositionPixelSpace.x - stampActualResolution / 2, localPositionPixelSpace.y - stampActualResolution / 2 ) #var currentPos : Vector2 #var thisColor: Color #var stampAlpha: float #var currentHeight = clamp(targetPosition.y / worldScale, 0.0, 1.0) #heightValue = clamp(heightValue / worldScale, 0.0, 1.0) #var hasNoAlpha = stampImage.detect_alpha() == Image.ALPHA_NONE # #for x in stampActualResolution: #if (stampTopCornerPos.x + x >= newHeightmapImage.get_width() || x * stampScale >= stampImage.get_width()): #break #for y in stampActualResolution: #if (stampTopCornerPos.y + y >= newHeightmapImage.get_height() || y * stampScale >= stampImage.get_width()): #break #currentPos.x = stampTopCornerPos.x + x #currentPos.y = stampTopCornerPos.y + y #if (currentPos.x < 0 || currentPos.y < 0): #continue # #thisColor = newHeightmapImage.get_pixelv(currentPos) #if (hasNoAlpha): #stampAlpha = stampImage.get_pixel(x * stampScale,y * stampScale).r #else: #stampAlpha = stampImage.get_pixel(x * stampScale,y * stampScale).a # #if (thisColor.g == 0): #thisColor.r = currentHeight # #thisColor.r = clampf(thisColor.r + ((heightValue - thisColor.r) * stampAlpha * power), 0.0, 1.0) ### Handles opacity, which always goes up. #thisColor.g = clampf(thisColor.g + (stampAlpha * abs(power) * 0.2), 0.0, 1.0) #newHeightmapImage.set_pixel(currentPos.x, currentPos.y, thisColor) #pixelChanged = true # #var imageTexture = ImageTexture.create_from_image(newHeightmapImage) # #currentMaterial.set_shader_parameter("HeightMap", imageTexture)