mirror of
https://github.com/Relintai/godot_voxel.git
synced 2024-11-11 20:35:08 +01:00
Added try_set_voxel and fix fill_area in cases where the box is out of range
This commit is contained in:
parent
20d8cf876b
commit
b052f7fc2d
16
rect3i.h
16
rect3i.h
@ -53,6 +53,22 @@ public:
|
||||
return String("(o:{0}, s:{1})").format(varray(pos.to_vec3(), size.to_vec3()));
|
||||
}
|
||||
|
||||
bool intersects(Rect3i other) {
|
||||
if (pos.x > other.pos.x + other.size.x)
|
||||
return false;
|
||||
if (pos.y > other.pos.y + other.size.y)
|
||||
return false;
|
||||
if (pos.z > other.pos.z + other.size.z)
|
||||
return false;
|
||||
if (other.pos.x > pos.x + size.x)
|
||||
return false;
|
||||
if (other.pos.y > pos.y + size.y)
|
||||
return false;
|
||||
if (other.pos.z > pos.z + size.z)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline bool operator!=(const Rect3i & a, const Rect3i & b) {
|
||||
|
@ -84,6 +84,7 @@ struct Vector3i {
|
||||
if (y < min.y) y = min.y;
|
||||
if (z < min.z) z = min.z;
|
||||
|
||||
// TODO Not sure it should clamp like that...
|
||||
if (x >= max.x) x = max.x - 1;
|
||||
if (y >= max.y) y = max.y - 1;
|
||||
if (z >= max.z) z = max.z - 1;
|
||||
|
@ -78,6 +78,24 @@ void VoxelBuffer::set_voxel(int value, int x, int y, int z, unsigned int channel
|
||||
}
|
||||
}
|
||||
|
||||
// This version does not cause errors if out of bounds. Use only if it's okay to be outside.
|
||||
void VoxelBuffer::try_set_voxel(int x, int y, int z, int value, unsigned int channel_index) {
|
||||
ERR_FAIL_INDEX(channel_index, MAX_CHANNELS);
|
||||
if(!validate_pos(x, y, z))
|
||||
return;
|
||||
|
||||
Channel &channel = _channels[channel_index];
|
||||
|
||||
if (channel.data == NULL) {
|
||||
if (channel.defval != value) {
|
||||
create_channel(channel_index, _size);
|
||||
channel.data[index(x, y, z)] = value;
|
||||
}
|
||||
} else {
|
||||
channel.data[index(x, y, z)] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelBuffer::set_voxel_v(int value, Vector3 pos, unsigned int channel_index) {
|
||||
set_voxel(value, pos.x, pos.y, pos.z, channel_index);
|
||||
}
|
||||
@ -109,10 +127,13 @@ void VoxelBuffer::fill_area(int defval, Vector3i min, Vector3i max, unsigned int
|
||||
|
||||
Vector3i::sort_min_max(min, max);
|
||||
|
||||
min.clamp_to(Vector3i(0, 0, 0), _size);
|
||||
min.clamp_to(Vector3i(0, 0, 0), _size + Vector3i(1, 1, 1));
|
||||
max.clamp_to(Vector3i(0, 0, 0), _size + Vector3i(1, 1, 1));
|
||||
Vector3i area_size = max - min;
|
||||
|
||||
if(area_size.x == 0 || area_size.y == 0 || area_size.z == 0)
|
||||
return;
|
||||
|
||||
Channel &channel = _channels[channel_index];
|
||||
if (channel.data == NULL) {
|
||||
if (channel.defval == defval)
|
||||
@ -122,9 +143,11 @@ void VoxelBuffer::fill_area(int defval, Vector3i min, Vector3i max, unsigned int
|
||||
}
|
||||
|
||||
Vector3i pos;
|
||||
int volume = get_volume();
|
||||
for (pos.z = min.z; pos.z < max.z; ++pos.z) {
|
||||
for (pos.x = min.x; pos.x < max.x; ++pos.x) {
|
||||
unsigned int dst_ri = index(pos.x, pos.y + min.y, pos.z);
|
||||
CRASH_COND(dst_ri >= volume);
|
||||
memset(&channel.data[dst_ri], defval, area_size.y * sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,8 @@ public:
|
||||
void set_voxel(int value, int x, int y, int z, unsigned int channel_index = 0);
|
||||
void set_voxel_v(int value, Vector3 pos, unsigned int channel_index = 0);
|
||||
|
||||
void try_set_voxel(int x, int y, int z, int value, unsigned int channel_index = 0);
|
||||
|
||||
_FORCE_INLINE_ void set_voxel_iso(real_t value, int x, int y, int z, unsigned int channel_index = 0) { set_voxel(iso_to_byte(value), x, y, z, channel_index); }
|
||||
_FORCE_INLINE_ real_t get_voxel_iso(int x, int y, int z, unsigned int channel_index = 0) const { return byte_to_iso(get_voxel(x, y, z, channel_index)); }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user