188 lines
5.7 KiB
C++
188 lines
5.7 KiB
C++
#include "voxel_node.h"
|
|
#include "../edition/voxel_tool.h"
|
|
#include "../generators/voxel_generator.h"
|
|
#include "../meshers/voxel_mesher.h"
|
|
#include "../streams/voxel_stream.h"
|
|
|
|
namespace zylann::voxel {
|
|
|
|
void VoxelNode::set_mesher(Ref<VoxelMesher> mesher) {
|
|
// Implemented in subclasses
|
|
}
|
|
|
|
Ref<VoxelMesher> VoxelNode::get_mesher() const {
|
|
// Implemented in subclasses
|
|
return Ref<VoxelMesher>();
|
|
}
|
|
|
|
void VoxelNode::set_stream(Ref<VoxelStream> stream) {
|
|
// Implemented in subclasses
|
|
}
|
|
|
|
Ref<VoxelStream> VoxelNode::get_stream() const {
|
|
// Implemented in subclasses
|
|
return Ref<VoxelStream>();
|
|
}
|
|
|
|
void VoxelNode::set_generator(Ref<VoxelGenerator> generator) {
|
|
// Implemented in subclasses
|
|
}
|
|
|
|
Ref<VoxelGenerator> VoxelNode::get_generator() const {
|
|
// Implemented in subclasses
|
|
return Ref<VoxelGenerator>();
|
|
}
|
|
|
|
void VoxelNode::restart_stream() {
|
|
// Not implemented
|
|
}
|
|
|
|
void VoxelNode::remesh_all_blocks() {
|
|
// Not implemented
|
|
}
|
|
|
|
uint32_t VoxelNode::get_volume_id() const {
|
|
CRASH_NOW_MSG("Not implemented");
|
|
return 0;
|
|
}
|
|
|
|
std::shared_ptr<StreamingDependency> VoxelNode::get_streaming_dependency() const {
|
|
CRASH_NOW_MSG("Not implemented");
|
|
return nullptr;
|
|
}
|
|
|
|
Ref<VoxelTool> VoxelNode::get_voxel_tool() {
|
|
CRASH_NOW_MSG("Not implemented");
|
|
return Ref<VoxelTool>();
|
|
}
|
|
|
|
#ifdef TOOLS_ENABLED
|
|
|
|
TypedArray<String> VoxelNode::get_configuration_warnings() const {
|
|
Ref<VoxelMesher> mesher = get_mesher();
|
|
Ref<VoxelStream> stream = get_stream();
|
|
Ref<VoxelGenerator> generator = get_generator();
|
|
|
|
TypedArray<String> warnings = Node3D::get_configuration_warnings();
|
|
|
|
if (mesher.is_null()) {
|
|
warnings.append(TTR("This node has no mesher assigned, it wont produce any mesh visuals. "
|
|
"You can assign one on the `mesher` property."));
|
|
}
|
|
|
|
if (stream.is_valid()) {
|
|
Ref<Script> script = stream->get_script();
|
|
|
|
if (script.is_valid()) {
|
|
if (script->is_tool()) {
|
|
// TODO This is very annoying. Probably needs an issue or proposal in Godot so we can handle this
|
|
// properly?
|
|
warnings.append(TTR("Careful, don't edit your custom stream while it's running, "
|
|
"it can cause crashes. Turn off `run_stream_in_editor` before doing so."));
|
|
} else {
|
|
warnings.append(TTR("The custom stream is not tool, the editor won't be able to use it."));
|
|
}
|
|
}
|
|
|
|
if (mesher.is_valid()) {
|
|
const int stream_channels = stream->get_used_channels_mask();
|
|
const int mesher_channels = mesher->get_used_channels_mask();
|
|
|
|
if ((stream_channels & mesher_channels) == 0) {
|
|
warnings.append(TTR("The current stream is providing voxel data only on channels that are not used by "
|
|
"the current mesher. This will result in nothing being visible."));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (generator.is_valid()) {
|
|
Ref<Script> script = generator->get_script();
|
|
bool can_check_generator_channels = true;
|
|
|
|
if (script.is_valid()) {
|
|
if (script->is_tool()) {
|
|
// TODO This is very annoying. Probably needs an issue or proposal in Godot so we can handle this
|
|
// properly?
|
|
warnings.append(TTR("Careful, don't edit your custom generator while it's running, "
|
|
"it can cause crashes. Turn off `run_stream_in_editor` before doing so."));
|
|
} else {
|
|
can_check_generator_channels = false;
|
|
// return TTR("The custom generator is not tool, the editor won't be able to use it.");
|
|
}
|
|
}
|
|
|
|
if (can_check_generator_channels && mesher.is_valid()) {
|
|
const int generator_channels = generator->get_used_channels_mask();
|
|
const int mesher_channels = mesher->get_used_channels_mask();
|
|
|
|
if ((generator_channels & mesher_channels) == 0) {
|
|
warnings.append(
|
|
TTR("The current generator is providing voxel data only on channels that are not used by "
|
|
"the current mesher. This will result in nothing being visible."));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (mesher.is_valid()) {
|
|
mesher->get_configuration_warnings(warnings);
|
|
}
|
|
|
|
return warnings;
|
|
}
|
|
|
|
#endif
|
|
|
|
int VoxelNode::get_used_channels_mask() const {
|
|
Ref<VoxelMesher> mesher = get_mesher();
|
|
if (mesher.is_valid()) {
|
|
return mesher->get_used_channels_mask();
|
|
}
|
|
Ref<VoxelGenerator> generator = get_generator();
|
|
if (generator.is_valid()) {
|
|
return generator->get_used_channels_mask();
|
|
}
|
|
Ref<VoxelStream> stream = get_stream();
|
|
if (stream.is_valid()) {
|
|
return stream->get_used_channels_mask();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void VoxelNode::set_gi_mode(VoxelNode::GIMode mode) {
|
|
ERR_FAIL_INDEX(mode, _GI_MODE_COUNT);
|
|
if (mode != _gi_mode) {
|
|
_gi_mode = mode;
|
|
_on_gi_mode_changed();
|
|
}
|
|
}
|
|
|
|
VoxelNode::GIMode VoxelNode::get_gi_mode() const {
|
|
return _gi_mode;
|
|
}
|
|
|
|
void VoxelNode::_bind_methods() {
|
|
ClassDB::bind_method(D_METHOD("set_stream", "stream"), &VoxelNode::_b_set_stream);
|
|
ClassDB::bind_method(D_METHOD("get_stream"), &VoxelNode::_b_get_stream);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_generator", "generator"), &VoxelNode::_b_set_generator);
|
|
ClassDB::bind_method(D_METHOD("get_generator"), &VoxelNode::_b_get_generator);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_mesher", "mesher"), &VoxelNode::_b_set_mesher);
|
|
ClassDB::bind_method(D_METHOD("get_mesher"), &VoxelNode::_b_get_mesher);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_gi_mode", "mode"), &VoxelNode::set_gi_mode);
|
|
ClassDB::bind_method(D_METHOD("get_gi_mode"), &VoxelNode::get_gi_mode);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, VoxelStream::get_class_static()),
|
|
"set_stream", "get_stream");
|
|
ADD_PROPERTY(
|
|
PropertyInfo(Variant::OBJECT, "generator", PROPERTY_HINT_RESOURCE_TYPE, VoxelGenerator::get_class_static()),
|
|
"set_generator", "get_generator");
|
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesher", PROPERTY_HINT_RESOURCE_TYPE, VoxelMesher::get_class_static()),
|
|
"set_mesher", "get_mesher");
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_mode", PROPERTY_HINT_ENUM, "Disabled,Baked,Dynamic"), "set_gi_mode",
|
|
"get_gi_mode");
|
|
}
|
|
|
|
} // namespace zylann::voxel
|