From 6edf50c4f67c2ac2e8c81fa7e2dd5d6d72217a41 Mon Sep 17 00:00:00 2001 From: Cory Petkovsek <632766+TokisanGames@users.noreply.github.com> Date: Thu, 16 Nov 2023 01:30:08 +0700 Subject: [PATCH] Enable texture brushing w/ new control map format --- src/terrain_3d_editor.cpp | 53 ++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/src/terrain_3d_editor.cpp b/src/terrain_3d_editor.cpp index a2364a661..f21735e09 100644 --- a/src/terrain_3d_editor.cpp +++ b/src/terrain_3d_editor.cpp @@ -203,31 +203,48 @@ void Terrain3DEditor::_operate_map(Vector3 p_global_position, real_t p_camera_di storage->update_heights(destf); } else if (map_type == Terrain3DStorage::TYPE_CONTROL) { + // Get bit field from pixel + uint32_t bits; + *(real_t *)&bits = src.r; + uint32_t base_index = bits >> 27u & 0x1Fu; + uint32_t overlay_index = bits >> 22u & 0x1Fu; + real_t blend = real_t(bits >> 14u & 0xFFu) / 255.0f; + real_t alpha_clip = (brush_alpha < 0.1f) ? 0.0f : 1.0f; - int index_base = int(src.r * 255.0f); - int index_overlay = int(src.g * 255.0f); - int dest_index = 0; + uint32_t dest_index = int(Math::lerp(base_index, texture_id, alpha_clip)); switch (_operation) { - case Terrain3DEditor::ADD: + case Terrain3DEditor::REPLACE: { + // Base Paint + base_index = dest_index; + blend = Math::lerp(real_t(blend), real_t(0.0f), alpha_clip * opacity); + } break; + case Terrain3DEditor::ADD: { // Spray Overlay - dest_index = int(Math::lerp(index_overlay, texture_id, alpha_clip)); - if (dest_index == index_base) { - dest.b = Math::lerp(real_t(src.b), real_t(0.0f), alpha_clip * opacity * real_t(0.5f)); + real_t spray_opacity = CLAMP(opacity * real_t(0.025f), real_t(0.003f), real_t(0.025f)); + real_t brush_value = CLAMP(brush_alpha * spray_opacity, real_t(0.0f), real_t(1.0f)); + if (dest_index == base_index) { + blend = CLAMP(blend - brush_value, real_t(0.0f), real_t(1.0f)); } else { - dest.g = dest_index / 255.0f; - dest.b = Math::lerp(real_t(src.b), CLAMP(src.b + brush_alpha, real_t(0.0f), real_t(1.0f)), brush_alpha * opacity * real_t(0.5f)); + overlay_index = dest_index; + blend = CLAMP(blend + brush_value, real_t(0.0f), real_t(1.0f)); } - break; - case Terrain3DEditor::REPLACE: - // Base Paint - dest_index = int(Math::lerp(index_base, texture_id, alpha_clip)); - dest.r = dest_index / 255.0f; - dest.b = Math::lerp(real_t(src.b), real_t(0.0f), alpha_clip * opacity); - break; - default: - break; + } break; + default: { + } break; } + + // Convert back to bit field + uint32_t base = (base_index & 0x1F) << 27; // 5 bits 32-28 + uint32_t over = (overlay_index & 0x1F) << 22; // 5 bits 27-23 + uint32_t blend_int = uint32_t(CLAMP(Math::round(blend * 255.0f), 0.0f, 255.0f)); + blend_int = (blend_int & 0xFF) << 14; // 8 bits 22-15 + bits = base | over | blend_int; + + // Write back to pixel in FORMAT_RF + real_t out_float = *(real_t *)&bits; + dest = Color(out_float, 0.f, 0.f, 1.0f); + } else if (map_type == Terrain3DStorage::TYPE_COLOR) { switch (_tool) { case COLOR: