Skip to content

Commit

Permalink
Absolute and Additive modes for setting blend index (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
TokisanGames committed Nov 11, 2023
1 parent 63fa6f5 commit 65b63b9
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 38 deletions.
2 changes: 2 additions & 0 deletions project/addons/terrain_3d/editor/components/tool_settings.gd
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ func _ready() -> void:

add_setting(SettingType.SLIDER, "size", 50, list, "m", 2, 200)
add_setting(SettingType.SLIDER, "opacity", 10, list, "%", 1, 100)
add_setting(SettingType.SLIDER, "blend", 1, list, "", 0, 7)
add_setting(SettingType.CHECKBOX, "additive", true, list)
add_setting(SettingType.SLIDER, "height", 50, list, "m", -500, 500, 0.1, ALLOW_OUT_OF_BOUNDS)
add_setting(SettingType.PICKER, "height picker", Terrain3DEditor.HEIGHT, list)
add_setting(SettingType.DOUBLE_SLIDER, "slope", 0, list, "°", 0, 180, 1)
Expand Down
9 changes: 9 additions & 0 deletions project/addons/terrain_3d/editor/components/ui.gd
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ func _on_tool_changed(p_tool: Terrain3DEditor.Tool, p_operation: Terrain3DEditor
to_hide.push_back("roughness")
to_hide.push_back("roughness picker")
to_hide.push_back("slope")
to_hide.push_back("blend")
to_hide.push_back("additive")
if p_operation != Terrain3DEditor.REPLACE:
to_hide.push_back("height")
to_hide.push_back("height picker")
Expand All @@ -105,6 +107,7 @@ func _on_tool_changed(p_tool: Terrain3DEditor.Tool, p_operation: Terrain3DEditor
to_hide.push_back("color picker")
to_hide.push_back("roughness")
to_hide.push_back("roughness picker")
to_hide.push_back("opacity")
to_hide.push_back("slope")

elif p_tool == Terrain3DEditor.COLOR:
Expand All @@ -113,13 +116,17 @@ func _on_tool_changed(p_tool: Terrain3DEditor.Tool, p_operation: Terrain3DEditor
to_hide.push_back("roughness")
to_hide.push_back("roughness picker")
to_hide.push_back("slope")
to_hide.push_back("blend")
to_hide.push_back("additive")

elif p_tool == Terrain3DEditor.ROUGHNESS:
to_hide.push_back("height")
to_hide.push_back("height picker")
to_hide.push_back("color")
to_hide.push_back("color picker")
to_hide.push_back("slope")
to_hide.push_back("blend")
to_hide.push_back("additive")

toolbar_settings.hide_settings(to_hide)

Expand All @@ -134,6 +141,8 @@ func _on_setting_changed() -> void:
brush_data = {
"size": int(toolbar_settings.get_setting("size")),
"opacity": toolbar_settings.get_setting("opacity") / 100.0,
"blend": toolbar_settings.get_setting("blend"),
"blend_add": toolbar_settings.get_setting("additive"),
"height": toolbar_settings.get_setting("height"),
"color": toolbar_settings.get_setting("color"),
"roughness": toolbar_settings.get_setting("roughness"),
Expand Down
1 change: 1 addition & 0 deletions project/demo/src/DemoScene.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ extends Node

func _ready():
$UI.player = $Player

138 changes: 102 additions & 36 deletions src/terrain_3d_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ void Terrain3DEditor::Brush::set_data(Dictionary p_data) {

_size = p_data["size"];
_opacity = p_data["opacity"];
_blend_strength = p_data["blend"];
_blend_add = p_data["blend_add"];
_height = p_data["height"];
_color = p_data["color"];
_roughness = p_data["roughness"];
Expand Down Expand Up @@ -109,6 +111,8 @@ void Terrain3DEditor::_operate_map(Vector3 p_global_position, real_t p_camera_di
int texture_id = _brush.get_texture_index();
Vector2 img_size = _brush.get_image_size();
real_t opacity = _brush.get_opacity();
int blend_strength = _brush.get_blend_strength();
bool blend_add = _brush.is_blend_additive();
real_t height = _brush.get_height();
Color color = _brush.get_color();
real_t roughness = _brush.get_roughness();
Expand All @@ -121,12 +125,6 @@ void Terrain3DEditor::_operate_map(Vector3 p_global_position, real_t p_camera_di
}
Object::cast_to<Node>(_terrain->get_plugin()->get("ui"))->call("set_decal_rotation", rot);

_range_buffer = MIN(_range_buffer + opacity * .01f, real_t(.115f));

if (counter++ % 30 == 0) {
LOG(WARN, "index: ", index, ", opacity: ", vformat("%.2f", opacity), ", range_buffer: ", vformat("%.2f", _range_buffer));
}

for (int x = 0; x < brush_size; x++) {
for (int y = 0; y < brush_size; y++) {
Vector2i brush_offset = Vector2i(x, y) - (Vector2i(brush_size, brush_size) / 2);
Expand Down Expand Up @@ -164,10 +162,13 @@ void Terrain3DEditor::_operate_map(Vector3 p_global_position, real_t p_camera_di

// Start brushing on the map
real_t brush_alpha = real_t(Math::pow(double(_brush.get_alpha(brush_pixel_position)), double(gamma)));
Color src = map->get_pixelv(map_pixel_position);
Color dest = src;
Color orig;
Color src;
Color dest;

if (map_type == Terrain3DStorage::TYPE_HEIGHT) {
src = map->get_pixelv(map_pixel_position);
dest = src;
real_t srcf = src.r;
real_t destf = dest.r;

Expand Down Expand Up @@ -212,6 +213,10 @@ void Terrain3DEditor::_operate_map(Vector3 p_global_position, real_t p_camera_di
map->set_pixelv(map_pixel_position, dest);

} else if (map_type == Terrain3DStorage::TYPE_CONTROL) {
TypedArray<Image> orig_maps = _undo_set[map_type];
orig = static_cast<Ref<Image>>(orig_maps[region_index])->get_pixelv(map_pixel_position);
src = map->get_pixelv(map_pixel_position);
dest = src;
real_t alpha_clip = (brush_alpha < 0.1f) ? 0.0f : 1.0f;

// Get bit field from pixel
Expand All @@ -223,67 +228,111 @@ void Terrain3DEditor::_operate_map(Vector3 p_global_position, real_t p_camera_di
real_t blend = Terrain3DStorage::RANGE[blend_index];
uint32_t dest_index = 0;

uint32_t obits;
*(real_t *)&obits = orig.r;
uint32_t obase_index = obits >> 27u & 0x1Fu;
uint32_t ooverlay_index = obits >> 22u & 0x1Fu;
uint32_t oblend_index = obits >> 19u & 0x7u;
real_t oblend = Terrain3DStorage::RANGE[oblend_index];

switch (_operation) {
case Terrain3DEditor::REPLACE:
// Base Paint
//dest_index = uint32_t(Math::lerp(base_index, index, alpha_clip));
//dest_index = uint32_t(Math::lerp(base_index, texture_id, alpha_clip));
//base_index = real_t(dest_index) / 255.0f;
//blend = Math::lerp(blend, real_t(0.0f), alpha_clip * opacity + _range_buffer);

//dest_index = int(Math::lerp(index_base, index, brush_alpha > 0.1f));
//dest_index = int(Math::lerp(index_base, texture_id, brush_alpha > 0.1f));
//dest.r = dest_index / 255.0f;
//dest.b = Math::lerp(real_t(src.b), real_t(0.0f), alpha_clip * opacity);

//dest_index = (brush_alpha < 0.1f) ? base_index : index;
dest_index = int(Math::lerp(base_index, index, alpha_clip));
base_index = dest_index;
overlay_index = dest_index;
blend = Math::lerp(blend, real_t(0.0f), alpha_clip * opacity + _range_buffer);
//dest_index = (brush_alpha < 0.1f) ? base_index : texture_id;

//dest_index = int(Math::lerp(base_index, texture_id, alpha_clip));
//base_index = dest_index;
//overlay_index = dest_index;
//blend = Math::lerp(blend, real_t(0.0f), alpha_clip * opacity + _range_buffer);

//if (brush_alpha > 0.1f) {
// base_index = index;
// overlay_index = index;
// blend = 0.0f;
//}
if (brush_alpha > 0.1f) {
base_index = texture_id;
overlay_index = texture_id;
blend = 0.0f;
blend_index = 0;
}
break;
case Terrain3DEditor::ADD:
// Spray Overlay
//dest_index = uint32_t(Math::lerp(overlay_index, index, alpha_clip));
//dest_index = uint32_t(Math::lerp(overlay_index, index, alpha_clip));
//dest_index = uint32_t(Math::lerp(overlay_index, texture_id, alpha_clip));
//dest_index = uint32_t(Math::lerp(overlay_index, texture_id, alpha_clip));
//if (dest_index == base_index) {
// blend = Math::lerp(blend, real_t(0.0f), alpha_clip * opacity * real_t(0.5f)+_range_buffer);
//} else {
// overlay_index = real_t(dest_index) / 255.0f;
// blend = Math::lerp(blend, CLAMP(blend + brush_alpha, real_t(0.0f), real_t(1.0f)), brush_alpha * opacity * real_t(0.5f)+_range_buffer);
//}

//dest_index = int(Math::lerp(index_overlay, index, alpha_clip));
//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));
//} 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));
//}

//dest_index = (brush_alpha < 0.1f) ? overlay_index : index;
dest_index = int(Math::lerp(overlay_index, index, alpha_clip));
if (dest_index == base_index) {
// why not brush_alpha?
real_t factor = CLAMP(alpha_clip * opacity * real_t(0.5f) + _range_buffer, real_t(0.f), real_t(1.f));
blend = Math::lerp(blend, real_t(0.0f), factor);
} else {
overlay_index = dest_index;
real_t b = CLAMP(blend + brush_alpha, real_t(0.0f), real_t(1.0f));
real_t factor = CLAMP(brush_alpha * opacity * real_t(0.5f) + _range_buffer, real_t(0.f), real_t(1.f));
blend = Math::lerp(blend, b, factor);
}
//dest_index = (brush_alpha < 0.1f) ? overlay_index : texture_id;
//
//dest_index = int(Math::lerp(overlay_index, texture_id, alpha_clip));
//if (dest_index == base_index) {
// // why not brush_alpha?
// real_t factor = CLAMP(alpha_clip * opacity * real_t(0.5f) + _range_buffer, real_t(0.f), real_t(1.f));
// blend = Math::lerp(blend, real_t(0.0f), factor);
//} else {
// overlay_index = dest_index;
// real_t b = CLAMP(blend + brush_alpha, real_t(0.0f), real_t(1.0f));
// real_t factor = CLAMP(brush_alpha * opacity * real_t(0.5f) + _range_buffer, real_t(0.f), real_t(1.f));
// blend = Math::lerp(blend, b, factor);
//}

//if (brush_alpha > 0.0f) {
// overlay_index = index;
// overlay_index = texture_id;
// real_t b = CLAMP(blend + brush_alpha, real_t(0.0f), real_t(1.0f));
// real_t factor = CLAMP(brush_alpha * opacity * real_t(0.5f) + _range_buffer, real_t(0.f), real_t(1.f));
// blend = Math::lerp(blend, b, factor);
//}

//if (brush_alpha > 0.1f) {
// //blend += brush_alpha * opacity * .1 + _range_buffer; // flips over at 1/8 *.5
// blend += _range_buffer; // flips over at 1/8 *.5
// overlay_index = texture_id;
//}

{
int bindex = Util::closest_index(brush_alpha, Terrain3DStorage::BRANGE, 8);
float balpha = Terrain3DStorage::BRANGE[bindex];
if (balpha >= .1f) {
overlay_index = texture_id;
if (blend_add) {
//blend_index = backup_pixel + brush_step + blend_strength;
//blend_index = oblend_index + blend_strength;
blend = oblend + balpha * blend_strength;
// clamp?
} else {
blend = balpha * blend_strength;
//blend_index = blend_strength;
}
}
}
//start_operation
// take backup
// --start timer
//operation blend
// backup pixel + strength (+1-7)
// --backup pixel + blendstep
// --if timeout, blendstep++
//end operation
// consolidate maps

break;
default:
break;
Expand All @@ -301,6 +350,8 @@ void Terrain3DEditor::_operate_map(Vector3 p_global_position, real_t p_camera_di
map->set_pixelv(map_pixel_position, Color(src.r, 0.f, 0.f, 1.0f));

} else if (map_type == Terrain3DStorage::TYPE_COLOR) {
src = map->get_pixelv(map_pixel_position);
dest = src;
switch (_tool) {
case COLOR:
dest = src.lerp(color, brush_alpha * opacity);
Expand All @@ -322,8 +373,22 @@ void Terrain3DEditor::_operate_map(Vector3 p_global_position, real_t p_camera_di
map->set_pixelv(map_pixel_position, dest);
}
}
}
} // for y
} // for x

//_range_buffer += opacity*.001f;
_range_buffer += .00208333;
if (_range_buffer > .065f) {
_range_buffer = 0.f;
}
if (counter++ % 10 == 0) {
LOG(WARN, "Texture: ", texture_id, ", opacity: ", vformat("%.2f", opacity),
", range_buffer: ", vformat("%.3f", _range_buffer)
//", blend: ", vformat("%.2f", blend),
//", blend_idx: ", Util::closest_index(blend, Terrain3DStorage::RANGE, 8);),
);
}

_modified = true;
storage->force_update_maps(map_type);
}
Expand Down Expand Up @@ -477,6 +542,7 @@ void Terrain3DEditor::operate(Vector3 p_global_position, real_t p_camera_directi

// Called on left mouse button released
void Terrain3DEditor::stop_operation() {
LOG(WARN, "range_buffer: ", vformat("%.3f", _range_buffer));
if (_pending_undo && _modified) {
_store_undo();
_pending_undo = false;
Expand Down
6 changes: 5 additions & 1 deletion src/terrain_3d_editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class Terrain3DEditor : public Object {

int _size = 0;
real_t _opacity = 0.0;
int _blend_strength = 0.0;
bool _blend_add = 0.0;
real_t _height = 0.0;
Color _color = COLOR_ROUGHNESS;
real_t _roughness = 0.5;
Expand All @@ -83,6 +85,8 @@ class Terrain3DEditor : public Object {

int get_size() const { return _size; }
real_t get_opacity() const { return _opacity; }
int get_blend_strength() const { return _blend_strength; }
bool is_blend_additive() const { return _blend_add; }
real_t get_height() const { return _height; }
Color get_color() const { return _color; }
real_t get_roughness() const { return _roughness; }
Expand All @@ -105,7 +109,7 @@ class Terrain3DEditor : public Object {
Brush _brush;
Vector3 _operation_position = Vector3();
real_t _operation_interval = 0.0f;
real_t _range_buffer = 0.0f;
real_t _range_buffer = 0.0f; // a tipping bucket for filling the gaps between the stepped range values
bool _pending_undo = false;
bool _modified = false;
Array _undo_set; // 0-2: map 0,1,2, 3: Region offsets, 4: height range
Expand Down
3 changes: 2 additions & 1 deletion src/terrain_3d_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ class Terrain3DStorage : public Resource {
COLOR_ZERO, // TYPE_MAX, unused just in case someone indexes the array
};

static inline const float RANGE[] = { 0.0f, .125f, .25f, .334f, .5f, .667f, .8f, 1.0f };
static inline const float BRANGE[] = { 0.0f, .125f, .25f, .334f, .5f, .667f, .8f, 1.0f };
static inline const float RANGE[] = { .125f, .25f, .334f, .375f, .5f, .625f, .75f, .93f };

enum RegionSize {
//SIZE_64 = 64,
Expand Down

0 comments on commit 65b63b9

Please sign in to comment.