mirror of
https://github.com/Relintai/godot_voxel.git
synced 2024-11-11 20:35:08 +01:00
Added VoxelIsoSurfaceTool
This commit is contained in:
parent
9108bfe0f6
commit
1defe3bdbd
@ -3,6 +3,7 @@
|
||||
#include "transvoxel/voxel_mesher_transvoxel.h"
|
||||
#include "voxel_box_mover.h"
|
||||
#include "voxel_buffer.h"
|
||||
#include "voxel_isosurface_tool.h"
|
||||
#include "voxel_library.h"
|
||||
#include "voxel_map.h"
|
||||
#include "voxel_mesher.h"
|
||||
@ -23,8 +24,8 @@ void register_voxel_types() {
|
||||
ClassDB::register_class<VoxelProviderImage>();
|
||||
ClassDB::register_class<VoxelMesherTransvoxel>();
|
||||
ClassDB::register_class<VoxelBoxMover>();
|
||||
|
||||
ClassDB::register_class<VoxelMesherDMC>();
|
||||
ClassDB::register_class<VoxelIsoSurfaceTool>();
|
||||
}
|
||||
|
||||
void unregister_voxel_types() {
|
||||
|
@ -71,4 +71,12 @@ inline T interpolate(const T v0, const T v1, const T v2, const T v3, const T v4,
|
||||
return res;
|
||||
}
|
||||
|
||||
inline float min(const float &a, const float &b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
inline float max(const float &a, const float &b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
#endif // HEADER_VOXEL_UTILITY_H
|
||||
|
141
voxel_isosurface_tool.cpp
Normal file
141
voxel_isosurface_tool.cpp
Normal file
@ -0,0 +1,141 @@
|
||||
#include "voxel_isosurface_tool.h"
|
||||
#include "utility.h"
|
||||
|
||||
VoxelIsoSurfaceTool::VoxelIsoSurfaceTool() {
|
||||
_iso_scale = 1.0;
|
||||
}
|
||||
|
||||
void VoxelIsoSurfaceTool::set_buffer(Ref<VoxelBuffer> buffer) {
|
||||
_buffer = buffer;
|
||||
}
|
||||
|
||||
Ref<VoxelBuffer> VoxelIsoSurfaceTool::get_buffer() const {
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
void VoxelIsoSurfaceTool::set_iso_scale(float iso_scale) {
|
||||
_iso_scale = iso_scale;
|
||||
}
|
||||
|
||||
float VoxelIsoSurfaceTool::get_iso_scale() const {
|
||||
return _iso_scale;
|
||||
}
|
||||
|
||||
void VoxelIsoSurfaceTool::set_offset(Vector3 offset) {
|
||||
_offset = offset;
|
||||
}
|
||||
|
||||
Vector3 VoxelIsoSurfaceTool::get_offset() const {
|
||||
return _offset;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
inline void do_op(VoxelBuffer &buffer, int x, int y, int z, float d1, VoxelIsoSurfaceTool::Operation op) {
|
||||
|
||||
float res;
|
||||
|
||||
switch (op) {
|
||||
|
||||
case VoxelIsoSurfaceTool::OP_ADD:
|
||||
res = MIN(d1, buffer.get_voxel_iso(x, y, z, VoxelBuffer::CHANNEL_ISOLEVEL));
|
||||
break;
|
||||
|
||||
case VoxelIsoSurfaceTool::OP_SUBTRACT:
|
||||
res = MAX(d1, buffer.get_voxel_iso(x, y, z, VoxelBuffer::CHANNEL_ISOLEVEL));
|
||||
break;
|
||||
|
||||
case VoxelIsoSurfaceTool::OP_SET:
|
||||
res = d1;
|
||||
break;
|
||||
}
|
||||
|
||||
buffer.set_voxel_iso(res, x, y, z, VoxelBuffer::CHANNEL_ISOLEVEL);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void VoxelIsoSurfaceTool::do_sphere(Vector3 center, real_t radius, Operation op) {
|
||||
|
||||
ERR_FAIL_COND(_buffer.is_null());
|
||||
VoxelBuffer &buffer = **_buffer;
|
||||
|
||||
center += _offset;
|
||||
|
||||
for (int z = 0; z < buffer.get_size().z; ++z) {
|
||||
for (int x = 0; x < buffer.get_size().x; ++x) {
|
||||
for (int y = 0; y < buffer.get_size().y; ++y) {
|
||||
|
||||
float d1 = (center.distance_to(Vector3(x, y, z)) - radius) * _iso_scale;
|
||||
do_op(buffer, x, y, z, d1, op);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelIsoSurfaceTool::do_plane(Plane plane, Operation op) {
|
||||
|
||||
ERR_FAIL_COND(_buffer.is_null());
|
||||
VoxelBuffer &buffer = **_buffer;
|
||||
|
||||
plane = Plane(plane.center() + _offset, plane.normal);
|
||||
|
||||
for (int z = 0; z < buffer.get_size().z; ++z) {
|
||||
for (int x = 0; x < buffer.get_size().x; ++x) {
|
||||
for (int y = 0; y < buffer.get_size().y; ++y) {
|
||||
|
||||
float d1 = plane.distance_to(Vector3(x, y, z)) * _iso_scale;
|
||||
do_op(buffer, x, y, z, d1, op);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
inline float sdf_cube(Vector3 pos, Vector3 extents) {
|
||||
|
||||
Vector3 d = pos.abs() - extents;
|
||||
return min(max(d.x, max(d.y, d.z)), 0.0) + Vector3(max(d.x, 0), max(d.y, 0), max(d.z, 0)).length();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void VoxelIsoSurfaceTool::do_cube(Transform transform, Vector3 extents, Operation op) {
|
||||
|
||||
ERR_FAIL_COND(_buffer.is_null());
|
||||
VoxelBuffer &buffer = **_buffer;
|
||||
|
||||
transform.origin += _offset;
|
||||
Transform inv_transform = transform.affine_inverse();
|
||||
|
||||
for (int z = 0; z < buffer.get_size().z; ++z) {
|
||||
for (int x = 0; x < buffer.get_size().x; ++x) {
|
||||
for (int y = 0; y < buffer.get_size().y; ++y) {
|
||||
|
||||
Vector3 pos = inv_transform.xform(Vector3(x, y, z));
|
||||
do_op(buffer, x, y, z, sdf_cube(pos, extents), op);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelIsoSurfaceTool::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_buffer", "voxel_buffer"), &VoxelIsoSurfaceTool::set_buffer);
|
||||
ClassDB::bind_method(D_METHOD("get_buffer"), &VoxelIsoSurfaceTool::get_buffer);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_iso_scale", "iso_scale"), &VoxelIsoSurfaceTool::set_iso_scale);
|
||||
ClassDB::bind_method(D_METHOD("get_iso_scale"), &VoxelIsoSurfaceTool::get_iso_scale);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_offset", "offset"), &VoxelIsoSurfaceTool::set_offset);
|
||||
ClassDB::bind_method(D_METHOD("get_offset"), &VoxelIsoSurfaceTool::get_offset);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("do_sphere", "center", "radius", "op"), &VoxelIsoSurfaceTool::do_sphere);
|
||||
ClassDB::bind_method(D_METHOD("do_plane", "plane", "op"), &VoxelIsoSurfaceTool::do_plane);
|
||||
ClassDB::bind_method(D_METHOD("do_cube", "transform", "extents", "op"), &VoxelIsoSurfaceTool::do_cube);
|
||||
|
||||
BIND_ENUM_CONSTANT(OP_ADD);
|
||||
BIND_ENUM_CONSTANT(OP_SUBTRACT);
|
||||
BIND_ENUM_CONSTANT(OP_SET);
|
||||
}
|
41
voxel_isosurface_tool.h
Normal file
41
voxel_isosurface_tool.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef VOXEL_ISOSURFACE_TOOL_H
|
||||
#define VOXEL_ISOSURFACE_TOOL_H
|
||||
|
||||
#include "voxel_buffer.h"
|
||||
|
||||
class VoxelIsoSurfaceTool : public Reference {
|
||||
GDCLASS(VoxelIsoSurfaceTool, Reference)
|
||||
public:
|
||||
enum Operation {
|
||||
OP_ADD = 0,
|
||||
OP_SUBTRACT,
|
||||
OP_SET
|
||||
};
|
||||
|
||||
VoxelIsoSurfaceTool();
|
||||
|
||||
void set_buffer(Ref<VoxelBuffer> buffer);
|
||||
Ref<VoxelBuffer> get_buffer() const;
|
||||
|
||||
void set_iso_scale(float iso_scale);
|
||||
float get_iso_scale() const;
|
||||
|
||||
void set_offset(Vector3 offset);
|
||||
Vector3 get_offset() const;
|
||||
|
||||
void do_sphere(Vector3 center, real_t radius, Operation op);
|
||||
void do_plane(Plane plane, Operation op);
|
||||
void do_cube(Transform transform, Vector3 extents, Operation op);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
private:
|
||||
Ref<VoxelBuffer> _buffer;
|
||||
float _iso_scale;
|
||||
Vector3 _offset;
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(VoxelIsoSurfaceTool::Operation)
|
||||
|
||||
#endif // VOXEL_ISOSURFACE_TOOL_H
|
Loading…
Reference in New Issue
Block a user