mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-02-11 18:40:06 +01:00
Optimized editing in TerrainWorldEditor.
This commit is contained in:
parent
c13a4d08a5
commit
2688162cf9
@ -375,6 +375,8 @@ void TerrainWorldEditor::isolevel_brush_draw(const Vector3 &p_world_position) {
|
||||
// Value will likely need more fine tuning.
|
||||
float s = 10.0 * _isolevel_brush_strength;
|
||||
|
||||
Array draw_data;
|
||||
|
||||
// TODO use a proper circle drawing algorithm.
|
||||
for (int x = -ilbh; x < ilbh; ++x) {
|
||||
for (int y = -ilbh; y < ilbh; ++y) {
|
||||
@ -412,7 +414,8 @@ void TerrainWorldEditor::isolevel_brush_draw(const Vector3 &p_world_position) {
|
||||
|
||||
uint8_t new_val = static_cast<uint8_t>(npil);
|
||||
|
||||
_world->set_voxel_at_world_data_position(vwp, new_val, _isolevel_brush_channel, true, _isolevel_brush_allow_create_chunks);
|
||||
draw_data.push_back(vwp);
|
||||
draw_data.push_back(new_val);
|
||||
|
||||
if (!_original_data.has(vwp)) {
|
||||
_original_data[vwp] = orig_val;
|
||||
@ -421,6 +424,8 @@ void TerrainWorldEditor::isolevel_brush_draw(const Vector3 &p_world_position) {
|
||||
_current_data[vwp] = new_val;
|
||||
}
|
||||
}
|
||||
|
||||
_world->set_voxels_at_world_data_position(draw_data, _isolevel_brush_channel, true, _isolevel_brush_allow_create_chunks);
|
||||
}
|
||||
|
||||
void TerrainWorldEditor::paint_brush_draw(const Vector3 &p_world_position) {
|
||||
@ -440,6 +445,8 @@ void TerrainWorldEditor::paint_brush_draw(const Vector3 &p_world_position) {
|
||||
selected_terrain = _selected_type + 1;
|
||||
uint8_t new_val = static_cast<uint8_t>(selected_terrain);
|
||||
|
||||
Array draw_data;
|
||||
|
||||
// TODO use a proper circle drawing algorithm.
|
||||
for (int x = -ilbh; x < ilbh; ++x) {
|
||||
for (int y = -ilbh; y < ilbh; ++y) {
|
||||
@ -453,7 +460,8 @@ void TerrainWorldEditor::paint_brush_draw(const Vector3 &p_world_position) {
|
||||
|
||||
uint8_t orig_val = _world->get_voxel_at_world_data_position(vwp, _paint_brush_channel);
|
||||
|
||||
_world->set_voxel_at_world_data_position(vwp, new_val, _paint_brush_channel, true, _paint_brush_allow_create_chunks);
|
||||
draw_data.push_back(vwp);
|
||||
draw_data.push_back(new_val);
|
||||
|
||||
if (!_original_data.has(vwp)) {
|
||||
_original_data[vwp] = orig_val;
|
||||
@ -462,6 +470,8 @@ void TerrainWorldEditor::paint_brush_draw(const Vector3 &p_world_position) {
|
||||
_current_data[vwp] = new_val;
|
||||
}
|
||||
}
|
||||
|
||||
_world->set_voxels_at_world_data_position(draw_data, _paint_brush_channel, true, _paint_brush_allow_create_chunks);
|
||||
}
|
||||
|
||||
void TerrainWorldEditor::edit(TerrainWorld *p_world) {
|
||||
@ -946,12 +956,7 @@ void TerrainWorldEditor::apply_data(const Array &p_data) {
|
||||
bool allow_create_chunks = p_data[2];
|
||||
Array data = p_data[3];
|
||||
|
||||
for (int i = 0; i < data.size(); i += 2) {
|
||||
Vector2i pos = data[i];
|
||||
uint8_t d = data[i + 1];
|
||||
|
||||
_world->set_voxel_at_world_data_position(pos, d, channel, true, allow_create_chunks);
|
||||
}
|
||||
_world->set_voxels_at_world_data_position(data, channel, true, allow_create_chunks);
|
||||
}
|
||||
|
||||
void TerrainWorldEditor::create_undo_point(const String &p_action, const int p_channel, const bool p_allow_create_chunks) {
|
||||
|
@ -31,6 +31,8 @@
|
||||
|
||||
#include "terrain_world.h"
|
||||
|
||||
#include "core/containers/hash_set.h"
|
||||
|
||||
#include "core/object/message_queue.h"
|
||||
#include "terrain_chunk.h"
|
||||
#include "terrain_structure.h"
|
||||
@ -1035,6 +1037,120 @@ Ref<TerrainChunk> TerrainWorld::get_or_create_chunk_at_world_data_position(const
|
||||
return chunk_get_or_create(x, z);
|
||||
}
|
||||
|
||||
void TerrainWorld::set_voxels_at_world_data_position(const Array &p_data, const int p_channel_index, const bool p_immediate_build, const bool p_allow_creating_chunks) {
|
||||
ERR_FAIL_COND(p_data.size() % 2 != 0);
|
||||
|
||||
// TODO rework this so it works directly with ints.
|
||||
|
||||
HashSet<Ref<TerrainChunk>> chunks_to_rebuild;
|
||||
|
||||
for (int i = 0; i < p_data.size(); i += 2) {
|
||||
Vector2i world_data_position = p_data[i];
|
||||
uint8_t value = p_data[i + 1];
|
||||
|
||||
Vector2 pos = world_data_position;
|
||||
|
||||
//Note: floor is needed to handle negative numbers properly
|
||||
int x = static_cast<int>(Math::floor(pos.x / get_chunk_size_x()));
|
||||
int z = static_cast<int>(Math::floor(pos.y / get_chunk_size_z()));
|
||||
|
||||
int bx = static_cast<int>(Math::floor(pos.x)) % get_chunk_size_x();
|
||||
int bz = static_cast<int>(Math::floor(pos.y)) % get_chunk_size_z();
|
||||
|
||||
if (bx < 0) {
|
||||
bx += get_chunk_size_x();
|
||||
}
|
||||
|
||||
if (bz < 0) {
|
||||
bz += get_chunk_size_z();
|
||||
}
|
||||
|
||||
Ref<TerrainChunk> chunk;
|
||||
|
||||
if (get_data_margin_end() > 0) {
|
||||
if (bx == 0) {
|
||||
if (p_allow_creating_chunks) {
|
||||
chunk = chunk_get_or_create(x - 1, z);
|
||||
} else {
|
||||
chunk = chunk_get(x - 1, z);
|
||||
}
|
||||
|
||||
if (chunk.is_valid()) {
|
||||
chunk->set_voxel(value, get_chunk_size_x(), bz, p_channel_index);
|
||||
|
||||
chunks_to_rebuild.insert(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
if (bz == 0) {
|
||||
if (p_allow_creating_chunks) {
|
||||
chunk = chunk_get_or_create(x, z - 1);
|
||||
} else {
|
||||
chunk = chunk_get(x, z - 1);
|
||||
}
|
||||
|
||||
if (chunk.is_valid()) {
|
||||
chunk->set_voxel(value, bx, get_chunk_size_z(), p_channel_index);
|
||||
|
||||
chunks_to_rebuild.insert(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (get_data_margin_start() > 0) {
|
||||
if (bx == get_chunk_size_x() - 1) {
|
||||
if (p_allow_creating_chunks) {
|
||||
chunk = chunk_get_or_create(x + 1, z);
|
||||
} else {
|
||||
chunk = chunk_get(x + 1, z);
|
||||
}
|
||||
|
||||
if (chunk.is_valid()) {
|
||||
chunk->set_voxel(value, -1, bz, p_channel_index);
|
||||
|
||||
chunks_to_rebuild.insert(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
if (bz == get_chunk_size_z() - 1) {
|
||||
if (p_allow_creating_chunks) {
|
||||
chunk = chunk_get_or_create(x, z + 1);
|
||||
} else {
|
||||
chunk = chunk_get(x, z + 1);
|
||||
}
|
||||
|
||||
if (chunk.is_valid()) {
|
||||
chunk->set_voxel(value, bx, -1, p_channel_index);
|
||||
|
||||
chunks_to_rebuild.insert(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_allow_creating_chunks) {
|
||||
chunk = chunk_get_or_create(x, z);
|
||||
} else {
|
||||
chunk = chunk_get(x, z);
|
||||
}
|
||||
|
||||
if (chunk.is_valid()) {
|
||||
chunk->set_voxel(value, bx, bz, p_channel_index);
|
||||
|
||||
chunks_to_rebuild.insert(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
for (HashSet<Ref<TerrainChunk>>::Iterator iter = chunks_to_rebuild.begin(); iter.valid(); iter.next()) {
|
||||
Ref<TerrainChunk> chunk = iter.key();
|
||||
|
||||
if (p_immediate_build) {
|
||||
chunk->build_immediate();
|
||||
} else {
|
||||
chunk->build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int TerrainWorld::get_channel_index_info(const TerrainWorld::ChannelTypeInfo channel_type) {
|
||||
return call("_get_channel_index_info", channel_type);
|
||||
}
|
||||
@ -1411,6 +1527,7 @@ void TerrainWorld::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_voxel_at_world_data_position", "world_data_position", "data", "channel_index", "rebuild", "allow_creating_chunks "), &TerrainWorld::set_voxel_at_world_data_position, DEFVAL(true), DEFVAL(true));
|
||||
ClassDB::bind_method(D_METHOD("get_chunk_at_world_data_position", "world_data_position"), &TerrainWorld::get_chunk_at_world_data_position);
|
||||
ClassDB::bind_method(D_METHOD("get_or_create_chunk_at_world_data_position", "world_data_position"), &TerrainWorld::get_or_create_chunk_at_world_data_position);
|
||||
ClassDB::bind_method(D_METHOD("set_voxels_at_world_data_position", "data", "channel_index", "immediate_build", "allow_creating_chunks"), &TerrainWorld::set_voxels_at_world_data_position, DEFVAL(false), DEFVAL(true));
|
||||
|
||||
BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::INT, "ret"), "_get_channel_index_info", PropertyInfo(Variant::INT, "channel_type", PROPERTY_HINT_ENUM, BINDING_STRING_CHANNEL_TYPE_INFO)));
|
||||
|
||||
|
@ -198,6 +198,7 @@ public:
|
||||
void set_voxel_at_world_data_position(const Vector2i &world_data_position, const uint8_t data, const int channel_index, const bool p_immediate_build = true, const bool allow_creating_chunks = true);
|
||||
Ref<TerrainChunk> get_chunk_at_world_data_position(const Vector2i &world_data_position);
|
||||
Ref<TerrainChunk> get_or_create_chunk_at_world_data_position(const Vector2i &world_data_position);
|
||||
void set_voxels_at_world_data_position(const Array &p_data, const int p_channel_index, const bool p_immediate_build = false, const bool p_allow_creating_chunks = true);
|
||||
|
||||
int get_channel_index_info(const ChannelTypeInfo channel_type);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user