-Added .hdr format support
-Added default environment editor setting -Added environment created by default in new projects -Removed default light and ambient from spatial editor, to make the editor more PBR compliant
This commit is contained in:
parent
06fc963796
commit
bb20f230ad
34
core/color.h
34
core/color.h
@ -83,6 +83,40 @@ struct Color {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ uint32_t to_rgbe9995() const {
|
||||||
|
|
||||||
|
const float pow2to9 = 512.0f;
|
||||||
|
const float B = 15.0f;
|
||||||
|
//const float Emax = 31.0f;
|
||||||
|
const float N = 9.0f;
|
||||||
|
|
||||||
|
float sharedexp = 65408.000f; //(( pow2to9 - 1.0f)/ pow2to9)*powf( 2.0f, 31.0f - 15.0f);
|
||||||
|
|
||||||
|
float cRed = MAX(0.0f, MIN(sharedexp, r));
|
||||||
|
float cGreen = MAX(0.0f, MIN(sharedexp, g));
|
||||||
|
float cBlue = MAX(0.0f, MIN(sharedexp, b));
|
||||||
|
|
||||||
|
float cMax = MAX(cRed, MAX(cGreen, cBlue));
|
||||||
|
|
||||||
|
// expp = MAX(-B - 1, log2(maxc)) + 1 + B
|
||||||
|
|
||||||
|
float expp = MAX(-B - 1.0f, floor(Math::log(cMax) / Math_LN2)) + 1.0f + B;
|
||||||
|
|
||||||
|
float sMax = (float)floor((cMax / Math::pow(2.0f, expp - B - N)) + 0.5f);
|
||||||
|
|
||||||
|
float exps = expp + 1.0f;
|
||||||
|
|
||||||
|
if (0.0 <= sMax && sMax < pow2to9) {
|
||||||
|
exps = expp;
|
||||||
|
}
|
||||||
|
|
||||||
|
float sRed = Math::floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
|
||||||
|
float sGreen = Math::floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
|
||||||
|
float sBlue = Math::floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
|
||||||
|
|
||||||
|
return (uint32_t(Math::fast_ftoi(sRed)) & 0x1FF) | ((uint32_t(Math::fast_ftoi(sGreen)) & 0x1FF) << 9) | ((uint32_t(Math::fast_ftoi(sBlue)) & 0x1FF) << 18) | ((uint32_t(Math::fast_ftoi(exps)) & 0x1F) << 27);
|
||||||
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ Color blend(const Color &p_over) const {
|
_FORCE_INLINE_ Color blend(const Color &p_over) const {
|
||||||
|
|
||||||
Color res;
|
Color res;
|
||||||
|
@ -1981,35 +1981,7 @@ void Image::put_pixel(int p_x, int p_y, const Color &p_color) {
|
|||||||
} break;
|
} break;
|
||||||
case FORMAT_RGBE9995: {
|
case FORMAT_RGBE9995: {
|
||||||
|
|
||||||
const float pow2to9 = 512.0f;
|
((uint32_t *)ptr)[ofs] = p_color.to_rgbe9995();
|
||||||
const float B = 7.0f;
|
|
||||||
//const float Emax = 31.0f;
|
|
||||||
const float N = 9.0f;
|
|
||||||
|
|
||||||
float sharedexp = 65408.000f; //(( pow2to9 - 1.0f)/ pow2to9)*powf( 2.0f, 31.0f - 15.0f);
|
|
||||||
|
|
||||||
float cRed = MAX(0.0f, MIN(sharedexp, p_color.r));
|
|
||||||
float cGreen = MAX(0.0f, MIN(sharedexp, p_color.g));
|
|
||||||
float cBlue = MAX(0.0f, MIN(sharedexp, p_color.b));
|
|
||||||
|
|
||||||
float cMax = MAX(cRed, MAX(cGreen, cBlue));
|
|
||||||
|
|
||||||
// expp = MAX(-B - 1, log2(maxc)) + 1 + B
|
|
||||||
float expp = MAX(-B - 1.0f, floor(Math::log(cMax) / Math::log(2.0))) + 1.0f + B;
|
|
||||||
|
|
||||||
float sMax = (float)floor((cMax / Math::pow(2.0f, expp - B - N)) + 0.5f);
|
|
||||||
|
|
||||||
float exps = expp + 1.0f;
|
|
||||||
|
|
||||||
if (0.0 <= sMax && sMax < pow2to9) {
|
|
||||||
exps = expp;
|
|
||||||
}
|
|
||||||
|
|
||||||
float sRed = (cRed / pow(2.0f, exps - B - N)) + 0.5f;
|
|
||||||
float sGreen = (cGreen / pow(2.0f, exps - B - N)) + 0.5f;
|
|
||||||
float sBlue = (cBlue / pow(2.0f, exps - B - N)) + 0.5f;
|
|
||||||
|
|
||||||
((uint32_t *)ptr)[ofs] = ((uint32_t)(sRed)&0x1FF) | (((uint32_t)(sGreen)&0x1FF) << 9) | (((uint32_t)(sBlue)&0x1FF) << 18) | (((uint32_t)(exps)&0x1F) << 27);
|
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
|
@ -252,6 +252,27 @@ double FileAccess::get_double() const {
|
|||||||
return m.d;
|
return m.d;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
String FileAccess::get_token() const {
|
||||||
|
|
||||||
|
CharString token;
|
||||||
|
|
||||||
|
CharType c = get_8();
|
||||||
|
|
||||||
|
while (!eof_reached()) {
|
||||||
|
|
||||||
|
if (c <= ' ') {
|
||||||
|
if (!token.empty())
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
token.push_back(c);
|
||||||
|
}
|
||||||
|
c = get_8();
|
||||||
|
}
|
||||||
|
|
||||||
|
token.push_back(0);
|
||||||
|
return String::utf8(token.get_data());
|
||||||
|
}
|
||||||
|
|
||||||
String FileAccess::get_line() const {
|
String FileAccess::get_line() const {
|
||||||
|
|
||||||
CharString line;
|
CharString line;
|
||||||
|
@ -106,6 +106,7 @@ public:
|
|||||||
|
|
||||||
virtual int get_buffer(uint8_t *p_dst, int p_length) const; ///< get an array of bytes
|
virtual int get_buffer(uint8_t *p_dst, int p_length) const; ///< get an array of bytes
|
||||||
virtual String get_line() const;
|
virtual String get_line() const;
|
||||||
|
virtual String get_token() const;
|
||||||
virtual Vector<String> get_csv_line(String delim = ",") const;
|
virtual Vector<String> get_csv_line(String delim = ",") const;
|
||||||
|
|
||||||
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
|
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
|
||||||
|
@ -694,6 +694,106 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
|
|||||||
return ERR_PARSE_ERROR;
|
return ERR_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
} else if (id == "Object") {
|
||||||
|
|
||||||
|
get_token(p_stream, token, line, r_err_str);
|
||||||
|
if (token.type != TK_PARENTHESIS_OPEN) {
|
||||||
|
r_err_str = "Expected '('";
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_token(p_stream, token, line, r_err_str);
|
||||||
|
|
||||||
|
if (token.type != TK_IDENTIFIER) {
|
||||||
|
r_err_str = "Expected identifier with type of object";
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
String type = token.value;
|
||||||
|
|
||||||
|
Object *obj = ClassDB::instance(type);
|
||||||
|
|
||||||
|
if (!obj) {
|
||||||
|
r_err_str = "Can't instance Object() of type: " + type;
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_token(p_stream, token, line, r_err_str);
|
||||||
|
if (token.type != TK_COMMA) {
|
||||||
|
r_err_str = "Expected ',' after object type";
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool at_key = true;
|
||||||
|
String key;
|
||||||
|
Token token;
|
||||||
|
bool need_comma = false;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
if (p_stream->is_eof()) {
|
||||||
|
r_err_str = "Unexpected End of File while parsing Object()";
|
||||||
|
return ERR_FILE_CORRUPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (at_key) {
|
||||||
|
|
||||||
|
Error err = get_token(p_stream, token, line, r_err_str);
|
||||||
|
if (err != OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (token.type == TK_PARENTHESIS_CLOSE) {
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (need_comma) {
|
||||||
|
|
||||||
|
if (token.type != TK_COMMA) {
|
||||||
|
|
||||||
|
r_err_str = "Expected '}' or ','";
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
} else {
|
||||||
|
need_comma = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get_token(p_stream, token, line, r_err_str);
|
||||||
|
if (token.type != TK_STRING) {
|
||||||
|
r_err_str = "Expected property name as string";
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = token.value;
|
||||||
|
|
||||||
|
err = get_token(p_stream, token, line, r_err_str);
|
||||||
|
|
||||||
|
if (err != OK)
|
||||||
|
return err;
|
||||||
|
if (token.type != TK_COLON) {
|
||||||
|
|
||||||
|
r_err_str = "Expected ':'";
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
at_key = false;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
Error err = get_token(p_stream, token, line, r_err_str);
|
||||||
|
if (err != OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
Variant v;
|
||||||
|
err = parse_value(token, v, p_stream, line, r_err_str, p_res_parser);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
obj->set(key, v);
|
||||||
|
need_comma = true;
|
||||||
|
at_key = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
} else if (id == "Resource" || id == "SubResource" || id == "ExtResource") {
|
} else if (id == "Resource" || id == "SubResource" || id == "ExtResource") {
|
||||||
@ -1611,19 +1711,25 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
|||||||
|
|
||||||
case Variant::OBJECT: {
|
case Variant::OBJECT: {
|
||||||
|
|
||||||
RES res = p_variant;
|
Object *obj = p_variant;
|
||||||
if (res.is_null()) {
|
|
||||||
|
if (!obj) {
|
||||||
p_store_string_func(p_store_string_ud, "null");
|
p_store_string_func(p_store_string_ud, "null");
|
||||||
break; // don't save it
|
break; // don't save it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RES res = p_variant;
|
||||||
|
if (res.is_valid()) {
|
||||||
|
//is resource
|
||||||
String res_text;
|
String res_text;
|
||||||
|
|
||||||
|
//try external function
|
||||||
if (p_encode_res_func) {
|
if (p_encode_res_func) {
|
||||||
|
|
||||||
res_text = p_encode_res_func(p_encode_res_ud, res);
|
res_text = p_encode_res_func(p_encode_res_ud, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//try path because it's a file
|
||||||
if (res_text == String() && res->get_path().is_resource_file()) {
|
if (res_text == String() && res->get_path().is_resource_file()) {
|
||||||
|
|
||||||
//external resource
|
//external resource
|
||||||
@ -1631,10 +1737,37 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
|||||||
res_text = "Resource( \"" + path + "\")";
|
res_text = "Resource( \"" + path + "\")";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res_text == String())
|
//could come up with some sort of text
|
||||||
res_text = "null";
|
if (res_text != String()) {
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, res_text);
|
p_store_string_func(p_store_string_ud, res_text);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//store as generic object
|
||||||
|
|
||||||
|
p_store_string_func(p_store_string_ud, "Object(" + obj->get_class() + ",");
|
||||||
|
|
||||||
|
List<PropertyInfo> props;
|
||||||
|
obj->get_property_list(&props);
|
||||||
|
bool first = true;
|
||||||
|
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
|
||||||
|
|
||||||
|
if (E->get().usage & PROPERTY_USAGE_STORAGE || E->get().usage & PROPERTY_USAGE_SCRIPT_VARIABLE) {
|
||||||
|
//must be serialized
|
||||||
|
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
p_store_string_func(p_store_string_ud, ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
p_store_string_func(p_store_string_ud, "\"" + E->get().name + "\":");
|
||||||
|
write(obj->get(E->get().name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p_store_string_func(p_store_string_ud, ")\n");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -889,6 +889,7 @@ void EditorNode::_save_scene(String p_file, int idx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
editor_data.apply_changes_in_editors();
|
editor_data.apply_changes_in_editors();
|
||||||
|
_save_default_environment();
|
||||||
|
|
||||||
_set_scene_metadata(p_file, idx);
|
_set_scene_metadata(p_file, idx);
|
||||||
|
|
||||||
@ -950,7 +951,7 @@ void EditorNode::_save_scene(String p_file, int idx) {
|
|||||||
|
|
||||||
_dialog_display_file_error(p_file, err);
|
_dialog_display_file_error(p_file, err);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
void EditorNode::_import_action(const String &p_action) {
|
void EditorNode::_import_action(const String &p_action) {
|
||||||
#if 0
|
#if 0
|
||||||
@ -1113,6 +1114,7 @@ void EditorNode::_dialog_action(String p_file) {
|
|||||||
if (file->get_mode() == EditorFileDialog::MODE_SAVE_FILE) {
|
if (file->get_mode() == EditorFileDialog::MODE_SAVE_FILE) {
|
||||||
|
|
||||||
//_save_scene(p_file);
|
//_save_scene(p_file);
|
||||||
|
_save_default_environment();
|
||||||
_save_scene_with_preview(p_file);
|
_save_scene_with_preview(p_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1122,6 +1124,7 @@ void EditorNode::_dialog_action(String p_file) {
|
|||||||
if (file->get_mode() == EditorFileDialog::MODE_SAVE_FILE) {
|
if (file->get_mode() == EditorFileDialog::MODE_SAVE_FILE) {
|
||||||
|
|
||||||
//_save_scene(p_file);
|
//_save_scene(p_file);
|
||||||
|
_save_default_environment();
|
||||||
_save_scene_with_preview(p_file);
|
_save_scene_with_preview(p_file);
|
||||||
_call_build();
|
_call_build();
|
||||||
_run(true);
|
_run(true);
|
||||||
@ -1375,6 +1378,17 @@ void EditorNode::_property_editor_back() {
|
|||||||
_edit_current();
|
_edit_current();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorNode::_save_default_environment() {
|
||||||
|
|
||||||
|
Ref<Environment> fallback = get_scene_root()->get_world()->get_fallback_environment();
|
||||||
|
|
||||||
|
if (fallback.is_valid() && fallback->get_path().is_resource_file()) {
|
||||||
|
Map<RES, bool> processed;
|
||||||
|
_find_and_save_edited_subresources(fallback.ptr(), processed, 0);
|
||||||
|
save_resource_in_path(fallback, fallback->get_path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EditorNode::_imported(Node *p_node) {
|
void EditorNode::_imported(Node *p_node) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1453,11 +1467,16 @@ void EditorNode::_edit_current() {
|
|||||||
|
|
||||||
Node *current_node = current_obj->cast_to<Node>();
|
Node *current_node = current_obj->cast_to<Node>();
|
||||||
ERR_FAIL_COND(!current_node);
|
ERR_FAIL_COND(!current_node);
|
||||||
ERR_FAIL_COND(!current_node->is_inside_tree());
|
// ERR_FAIL_COND(!current_node->is_inside_tree());
|
||||||
|
|
||||||
property_editor->edit(current_node);
|
property_editor->edit(current_node);
|
||||||
|
if (current_node->is_inside_tree()) {
|
||||||
node_dock->set_node(current_node);
|
node_dock->set_node(current_node);
|
||||||
scene_tree_dock->set_selected(current_node);
|
scene_tree_dock->set_selected(current_node);
|
||||||
|
} else {
|
||||||
|
node_dock->set_node(NULL);
|
||||||
|
scene_tree_dock->set_selected(NULL);
|
||||||
|
}
|
||||||
object_menu->get_popup()->clear();
|
object_menu->get_popup()->clear();
|
||||||
|
|
||||||
//top_pallete->set_current_tab(0);
|
//top_pallete->set_current_tab(0);
|
||||||
@ -1951,6 +1970,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
|
|||||||
}
|
}
|
||||||
} // else: ignore new scenes
|
} // else: ignore new scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_save_default_environment();
|
||||||
} break;
|
} break;
|
||||||
case FILE_SAVE_BEFORE_RUN: {
|
case FILE_SAVE_BEFORE_RUN: {
|
||||||
if (!p_confirmed) {
|
if (!p_confirmed) {
|
||||||
@ -2384,6 +2405,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
|
|||||||
|
|
||||||
} break;
|
} break;
|
||||||
case RUN_PLAY_SCENE: {
|
case RUN_PLAY_SCENE: {
|
||||||
|
|
||||||
|
_save_default_environment();
|
||||||
_menu_option_confirm(RUN_STOP, true);
|
_menu_option_confirm(RUN_STOP, true);
|
||||||
_call_build();
|
_call_build();
|
||||||
_run(true);
|
_run(true);
|
||||||
@ -5237,6 +5260,7 @@ EditorNode::EditorNode() {
|
|||||||
p->add_separator();
|
p->add_separator();
|
||||||
p->add_item(TTR("Project Settings"), RUN_SETTINGS);
|
p->add_item(TTR("Project Settings"), RUN_SETTINGS);
|
||||||
p->add_separator();
|
p->add_separator();
|
||||||
|
|
||||||
#ifdef OSX_ENABLED
|
#ifdef OSX_ENABLED
|
||||||
p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q);
|
p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q);
|
||||||
#else
|
#else
|
||||||
|
@ -593,6 +593,7 @@ private:
|
|||||||
|
|
||||||
static int plugin_init_callback_count;
|
static int plugin_init_callback_count;
|
||||||
static EditorPluginInitializeCallback plugin_init_callbacks[MAX_INIT_CALLBACKS];
|
static EditorPluginInitializeCallback plugin_init_callbacks[MAX_INIT_CALLBACKS];
|
||||||
|
void _save_default_environment();
|
||||||
|
|
||||||
void _call_build();
|
void _call_build();
|
||||||
static int build_callback_count;
|
static int build_callback_count;
|
||||||
|
@ -46,10 +46,10 @@ ColorRampEditorPlugin::ColorRampEditorPlugin(EditorNode *p_node) {
|
|||||||
|
|
||||||
void ColorRampEditorPlugin::edit(Object *p_object) {
|
void ColorRampEditorPlugin::edit(Object *p_object) {
|
||||||
|
|
||||||
ColorRamp *color_ramp = p_object->cast_to<ColorRamp>();
|
Gradient *color_ramp = p_object->cast_to<Gradient>();
|
||||||
if (!color_ramp)
|
if (!color_ramp)
|
||||||
return;
|
return;
|
||||||
color_ramp_ref = Ref<ColorRamp>(color_ramp);
|
color_ramp_ref = Ref<Gradient>(color_ramp);
|
||||||
ramp_editor->set_points(color_ramp_ref->get_points());
|
ramp_editor->set_points(color_ramp_ref->get_points());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ class ColorRampEditorPlugin : public EditorPlugin {
|
|||||||
GDCLASS(ColorRampEditorPlugin, EditorPlugin);
|
GDCLASS(ColorRampEditorPlugin, EditorPlugin);
|
||||||
|
|
||||||
bool _2d;
|
bool _2d;
|
||||||
Ref<ColorRamp> color_ramp_ref;
|
Ref<Gradient> color_ramp_ref;
|
||||||
ColorRampEdit *ramp_editor;
|
ColorRampEdit *ramp_editor;
|
||||||
EditorNode *editor;
|
EditorNode *editor;
|
||||||
|
|
||||||
|
@ -2493,17 +2493,11 @@ Dictionary SpatialEditor::get_state() const {
|
|||||||
|
|
||||||
d["viewports"] = vpdata;
|
d["viewports"] = vpdata;
|
||||||
|
|
||||||
d["default_light"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_LIGHT));
|
|
||||||
d["ambient_light_color"] = settings_ambient_color->get_pick_color();
|
|
||||||
|
|
||||||
d["default_srgb"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_SRGB));
|
|
||||||
d["show_grid"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_GRID));
|
d["show_grid"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_GRID));
|
||||||
d["show_origin"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN));
|
d["show_origin"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN));
|
||||||
d["fov"] = get_fov();
|
d["fov"] = get_fov();
|
||||||
d["znear"] = get_znear();
|
d["znear"] = get_znear();
|
||||||
d["zfar"] = get_zfar();
|
d["zfar"] = get_zfar();
|
||||||
d["deflight_rot_x"] = settings_default_light_rot_x;
|
|
||||||
d["deflight_rot_y"] = settings_default_light_rot_y;
|
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
@ -2565,26 +2559,6 @@ void SpatialEditor::set_state(const Dictionary &p_state) {
|
|||||||
if (d.has("fov"))
|
if (d.has("fov"))
|
||||||
settings_fov->set_value(float(d["fov"]));
|
settings_fov->set_value(float(d["fov"]));
|
||||||
|
|
||||||
if (d.has("default_light")) {
|
|
||||||
bool use = d["default_light"];
|
|
||||||
|
|
||||||
bool existing = light_instance.is_valid();
|
|
||||||
if (use != existing) {
|
|
||||||
if (existing) {
|
|
||||||
VisualServer::get_singleton()->free(light_instance);
|
|
||||||
light_instance = RID();
|
|
||||||
} else {
|
|
||||||
light_instance = VisualServer::get_singleton()->instance_create2(light, get_tree()->get_root()->get_world()->get_scenario());
|
|
||||||
VisualServer::get_singleton()->instance_set_transform(light_instance, light_transform);
|
|
||||||
}
|
|
||||||
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_LIGHT), light_instance.is_valid());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (d.has("ambient_light_color")) {
|
|
||||||
settings_ambient_color->set_pick_color(d["ambient_light_color"]);
|
|
||||||
//viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,d["ambient_light_color"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d.has("default_srgb")) {
|
if (d.has("default_srgb")) {
|
||||||
bool use = d["default_srgb"];
|
bool use = d["default_srgb"];
|
||||||
|
|
||||||
@ -2607,13 +2581,6 @@ void SpatialEditor::set_state(const Dictionary &p_state) {
|
|||||||
VisualServer::get_singleton()->instance_set_visible(origin_instance, use);
|
VisualServer::get_singleton()->instance_set_visible(origin_instance, use);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d.has("deflight_rot_x"))
|
|
||||||
settings_default_light_rot_x = d["deflight_rot_x"];
|
|
||||||
if (d.has("deflight_rot_y"))
|
|
||||||
settings_default_light_rot_y = d["deflight_rot_y"];
|
|
||||||
|
|
||||||
_update_default_light_angle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpatialEditor::edit(Spatial *p_spatial) {
|
void SpatialEditor::edit(Spatial *p_spatial) {
|
||||||
@ -2749,38 +2716,6 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
|
|||||||
|
|
||||||
xform_dialog->popup_centered(Size2(200, 200));
|
xform_dialog->popup_centered(Size2(200, 200));
|
||||||
|
|
||||||
} break;
|
|
||||||
case MENU_VIEW_USE_DEFAULT_LIGHT: {
|
|
||||||
|
|
||||||
bool is_checked = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(p_option));
|
|
||||||
|
|
||||||
if (is_checked) {
|
|
||||||
VisualServer::get_singleton()->free(light_instance);
|
|
||||||
light_instance = RID();
|
|
||||||
} else {
|
|
||||||
light_instance = VisualServer::get_singleton()->instance_create2(light, get_tree()->get_root()->get_world()->get_scenario());
|
|
||||||
VisualServer::get_singleton()->instance_set_transform(light_instance, light_transform);
|
|
||||||
|
|
||||||
_update_default_light_angle();
|
|
||||||
}
|
|
||||||
|
|
||||||
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(p_option), light_instance.is_valid());
|
|
||||||
|
|
||||||
} break;
|
|
||||||
case MENU_VIEW_USE_DEFAULT_SRGB: {
|
|
||||||
|
|
||||||
bool is_checked = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(p_option));
|
|
||||||
|
|
||||||
if (is_checked) {
|
|
||||||
//viewport_environment->set_enable_fx(Environment::FX_SRGB,false);
|
|
||||||
} else {
|
|
||||||
//viewport_environment->set_enable_fx(Environment::FX_SRGB,true);
|
|
||||||
}
|
|
||||||
|
|
||||||
is_checked = !is_checked;
|
|
||||||
|
|
||||||
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(p_option), is_checked);
|
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case MENU_VIEW_USE_1_VIEWPORT: {
|
case MENU_VIEW_USE_1_VIEWPORT: {
|
||||||
|
|
||||||
@ -2993,14 +2928,6 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
|
|||||||
|
|
||||||
void SpatialEditor::_init_indicators() {
|
void SpatialEditor::_init_indicators() {
|
||||||
|
|
||||||
//make sure that the camera indicator is not selectable
|
|
||||||
light = VisualServer::get_singleton()->light_create(VisualServer::LIGHT_DIRECTIONAL);
|
|
||||||
//VisualServer::get_singleton()->light_set_shadow( light, true );
|
|
||||||
light_instance = VisualServer::get_singleton()->instance_create2(light, get_tree()->get_root()->get_world()->get_scenario());
|
|
||||||
|
|
||||||
light_transform.rotate(Vector3(1, 0, 0), -Math_PI / 5.0);
|
|
||||||
VisualServer::get_singleton()->instance_set_transform(light_instance, light_transform);
|
|
||||||
|
|
||||||
//RID mat = VisualServer::get_singleton()->fixed_material_create();
|
//RID mat = VisualServer::get_singleton()->fixed_material_create();
|
||||||
///VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA,true);
|
///VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA,true);
|
||||||
//VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true);
|
//VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true);
|
||||||
@ -3258,8 +3185,6 @@ void SpatialEditor::_finish_indicators() {
|
|||||||
VisualServer::get_singleton()->free(grid_instance[i]);
|
VisualServer::get_singleton()->free(grid_instance[i]);
|
||||||
VisualServer::get_singleton()->free(grid[i]);
|
VisualServer::get_singleton()->free(grid[i]);
|
||||||
}
|
}
|
||||||
VisualServer::get_singleton()->free(light_instance);
|
|
||||||
VisualServer::get_singleton()->free(light);
|
|
||||||
//VisualServer::get_singleton()->free(poly);
|
//VisualServer::get_singleton()->free(poly);
|
||||||
//VisualServer::get_singleton()->free(indicators_instance);
|
//VisualServer::get_singleton()->free(indicators_instance);
|
||||||
//VisualServer::get_singleton()->free(indicators);
|
//VisualServer::get_singleton()->free(indicators);
|
||||||
@ -3351,14 +3276,12 @@ void SpatialEditor::_notification(int p_what) {
|
|||||||
_menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT);
|
_menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT);
|
||||||
|
|
||||||
get_tree()->connect("node_removed", this, "_node_removed");
|
get_tree()->connect("node_removed", this, "_node_removed");
|
||||||
VS::get_singleton()->scenario_set_fallback_environment(get_viewport()->find_world()->get_scenario(), viewport_environment->get_rid());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_what == NOTIFICATION_ENTER_TREE) {
|
if (p_what == NOTIFICATION_ENTER_TREE) {
|
||||||
|
|
||||||
gizmos = memnew(SpatialEditorGizmos);
|
gizmos = memnew(SpatialEditorGizmos);
|
||||||
_init_indicators();
|
_init_indicators();
|
||||||
_update_default_light_angle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_what == NOTIFICATION_EXIT_TREE) {
|
if (p_what == NOTIFICATION_EXIT_TREE) {
|
||||||
@ -3481,8 +3404,6 @@ void SpatialEditor::_bind_methods() {
|
|||||||
ClassDB::bind_method("_xform_dialog_action", &SpatialEditor::_xform_dialog_action);
|
ClassDB::bind_method("_xform_dialog_action", &SpatialEditor::_xform_dialog_action);
|
||||||
ClassDB::bind_method("_get_editor_data", &SpatialEditor::_get_editor_data);
|
ClassDB::bind_method("_get_editor_data", &SpatialEditor::_get_editor_data);
|
||||||
ClassDB::bind_method("_request_gizmo", &SpatialEditor::_request_gizmo);
|
ClassDB::bind_method("_request_gizmo", &SpatialEditor::_request_gizmo);
|
||||||
ClassDB::bind_method("_default_light_angle_input", &SpatialEditor::_default_light_angle_input);
|
|
||||||
ClassDB::bind_method("_update_ambient_light_color", &SpatialEditor::_update_ambient_light_color);
|
|
||||||
ClassDB::bind_method("_toggle_maximize_view", &SpatialEditor::_toggle_maximize_view);
|
ClassDB::bind_method("_toggle_maximize_view", &SpatialEditor::_toggle_maximize_view);
|
||||||
|
|
||||||
ADD_SIGNAL(MethodInfo("transform_key_request"));
|
ADD_SIGNAL(MethodInfo("transform_key_request"));
|
||||||
@ -3517,43 +3438,6 @@ void SpatialEditor::clear() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_GRID), true);
|
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_GRID), true);
|
||||||
|
|
||||||
settings_default_light_rot_x = Math_PI * 0.3;
|
|
||||||
settings_default_light_rot_y = Math_PI * 0.2;
|
|
||||||
|
|
||||||
//viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,Color(0.15,0.15,0.15));
|
|
||||||
settings_ambient_color->set_pick_color(Color(0.15, 0.15, 0.15));
|
|
||||||
if (!light_instance.is_valid())
|
|
||||||
_menu_item_pressed(MENU_VIEW_USE_DEFAULT_LIGHT);
|
|
||||||
|
|
||||||
_update_default_light_angle();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpatialEditor::_update_ambient_light_color(const Color &p_color) {
|
|
||||||
|
|
||||||
//viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,settings_ambient_color->get_color());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpatialEditor::_update_default_light_angle() {
|
|
||||||
|
|
||||||
Transform t;
|
|
||||||
t.basis.rotate(Vector3(1, 0, 0), -settings_default_light_rot_x);
|
|
||||||
t.basis.rotate(Vector3(0, 1, 0), -settings_default_light_rot_y);
|
|
||||||
settings_dlight->set_transform(t);
|
|
||||||
if (light_instance.is_valid()) {
|
|
||||||
VS::get_singleton()->instance_set_transform(light_instance, t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpatialEditor::_default_light_angle_input(const Ref<InputEvent> &p_event) {
|
|
||||||
|
|
||||||
Ref<InputEventMouseMotion> mm = p_event;
|
|
||||||
if (mm.is_valid() && mm->get_button_mask() & (0x1 | 0x2 | 0x4)) {
|
|
||||||
|
|
||||||
settings_default_light_rot_y = Math::fposmod(settings_default_light_rot_y - mm->get_relative().x * 0.01, Math_PI * 2.0);
|
|
||||||
settings_default_light_rot_x = Math::fposmod(settings_default_light_rot_x - mm->get_relative().y * 0.01, Math_PI * 2.0);
|
|
||||||
_update_default_light_angle();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SpatialEditor::SpatialEditor(EditorNode *p_editor) {
|
SpatialEditor::SpatialEditor(EditorNode *p_editor) {
|
||||||
@ -3674,10 +3558,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
|
|||||||
|
|
||||||
p = view_menu->get_popup();
|
p = view_menu->get_popup();
|
||||||
|
|
||||||
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/use_default_light", TTR("Use Default Light")), MENU_VIEW_USE_DEFAULT_LIGHT);
|
|
||||||
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/use_default_srgb", TTR("Use Default sRGB")), MENU_VIEW_USE_DEFAULT_SRGB);
|
|
||||||
p->add_separator();
|
|
||||||
|
|
||||||
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/1_viewport", TTR("1 Viewport"), KEY_MASK_CMD + KEY_1), MENU_VIEW_USE_1_VIEWPORT);
|
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/1_viewport", TTR("1 Viewport"), KEY_MASK_CMD + KEY_1), MENU_VIEW_USE_1_VIEWPORT);
|
||||||
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports", TTR("2 Viewports"), KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS);
|
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports", TTR("2 Viewports"), KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS);
|
||||||
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports_alt", TTR("2 Viewports (Alt)"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS_ALT);
|
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports_alt", TTR("2 Viewports (Alt)"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS_ALT);
|
||||||
@ -3696,7 +3576,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
|
|||||||
p->add_separator();
|
p->add_separator();
|
||||||
p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings")), MENU_VIEW_CAMERA_SETTINGS);
|
p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings")), MENU_VIEW_CAMERA_SETTINGS);
|
||||||
|
|
||||||
p->set_item_checked(p->get_item_index(MENU_VIEW_USE_DEFAULT_LIGHT), true);
|
|
||||||
p->set_item_checked(p->get_item_index(MENU_VIEW_DISPLAY_NORMAL), true);
|
p->set_item_checked(p->get_item_index(MENU_VIEW_DISPLAY_NORMAL), true);
|
||||||
p->set_item_checked(p->get_item_index(MENU_VIEW_ORIGIN), true);
|
p->set_item_checked(p->get_item_index(MENU_VIEW_ORIGIN), true);
|
||||||
p->set_item_checked(p->get_item_index(MENU_VIEW_GRID), true);
|
p->set_item_checked(p->get_item_index(MENU_VIEW_GRID), true);
|
||||||
@ -3755,36 +3634,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
|
|||||||
settings_dialog->add_child(settings_vbc);
|
settings_dialog->add_child(settings_vbc);
|
||||||
//settings_dialog->set_child_rect(settings_vbc);
|
//settings_dialog->set_child_rect(settings_vbc);
|
||||||
|
|
||||||
settings_light_base = memnew(ViewportContainer);
|
|
||||||
settings_light_base->set_custom_minimum_size(Size2(128, 128));
|
|
||||||
settings_light_base->connect("gui_input", this, "_default_light_angle_input");
|
|
||||||
settings_vbc->add_margin_child(TTR("Default Light Normal:"), settings_light_base);
|
|
||||||
settings_light_vp = memnew(Viewport);
|
|
||||||
settings_light_vp->set_disable_input(true);
|
|
||||||
settings_light_vp->set_use_own_world(true);
|
|
||||||
settings_light_base->add_child(settings_light_vp);
|
|
||||||
|
|
||||||
settings_dlight = memnew(DirectionalLight);
|
|
||||||
settings_light_vp->add_child(settings_dlight);
|
|
||||||
settings_sphere = memnew(ImmediateGeometry);
|
|
||||||
settings_sphere->begin(Mesh::PRIMITIVE_TRIANGLES, Ref<Texture>());
|
|
||||||
settings_sphere->set_color(Color(1, 1, 1));
|
|
||||||
settings_sphere->add_sphere(32, 16, 1);
|
|
||||||
settings_sphere->end();
|
|
||||||
settings_light_vp->add_child(settings_sphere);
|
|
||||||
settings_camera = memnew(Camera);
|
|
||||||
settings_light_vp->add_child(settings_camera);
|
|
||||||
settings_camera->set_translation(Vector3(0, 0, 2));
|
|
||||||
settings_camera->set_orthogonal(2.1, 0.1, 5);
|
|
||||||
|
|
||||||
settings_default_light_rot_x = Math_PI * 0.3;
|
|
||||||
settings_default_light_rot_y = Math_PI * 0.2;
|
|
||||||
|
|
||||||
settings_ambient_color = memnew(ColorPickerButton);
|
|
||||||
settings_vbc->add_margin_child(TTR("Ambient Light Color:"), settings_ambient_color);
|
|
||||||
settings_ambient_color->connect("color_changed", this, "_update_ambient_light_color");
|
|
||||||
settings_ambient_color->set_pick_color(Color(0.15, 0.15, 0.15));
|
|
||||||
|
|
||||||
settings_fov = memnew(SpinBox);
|
settings_fov = memnew(SpinBox);
|
||||||
settings_fov->set_max(179);
|
settings_fov->set_max(179);
|
||||||
settings_fov->set_min(1);
|
settings_fov->set_min(1);
|
||||||
|
@ -321,10 +321,6 @@ private:
|
|||||||
|
|
||||||
VisualServer::ScenarioDebugMode scenario_debug;
|
VisualServer::ScenarioDebugMode scenario_debug;
|
||||||
|
|
||||||
RID light;
|
|
||||||
RID light_instance;
|
|
||||||
Transform light_transform;
|
|
||||||
|
|
||||||
RID origin;
|
RID origin;
|
||||||
RID origin_instance;
|
RID origin_instance;
|
||||||
RID grid[3];
|
RID grid[3];
|
||||||
@ -383,8 +379,6 @@ private:
|
|||||||
MENU_VIEW_USE_3_VIEWPORTS,
|
MENU_VIEW_USE_3_VIEWPORTS,
|
||||||
MENU_VIEW_USE_3_VIEWPORTS_ALT,
|
MENU_VIEW_USE_3_VIEWPORTS_ALT,
|
||||||
MENU_VIEW_USE_4_VIEWPORTS,
|
MENU_VIEW_USE_4_VIEWPORTS,
|
||||||
MENU_VIEW_USE_DEFAULT_LIGHT,
|
|
||||||
MENU_VIEW_USE_DEFAULT_SRGB,
|
|
||||||
MENU_VIEW_DISPLAY_NORMAL,
|
MENU_VIEW_DISPLAY_NORMAL,
|
||||||
MENU_VIEW_DISPLAY_WIREFRAME,
|
MENU_VIEW_DISPLAY_WIREFRAME,
|
||||||
MENU_VIEW_DISPLAY_OVERDRAW,
|
MENU_VIEW_DISPLAY_OVERDRAW,
|
||||||
@ -419,16 +413,6 @@ private:
|
|||||||
SpinBox *settings_fov;
|
SpinBox *settings_fov;
|
||||||
SpinBox *settings_znear;
|
SpinBox *settings_znear;
|
||||||
SpinBox *settings_zfar;
|
SpinBox *settings_zfar;
|
||||||
DirectionalLight *settings_dlight;
|
|
||||||
ImmediateGeometry *settings_sphere;
|
|
||||||
Camera *settings_camera;
|
|
||||||
float settings_default_light_rot_x;
|
|
||||||
float settings_default_light_rot_y;
|
|
||||||
|
|
||||||
ViewportContainer *settings_light_base;
|
|
||||||
Viewport *settings_light_vp;
|
|
||||||
ColorPickerButton *settings_ambient_color;
|
|
||||||
Ref<Image> settings_light_dir_image;
|
|
||||||
|
|
||||||
void _xform_dialog_action();
|
void _xform_dialog_action();
|
||||||
void _menu_item_pressed(int p_option);
|
void _menu_item_pressed(int p_option);
|
||||||
@ -462,10 +446,6 @@ private:
|
|||||||
SpatialEditorGizmos *gizmos;
|
SpatialEditorGizmos *gizmos;
|
||||||
SpatialEditor();
|
SpatialEditor();
|
||||||
|
|
||||||
void _update_ambient_light_color(const Color &p_color);
|
|
||||||
void _update_default_light_angle();
|
|
||||||
void _default_light_angle_input(const Ref<InputEvent> &p_event);
|
|
||||||
|
|
||||||
bool is_any_freelook_active() const;
|
bool is_any_freelook_active() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -203,10 +203,23 @@ private:
|
|||||||
f->store_line("\n");
|
f->store_line("\n");
|
||||||
f->store_line("name=\"" + project_name->get_text() + "\"");
|
f->store_line("name=\"" + project_name->get_text() + "\"");
|
||||||
f->store_line("icon=\"res://icon.png\"");
|
f->store_line("icon=\"res://icon.png\"");
|
||||||
|
f->store_line("[rendering]");
|
||||||
|
f->store_line("viewport/default_environment=\"res://default_env.tres\"");
|
||||||
memdelete(f);
|
memdelete(f);
|
||||||
|
|
||||||
ResourceSaver::save(dir.plus_file("/icon.png"), get_icon("DefaultProjectIcon", "EditorIcons"));
|
ResourceSaver::save(dir.plus_file("/icon.png"), get_icon("DefaultProjectIcon", "EditorIcons"));
|
||||||
|
|
||||||
|
f = FileAccess::open(dir.plus_file("/default_env.tres"), FileAccess::WRITE);
|
||||||
|
if (!f) {
|
||||||
|
error->set_text(TTR("Couldn't create project.godot in project path."));
|
||||||
|
} else {
|
||||||
|
f->store_line("[gd_resource type=\"Environment\" load_steps=2 format=2]");
|
||||||
|
f->store_line("[sub_resource type=\"ProceduralSky\" id=1]");
|
||||||
|
f->store_line("[resource]");
|
||||||
|
f->store_line("background_mode = 2");
|
||||||
|
f->store_line("background_sky = SubResource( 1 )");
|
||||||
|
memdelete(f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (mode == MODE_INSTALL) {
|
} else if (mode == MODE_INSTALL) {
|
||||||
|
@ -462,6 +462,59 @@ uint32_t ihash3(uint32_t a) {
|
|||||||
|
|
||||||
MainLoop *test() {
|
MainLoop *test() {
|
||||||
|
|
||||||
|
{
|
||||||
|
float r = 1;
|
||||||
|
float g = 0.5;
|
||||||
|
float b = 0.1;
|
||||||
|
|
||||||
|
const float pow2to9 = 512.0f;
|
||||||
|
const float B = 15.0f;
|
||||||
|
//const float Emax = 31.0f;
|
||||||
|
const float N = 9.0f;
|
||||||
|
|
||||||
|
float sharedexp = 65408.000f; //(( pow2to9 - 1.0f)/ pow2to9)*powf( 2.0f, 31.0f - 15.0f);
|
||||||
|
|
||||||
|
float cRed = MAX(0.0f, MIN(sharedexp, r));
|
||||||
|
float cGreen = MAX(0.0f, MIN(sharedexp, g));
|
||||||
|
float cBlue = MAX(0.0f, MIN(sharedexp, b));
|
||||||
|
|
||||||
|
float cMax = MAX(cRed, MAX(cGreen, cBlue));
|
||||||
|
|
||||||
|
// expp = MAX(-B - 1, log2(maxc)) + 1 + B
|
||||||
|
|
||||||
|
float expp = MAX(-B - 1.0f, floor(Math::log(cMax) / Math_LN2)) + 1.0f + B;
|
||||||
|
|
||||||
|
float sMax = (float)floor((cMax / Math::pow(2.0f, expp - B - N)) + 0.5f);
|
||||||
|
|
||||||
|
float exps = expp + 1.0f;
|
||||||
|
|
||||||
|
if (0.0 <= sMax && sMax < pow2to9) {
|
||||||
|
exps = expp;
|
||||||
|
}
|
||||||
|
|
||||||
|
float sRed = Math::floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
|
||||||
|
float sGreen = Math::floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
|
||||||
|
float sBlue = Math::floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
|
||||||
|
|
||||||
|
print_line("R: " + rtos(sRed) + " G: " + rtos(sGreen) + " B: " + rtos(sBlue) + " EXP: " + rtos(exps));
|
||||||
|
|
||||||
|
uint32_t rgbe = (Math::fast_ftoi(sRed) & 0x1FF) | ((Math::fast_ftoi(sGreen) & 0x1FF) << 9) | ((Math::fast_ftoi(sBlue) & 0x1FF) << 18) | ((Math::fast_ftoi(exps) & 0x1F) << 27);
|
||||||
|
|
||||||
|
float rb = rgbe & 0x1ff;
|
||||||
|
float gb = (rgbe >> 9) & 0x1ff;
|
||||||
|
float bb = (rgbe >> 18) & 0x1ff;
|
||||||
|
float eb = (rgbe >> 27);
|
||||||
|
float mb = Math::pow(2, eb - 15.0 - 9.0);
|
||||||
|
;
|
||||||
|
float rd = rb * mb;
|
||||||
|
float gd = gb * mb;
|
||||||
|
float bd = bb * mb;
|
||||||
|
|
||||||
|
print_line("RGBE: " + Color(rd, gd, bd));
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
print_line("Dvectors: " + itos(MemoryPool::allocs_used));
|
print_line("Dvectors: " + itos(MemoryPool::allocs_used));
|
||||||
print_line("Mem used: " + itos(MemoryPool::total_memory));
|
print_line("Mem used: " + itos(MemoryPool::total_memory));
|
||||||
print_line("MAx mem used: " + itos(MemoryPool::max_memory));
|
print_line("MAx mem used: " + itos(MemoryPool::max_memory));
|
||||||
|
9
modules/hdr/SCsub
Normal file
9
modules/hdr/SCsub
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
Import('env')
|
||||||
|
Import('env_modules')
|
||||||
|
|
||||||
|
env_hdr = env_modules.Clone()
|
||||||
|
|
||||||
|
# Godot's own source files
|
||||||
|
env_hdr.add_source_files(env.modules_sources, "*.cpp")
|
7
modules/hdr/config.py
Normal file
7
modules/hdr/config.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
def can_build(platform):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def configure(env):
|
||||||
|
pass
|
151
modules/hdr/image_loader_hdr.cpp
Normal file
151
modules/hdr/image_loader_hdr.cpp
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/*************************************************************************/
|
||||||
|
/* image_loader_jpegd.cpp */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* http://www.godotengine.org */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/*************************************************************************/
|
||||||
|
#include "image_loader_hdr.h"
|
||||||
|
|
||||||
|
#include "os/os.h"
|
||||||
|
#include "print_string.h"
|
||||||
|
|
||||||
|
#include "thirdparty/tinyexr/tinyexr.h"
|
||||||
|
|
||||||
|
Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f) {
|
||||||
|
|
||||||
|
String header = f->get_token();
|
||||||
|
|
||||||
|
print_line("HEADER: " + header);
|
||||||
|
ERR_FAIL_COND_V(header != "#?RADIANCE", ERR_FILE_UNRECOGNIZED);
|
||||||
|
|
||||||
|
String format = f->get_token();
|
||||||
|
print_line("FORMAT: " + format);
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(format != "FORMAT=32-bit_rle_rgbe", ERR_FILE_UNRECOGNIZED);
|
||||||
|
|
||||||
|
String token = f->get_token();
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(token != "-Y", ERR_FILE_CORRUPT);
|
||||||
|
|
||||||
|
int height = f->get_token().to_int();
|
||||||
|
|
||||||
|
token = f->get_token();
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(token != "+X", ERR_FILE_CORRUPT);
|
||||||
|
|
||||||
|
int width = f->get_line().to_int();
|
||||||
|
|
||||||
|
print_line("HDR w: " + itos(width) + " h:" + itos(height));
|
||||||
|
|
||||||
|
PoolVector<uint8_t> imgdata;
|
||||||
|
|
||||||
|
imgdata.resize(height * width * sizeof(uint32_t));
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
PoolVector<uint8_t>::Write w = imgdata.write();
|
||||||
|
|
||||||
|
uint8_t *ptr = (uint8_t *)w.ptr();
|
||||||
|
|
||||||
|
if (width < 8 || width >= 32768) {
|
||||||
|
// Read flat data
|
||||||
|
|
||||||
|
f->get_buffer(ptr, width * height * 4);
|
||||||
|
} else {
|
||||||
|
// Read RLE-encoded data
|
||||||
|
|
||||||
|
for (int j = 0; j < height; ++j) {
|
||||||
|
int c1 = f->get_8();
|
||||||
|
int c2 = f->get_8();
|
||||||
|
int len = f->get_8();
|
||||||
|
if (c1 != 2 || c2 != 2 || (len & 0x80)) {
|
||||||
|
// not run-length encoded, so we have to actually use THIS data as a decoded
|
||||||
|
// pixel (note this can't be a valid pixel--one of RGB must be >= 128)
|
||||||
|
|
||||||
|
ptr[(j * width) * 4 + 0] = uint8_t(c1);
|
||||||
|
ptr[(j * width) * 4 + 1] = uint8_t(c2);
|
||||||
|
ptr[(j * width) * 4 + 2] = uint8_t(len);
|
||||||
|
ptr[(j * width) * 4 + 3] = f->get_8();
|
||||||
|
|
||||||
|
f->get_buffer(&ptr[(j * width + 1) * 4], (width - 1) * 4);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
len <<= 8;
|
||||||
|
len |= f->get_8();
|
||||||
|
|
||||||
|
print_line("line: " + itos(len));
|
||||||
|
if (len != width) {
|
||||||
|
ERR_EXPLAIN("invalid decoded scanline length, corrupt HDR");
|
||||||
|
ERR_FAIL_V(ERR_FILE_CORRUPT);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int k = 0; k < 4; ++k) {
|
||||||
|
int i = 0;
|
||||||
|
while (i < width) {
|
||||||
|
int count = f->get_8();
|
||||||
|
if (count > 128) {
|
||||||
|
// Run
|
||||||
|
int value = f->get_8();
|
||||||
|
count -= 128;
|
||||||
|
for (int z = 0; z < count; ++z)
|
||||||
|
ptr[(j * width + i++) * 4 + k] = uint8_t(value);
|
||||||
|
} else {
|
||||||
|
// Dump
|
||||||
|
for (int z = 0; z < count; ++z)
|
||||||
|
ptr[(j * width + i++) * 4 + k] = f->get_8();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//convert
|
||||||
|
for (int i = 0; i < width * height; i++) {
|
||||||
|
|
||||||
|
float exp = pow(2, ptr[3] - 128);
|
||||||
|
|
||||||
|
Color c(
|
||||||
|
ptr[0] * exp / 255.0,
|
||||||
|
ptr[1] * exp / 255.0,
|
||||||
|
ptr[2] * exp / 255.0);
|
||||||
|
|
||||||
|
*(uint32_t *)ptr = c.to_rgbe9995();
|
||||||
|
ptr += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p_image->create(width, height, false, Image::FORMAT_RGBE9995, imgdata);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageLoaderHDR::get_recognized_extensions(List<String> *p_extensions) const {
|
||||||
|
|
||||||
|
p_extensions->push_back("hdr");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageLoaderHDR::ImageLoaderHDR() {
|
||||||
|
}
|
46
modules/hdr/image_loader_hdr.h
Normal file
46
modules/hdr/image_loader_hdr.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*************************************************************************/
|
||||||
|
/* image_loader_jpegd.h */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* http://www.godotengine.org */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/*************************************************************************/
|
||||||
|
#ifndef IMAGE_LOADER_TINYEXR_H
|
||||||
|
#define IMAGE_LOADER_TINYEXR_H
|
||||||
|
|
||||||
|
#include "io/image_loader.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
@author Juan Linietsky <reduzio@gmail.com>
|
||||||
|
*/
|
||||||
|
class ImageLoaderHDR : public ImageFormatLoader {
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual Error load_image(Ref<Image> p_image, FileAccess *f);
|
||||||
|
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||||
|
ImageLoaderHDR();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
45
modules/hdr/register_types.cpp
Normal file
45
modules/hdr/register_types.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*************************************************************************/
|
||||||
|
/* register_types.cpp */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* http://www.godotengine.org */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/*************************************************************************/
|
||||||
|
#include "register_types.h"
|
||||||
|
|
||||||
|
#include "image_loader_hdr.h"
|
||||||
|
|
||||||
|
static ImageLoaderHDR *image_loader_hdr = NULL;
|
||||||
|
|
||||||
|
void register_hdr_types() {
|
||||||
|
|
||||||
|
image_loader_hdr = memnew(ImageLoaderHDR);
|
||||||
|
ImageLoader::add_image_format_loader(image_loader_hdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unregister_hdr_types() {
|
||||||
|
|
||||||
|
memdelete(image_loader_hdr);
|
||||||
|
}
|
31
modules/hdr/register_types.h
Normal file
31
modules/hdr/register_types.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*************************************************************************/
|
||||||
|
/* register_types.h */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* http://www.godotengine.org */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/*************************************************************************/
|
||||||
|
void register_hdr_types();
|
||||||
|
void unregister_hdr_types();
|
@ -99,7 +99,7 @@ Color Line2D::get_default_color() const {
|
|||||||
return _default_color;
|
return _default_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Line2D::set_gradient(const Ref<ColorRamp> &gradient) {
|
void Line2D::set_gradient(const Ref<Gradient> &gradient) {
|
||||||
|
|
||||||
// Cleanup previous connection if any
|
// Cleanup previous connection if any
|
||||||
if (_gradient.is_valid()) {
|
if (_gradient.is_valid()) {
|
||||||
@ -116,7 +116,7 @@ void Line2D::set_gradient(const Ref<ColorRamp> &gradient) {
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<ColorRamp> Line2D::get_gradient() const {
|
Ref<Gradient> Line2D::get_gradient() const {
|
||||||
return _gradient;
|
return _gradient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,8 +57,8 @@ public:
|
|||||||
void set_default_color(Color color);
|
void set_default_color(Color color);
|
||||||
Color get_default_color() const;
|
Color get_default_color() const;
|
||||||
|
|
||||||
void set_gradient(const Ref<ColorRamp> &gradient);
|
void set_gradient(const Ref<Gradient> &gradient);
|
||||||
Ref<ColorRamp> get_gradient() const;
|
Ref<Gradient> get_gradient() const;
|
||||||
|
|
||||||
void set_texture(const Ref<Texture> &texture);
|
void set_texture(const Ref<Texture> &texture);
|
||||||
Ref<Texture> get_texture() const;
|
Ref<Texture> get_texture() const;
|
||||||
@ -97,7 +97,7 @@ private:
|
|||||||
LineCapMode _end_cap_mode;
|
LineCapMode _end_cap_mode;
|
||||||
float _width;
|
float _width;
|
||||||
Color _default_color;
|
Color _default_color;
|
||||||
Ref<ColorRamp> _gradient;
|
Ref<Gradient> _gradient;
|
||||||
Ref<Texture> _texture;
|
Ref<Texture> _texture;
|
||||||
LineTextureMode _texture_mode;
|
LineTextureMode _texture_mode;
|
||||||
float _sharp_limit;
|
float _sharp_limit;
|
||||||
|
@ -62,7 +62,7 @@ public:
|
|||||||
LineCapMode end_cap_mode;
|
LineCapMode end_cap_mode;
|
||||||
float width;
|
float width;
|
||||||
Color default_color;
|
Color default_color;
|
||||||
ColorRamp *gradient;
|
Gradient *gradient;
|
||||||
LineTextureMode texture_mode;
|
LineTextureMode texture_mode;
|
||||||
float sharp_limit;
|
float sharp_limit;
|
||||||
int round_precision;
|
int round_precision;
|
||||||
|
@ -774,12 +774,12 @@ Color Particles2D::get_color() const {
|
|||||||
return default_color;
|
return default_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Particles2D::set_color_ramp(const Ref<ColorRamp> &p_color_ramp) {
|
void Particles2D::set_color_ramp(const Ref<Gradient> &p_color_ramp) {
|
||||||
|
|
||||||
color_ramp = p_color_ramp;
|
color_ramp = p_color_ramp;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<ColorRamp> Particles2D::get_color_ramp() const {
|
Ref<Gradient> Particles2D::get_color_ramp() const {
|
||||||
|
|
||||||
return color_ramp;
|
return color_ramp;
|
||||||
}
|
}
|
||||||
@ -810,7 +810,7 @@ void Particles2D::set_color_phases(int p_phases) {
|
|||||||
//Create color ramp if we have 2 or more phases.
|
//Create color ramp if we have 2 or more phases.
|
||||||
//Otherwise first phase phase will be assigned to default color.
|
//Otherwise first phase phase will be assigned to default color.
|
||||||
if (p_phases > 1 && color_ramp.is_null()) {
|
if (p_phases > 1 && color_ramp.is_null()) {
|
||||||
color_ramp = Ref<ColorRamp>(memnew(ColorRamp()));
|
color_ramp = Ref<Gradient>(memnew(Gradient()));
|
||||||
}
|
}
|
||||||
if (color_ramp.is_valid()) {
|
if (color_ramp.is_valid()) {
|
||||||
color_ramp->get_points().resize(p_phases);
|
color_ramp->get_points().resize(p_phases);
|
||||||
|
@ -169,7 +169,7 @@ private:
|
|||||||
|
|
||||||
//If no color ramp is set then default color is used. Created as simple alternative to color_ramp.
|
//If no color ramp is set then default color is used. Created as simple alternative to color_ramp.
|
||||||
Color default_color;
|
Color default_color;
|
||||||
Ref<ColorRamp> color_ramp;
|
Ref<Gradient> color_ramp;
|
||||||
|
|
||||||
void _process_particles(float p_delta);
|
void _process_particles(float p_delta);
|
||||||
friend class ParticleAttractor2D;
|
friend class ParticleAttractor2D;
|
||||||
@ -241,8 +241,8 @@ public:
|
|||||||
void set_color(const Color &p_color);
|
void set_color(const Color &p_color);
|
||||||
Color get_color() const;
|
Color get_color() const;
|
||||||
|
|
||||||
void set_color_ramp(const Ref<ColorRamp> &p_texture);
|
void set_color_ramp(const Ref<Gradient> &p_texture);
|
||||||
Ref<ColorRamp> get_color_ramp() const;
|
Ref<Gradient> get_color_ramp() const;
|
||||||
|
|
||||||
void set_emissor_offset(const Point2 &p_offset);
|
void set_emissor_offset(const Point2 &p_offset);
|
||||||
Point2 get_emissor_offset() const;
|
Point2 get_emissor_offset() const;
|
||||||
|
@ -114,7 +114,7 @@ void ColorRampEdit::_gui_input(const Ref<InputEvent> &p_event) {
|
|||||||
|
|
||||||
if (grabbed != -1) {
|
if (grabbed != -1) {
|
||||||
int total_w = get_size().width - get_size().height - 3;
|
int total_w = get_size().width - get_size().height - 3;
|
||||||
ColorRamp::Point newPoint = points[grabbed];
|
Gradient::Point newPoint = points[grabbed];
|
||||||
newPoint.offset = CLAMP(x / float(total_w), 0, 1);
|
newPoint.offset = CLAMP(x / float(total_w), 0, 1);
|
||||||
|
|
||||||
points.push_back(newPoint);
|
points.push_back(newPoint);
|
||||||
@ -152,11 +152,11 @@ void ColorRampEdit::_gui_input(const Ref<InputEvent> &p_event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//insert
|
//insert
|
||||||
ColorRamp::Point newPoint;
|
Gradient::Point newPoint;
|
||||||
newPoint.offset = CLAMP(x / float(total_w), 0, 1);
|
newPoint.offset = CLAMP(x / float(total_w), 0, 1);
|
||||||
|
|
||||||
ColorRamp::Point prev;
|
Gradient::Point prev;
|
||||||
ColorRamp::Point next;
|
Gradient::Point next;
|
||||||
|
|
||||||
int pos = -1;
|
int pos = -1;
|
||||||
for (int i = 0; i < points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
@ -293,7 +293,7 @@ void ColorRampEdit::_notification(int p_what) {
|
|||||||
_draw_checker(0, 0, total_w, h);
|
_draw_checker(0, 0, total_w, h);
|
||||||
|
|
||||||
//Draw color ramp
|
//Draw color ramp
|
||||||
ColorRamp::Point prev;
|
Gradient::Point prev;
|
||||||
prev.offset = 0;
|
prev.offset = 0;
|
||||||
if (points.size() == 0)
|
if (points.size() == 0)
|
||||||
prev.color = Color(0, 0, 0); //Draw black rectangle if we have no points
|
prev.color = Color(0, 0, 0); //Draw black rectangle if we have no points
|
||||||
@ -302,7 +302,7 @@ void ColorRampEdit::_notification(int p_what) {
|
|||||||
|
|
||||||
for (int i = -1; i < points.size(); i++) {
|
for (int i = -1; i < points.size(); i++) {
|
||||||
|
|
||||||
ColorRamp::Point next;
|
Gradient::Point next;
|
||||||
//If there is no next point
|
//If there is no next point
|
||||||
if (i + 1 == points.size()) {
|
if (i + 1 == points.size()) {
|
||||||
if (points.size() == 0)
|
if (points.size() == 0)
|
||||||
@ -410,7 +410,7 @@ void ColorRampEdit::set_ramp(const Vector<float> &p_offsets, const Vector<Color>
|
|||||||
ERR_FAIL_COND(p_offsets.size() != p_colors.size());
|
ERR_FAIL_COND(p_offsets.size() != p_colors.size());
|
||||||
points.clear();
|
points.clear();
|
||||||
for (int i = 0; i < p_offsets.size(); i++) {
|
for (int i = 0; i < p_offsets.size(); i++) {
|
||||||
ColorRamp::Point p;
|
Gradient::Point p;
|
||||||
p.offset = p_offsets[i];
|
p.offset = p_offsets[i];
|
||||||
p.color = p_colors[i];
|
p.color = p_colors[i];
|
||||||
points.push_back(p);
|
points.push_back(p);
|
||||||
@ -434,14 +434,14 @@ Vector<Color> ColorRampEdit::get_colors() const {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorRampEdit::set_points(Vector<ColorRamp::Point> &p_points) {
|
void ColorRampEdit::set_points(Vector<Gradient::Point> &p_points) {
|
||||||
if (points.size() != p_points.size())
|
if (points.size() != p_points.size())
|
||||||
grabbed = -1;
|
grabbed = -1;
|
||||||
points.clear();
|
points.clear();
|
||||||
points = p_points;
|
points = p_points;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<ColorRamp::Point> &ColorRampEdit::get_points() {
|
Vector<Gradient::Point> &ColorRampEdit::get_points() {
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ class ColorRampEdit : public Control {
|
|||||||
|
|
||||||
bool grabbing;
|
bool grabbing;
|
||||||
int grabbed;
|
int grabbed;
|
||||||
Vector<ColorRamp::Point> points;
|
Vector<Gradient::Point> points;
|
||||||
|
|
||||||
void _draw_checker(int x, int y, int w, int h);
|
void _draw_checker(int x, int y, int w, int h);
|
||||||
void _color_changed(const Color &p_color);
|
void _color_changed(const Color &p_color);
|
||||||
@ -64,8 +64,8 @@ public:
|
|||||||
void set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors);
|
void set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors);
|
||||||
Vector<float> get_offsets() const;
|
Vector<float> get_offsets() const;
|
||||||
Vector<Color> get_colors() const;
|
Vector<Color> get_colors() const;
|
||||||
void set_points(Vector<ColorRamp::Point> &p_points);
|
void set_points(Vector<Gradient::Point> &p_points);
|
||||||
Vector<ColorRamp::Point> &get_points();
|
Vector<Gradient::Point> &get_points();
|
||||||
virtual Size2 get_minimum_size() const;
|
virtual Size2 get_minimum_size() const;
|
||||||
|
|
||||||
ColorRampEdit();
|
ColorRampEdit();
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "print_string.h"
|
#include "print_string.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
//#include "servers/spatial_sound_2d_server.h"
|
//#include "servers/spatial_sound_2d_server.h"
|
||||||
|
|
||||||
#include "io/marshalls.h"
|
#include "io/marshalls.h"
|
||||||
#include "io/resource_loader.h"
|
#include "io/resource_loader.h"
|
||||||
#include "scene/resources/material.h"
|
#include "scene/resources/material.h"
|
||||||
@ -609,6 +610,30 @@ bool SceneTree::idle(float p_time) {
|
|||||||
|
|
||||||
_call_idle_callbacks();
|
_call_idle_callbacks();
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
|
||||||
|
if (is_editor_hint()) {
|
||||||
|
//simple hack to reload fallback environment if it changed from editor
|
||||||
|
String env_path = GlobalConfig::get_singleton()->get("rendering/viewport/default_environment");
|
||||||
|
env_path = env_path.strip_edges(); //user may have added a space or two
|
||||||
|
String cpath;
|
||||||
|
Ref<Environment> fallback = get_root()->get_world()->get_fallback_environment();
|
||||||
|
if (fallback.is_valid()) {
|
||||||
|
cpath = fallback->get_path();
|
||||||
|
}
|
||||||
|
if (cpath != env_path) {
|
||||||
|
|
||||||
|
if (env_path != String()) {
|
||||||
|
fallback = ResourceLoader::load(env_path);
|
||||||
|
} else {
|
||||||
|
fallback.unref();
|
||||||
|
}
|
||||||
|
get_root()->get_world()->set_fallback_environment(fallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return _quit;
|
return _quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2301,7 +2326,9 @@ SceneTree::SceneTree() {
|
|||||||
|
|
||||||
root = memnew(Viewport);
|
root = memnew(Viewport);
|
||||||
root->set_name("root");
|
root->set_name("root");
|
||||||
|
if (!root->get_world().is_valid())
|
||||||
root->set_world(Ref<World>(memnew(World)));
|
root->set_world(Ref<World>(memnew(World)));
|
||||||
|
|
||||||
//root->set_world_2d( Ref<World2D>( memnew( World2D )));
|
//root->set_world_2d( Ref<World2D>( memnew( World2D )));
|
||||||
root->set_as_audio_listener(true);
|
root->set_as_audio_listener(true);
|
||||||
root->set_as_audio_listener_2d(true);
|
root->set_as_audio_listener_2d(true);
|
||||||
@ -2317,6 +2344,37 @@ SceneTree::SceneTree() {
|
|||||||
|
|
||||||
VS::get_singleton()->scenario_set_reflection_atlas_size(root->get_world()->get_scenario(), ref_atlas_size, ref_atlas_subdiv);
|
VS::get_singleton()->scenario_set_reflection_atlas_size(root->get_world()->get_scenario(), ref_atlas_size, ref_atlas_subdiv);
|
||||||
|
|
||||||
|
{ //load default fallback environment
|
||||||
|
//get possible extensions
|
||||||
|
List<String> exts;
|
||||||
|
ResourceLoader::get_recognized_extensions_for_type("Environment", &exts);
|
||||||
|
String ext_hint;
|
||||||
|
for (List<String>::Element *E = exts.front(); E; E = E->next()) {
|
||||||
|
if (ext_hint != String())
|
||||||
|
ext_hint += ",";
|
||||||
|
ext_hint += "*." + E->get();
|
||||||
|
}
|
||||||
|
//get path
|
||||||
|
String env_path = GLOBAL_DEF("rendering/viewport/default_environment", "");
|
||||||
|
//setup property
|
||||||
|
GlobalConfig::get_singleton()->set_custom_property_info("rendering/viewport/default_environment", PropertyInfo(Variant::STRING, "rendering/viewport/default_environment", PROPERTY_HINT_FILE, ext_hint));
|
||||||
|
env_path = env_path.strip_edges();
|
||||||
|
if (env_path != String()) {
|
||||||
|
Ref<Environment> env = ResourceLoader::load(env_path);
|
||||||
|
if (env.is_valid()) {
|
||||||
|
root->get_world()->set_fallback_environment(env);
|
||||||
|
} else {
|
||||||
|
if (is_editor_hint()) {
|
||||||
|
//file was erased, clear the field.
|
||||||
|
GlobalConfig::get_singleton()->set("rendering/viewport/default_environment", "");
|
||||||
|
} else {
|
||||||
|
//file was erased, notify user.
|
||||||
|
ERR_PRINTS(RTR("Default Environment as specified in Project Setings (Rendering -> Viewport -> Default Environment) could not be loaded."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stretch_mode = STRETCH_MODE_DISABLED;
|
stretch_mode = STRETCH_MODE_DISABLED;
|
||||||
stretch_aspect = STRETCH_ASPECT_IGNORE;
|
stretch_aspect = STRETCH_ASPECT_IGNORE;
|
||||||
|
|
||||||
|
@ -563,6 +563,7 @@ void register_scene_types() {
|
|||||||
ClassDB::register_virtual_class<Texture>();
|
ClassDB::register_virtual_class<Texture>();
|
||||||
ClassDB::register_virtual_class<Sky>();
|
ClassDB::register_virtual_class<Sky>();
|
||||||
ClassDB::register_class<PanoramaSky>();
|
ClassDB::register_class<PanoramaSky>();
|
||||||
|
ClassDB::register_class<ProceduralSky>();
|
||||||
ClassDB::register_class<StreamTexture>();
|
ClassDB::register_class<StreamTexture>();
|
||||||
ClassDB::register_class<ImageTexture>();
|
ClassDB::register_class<ImageTexture>();
|
||||||
ClassDB::register_class<AtlasTexture>();
|
ClassDB::register_class<AtlasTexture>();
|
||||||
@ -584,7 +585,7 @@ void register_scene_types() {
|
|||||||
|
|
||||||
ClassDB::register_class<PolygonPathFinder>();
|
ClassDB::register_class<PolygonPathFinder>();
|
||||||
ClassDB::register_class<BitMap>();
|
ClassDB::register_class<BitMap>();
|
||||||
ClassDB::register_class<ColorRamp>();
|
ClassDB::register_class<Gradient>();
|
||||||
|
|
||||||
OS::get_singleton()->yield(); //may take time to init
|
OS::get_singleton()->yield(); //may take time to init
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
#define COLOR_RAMP_SET_OFFSETS "set_offsets"
|
#define COLOR_RAMP_SET_OFFSETS "set_offsets"
|
||||||
#define COLOR_RAMP_SET_COLORS "set_colors"
|
#define COLOR_RAMP_SET_COLORS "set_colors"
|
||||||
|
|
||||||
ColorRamp::ColorRamp() {
|
Gradient::Gradient() {
|
||||||
//Set initial color ramp transition from black to white
|
//Set initial color ramp transition from black to white
|
||||||
points.resize(2);
|
points.resize(2);
|
||||||
points[0].color = Color(0, 0, 0, 1);
|
points[0].color = Color(0, 0, 0, 1);
|
||||||
@ -46,35 +46,35 @@ ColorRamp::ColorRamp() {
|
|||||||
is_sorted = true;
|
is_sorted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorRamp::~ColorRamp() {
|
Gradient::~Gradient() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorRamp::_bind_methods() {
|
void Gradient::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("add_point", "offset", "color"), &ColorRamp::add_point);
|
ClassDB::bind_method(D_METHOD("add_point", "offset", "color"), &Gradient::add_point);
|
||||||
ClassDB::bind_method(D_METHOD("remove_point", "offset", "color"), &ColorRamp::remove_point);
|
ClassDB::bind_method(D_METHOD("remove_point", "offset", "color"), &Gradient::remove_point);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_offset", "point", "offset"), &ColorRamp::set_offset);
|
ClassDB::bind_method(D_METHOD("set_offset", "point", "offset"), &Gradient::set_offset);
|
||||||
ClassDB::bind_method(D_METHOD("get_offset", "point"), &ColorRamp::get_offset);
|
ClassDB::bind_method(D_METHOD("get_offset", "point"), &Gradient::get_offset);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_color", "point", "color"), &ColorRamp::set_color);
|
ClassDB::bind_method(D_METHOD("set_color", "point", "color"), &Gradient::set_color);
|
||||||
ClassDB::bind_method(D_METHOD("get_color", "point"), &ColorRamp::get_color);
|
ClassDB::bind_method(D_METHOD("get_color", "point"), &Gradient::get_color);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("interpolate", "offset"), &ColorRamp::get_color_at_offset);
|
ClassDB::bind_method(D_METHOD("interpolate", "offset"), &Gradient::get_color_at_offset);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_point_count"), &ColorRamp::get_points_count);
|
ClassDB::bind_method(D_METHOD("get_point_count"), &Gradient::get_points_count);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_OFFSETS, "offsets"), &ColorRamp::set_offsets);
|
ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_OFFSETS, "offsets"), &Gradient::set_offsets);
|
||||||
ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_OFFSETS), &ColorRamp::get_offsets);
|
ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_OFFSETS), &Gradient::get_offsets);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_COLORS, "colors"), &ColorRamp::set_colors);
|
ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_COLORS, "colors"), &Gradient::set_colors);
|
||||||
ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_COLORS), &ColorRamp::get_colors);
|
ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_COLORS), &Gradient::get_colors);
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "offsets"), COLOR_RAMP_SET_OFFSETS, COLOR_RAMP_GET_OFFSETS);
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "offsets"), COLOR_RAMP_SET_OFFSETS, COLOR_RAMP_GET_OFFSETS);
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "colors"), COLOR_RAMP_SET_COLORS, COLOR_RAMP_GET_COLORS);
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "colors"), COLOR_RAMP_SET_COLORS, COLOR_RAMP_GET_COLORS);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<float> ColorRamp::get_offsets() const {
|
Vector<float> Gradient::get_offsets() const {
|
||||||
Vector<float> offsets;
|
Vector<float> offsets;
|
||||||
offsets.resize(points.size());
|
offsets.resize(points.size());
|
||||||
for (int i = 0; i < points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
@ -83,7 +83,7 @@ Vector<float> ColorRamp::get_offsets() const {
|
|||||||
return offsets;
|
return offsets;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<Color> ColorRamp::get_colors() const {
|
Vector<Color> Gradient::get_colors() const {
|
||||||
Vector<Color> colors;
|
Vector<Color> colors;
|
||||||
colors.resize(points.size());
|
colors.resize(points.size());
|
||||||
for (int i = 0; i < points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
@ -92,7 +92,7 @@ Vector<Color> ColorRamp::get_colors() const {
|
|||||||
return colors;
|
return colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorRamp::set_offsets(const Vector<float> &p_offsets) {
|
void Gradient::set_offsets(const Vector<float> &p_offsets) {
|
||||||
points.resize(p_offsets.size());
|
points.resize(p_offsets.size());
|
||||||
for (int i = 0; i < points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
points[i].offset = p_offsets[i];
|
points[i].offset = p_offsets[i];
|
||||||
@ -101,7 +101,7 @@ void ColorRamp::set_offsets(const Vector<float> &p_offsets) {
|
|||||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorRamp::set_colors(const Vector<Color> &p_colors) {
|
void Gradient::set_colors(const Vector<Color> &p_colors) {
|
||||||
if (points.size() < p_colors.size())
|
if (points.size() < p_colors.size())
|
||||||
is_sorted = false;
|
is_sorted = false;
|
||||||
points.resize(p_colors.size());
|
points.resize(p_colors.size());
|
||||||
@ -111,11 +111,11 @@ void ColorRamp::set_colors(const Vector<Color> &p_colors) {
|
|||||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<ColorRamp::Point> &ColorRamp::get_points() {
|
Vector<Gradient::Point> &Gradient::get_points() {
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorRamp::add_point(float p_offset, const Color &p_color) {
|
void Gradient::add_point(float p_offset, const Color &p_color) {
|
||||||
|
|
||||||
Point p;
|
Point p;
|
||||||
p.offset = p_offset;
|
p.offset = p_offset;
|
||||||
@ -126,7 +126,7 @@ void ColorRamp::add_point(float p_offset, const Color &p_color) {
|
|||||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorRamp::remove_point(int p_index) {
|
void Gradient::remove_point(int p_index) {
|
||||||
|
|
||||||
ERR_FAIL_INDEX(p_index, points.size());
|
ERR_FAIL_INDEX(p_index, points.size());
|
||||||
ERR_FAIL_COND(points.size() <= 2);
|
ERR_FAIL_COND(points.size() <= 2);
|
||||||
@ -134,13 +134,13 @@ void ColorRamp::remove_point(int p_index) {
|
|||||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorRamp::set_points(Vector<ColorRamp::Point> &p_points) {
|
void Gradient::set_points(Vector<Gradient::Point> &p_points) {
|
||||||
points = p_points;
|
points = p_points;
|
||||||
is_sorted = false;
|
is_sorted = false;
|
||||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorRamp::set_offset(int pos, const float offset) {
|
void Gradient::set_offset(int pos, const float offset) {
|
||||||
if (points.size() <= pos)
|
if (points.size() <= pos)
|
||||||
points.resize(pos + 1);
|
points.resize(pos + 1);
|
||||||
points[pos].offset = offset;
|
points[pos].offset = offset;
|
||||||
@ -148,13 +148,13 @@ void ColorRamp::set_offset(int pos, const float offset) {
|
|||||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
float ColorRamp::get_offset(int pos) const {
|
float Gradient::get_offset(int pos) const {
|
||||||
if (points.size() > pos)
|
if (points.size() > pos)
|
||||||
return points[pos].offset;
|
return points[pos].offset;
|
||||||
return 0; //TODO: Maybe throw some error instead?
|
return 0; //TODO: Maybe throw some error instead?
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorRamp::set_color(int pos, const Color &color) {
|
void Gradient::set_color(int pos, const Color &color) {
|
||||||
if (points.size() <= pos) {
|
if (points.size() <= pos) {
|
||||||
points.resize(pos + 1);
|
points.resize(pos + 1);
|
||||||
is_sorted = false;
|
is_sorted = false;
|
||||||
@ -163,12 +163,12 @@ void ColorRamp::set_color(int pos, const Color &color) {
|
|||||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color ColorRamp::get_color(int pos) const {
|
Color Gradient::get_color(int pos) const {
|
||||||
if (points.size() > pos)
|
if (points.size() > pos)
|
||||||
return points[pos].color;
|
return points[pos].color;
|
||||||
return Color(0, 0, 0, 1); //TODO: Maybe throw some error instead?
|
return Color(0, 0, 0, 1); //TODO: Maybe throw some error instead?
|
||||||
}
|
}
|
||||||
|
|
||||||
int ColorRamp::get_points_count() const {
|
int Gradient::get_points_count() const {
|
||||||
return points.size();
|
return points.size();
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,9 @@
|
|||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
class ColorRamp : public Resource {
|
class Gradient : public Resource {
|
||||||
GDCLASS(ColorRamp, Resource);
|
GDCLASS(Gradient, Resource);
|
||||||
OBJ_SAVE_TYPE(ColorRamp);
|
OBJ_SAVE_TYPE(Gradient);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct Point {
|
struct Point {
|
||||||
@ -54,8 +54,8 @@ protected:
|
|||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ColorRamp();
|
Gradient();
|
||||||
virtual ~ColorRamp();
|
virtual ~Gradient();
|
||||||
|
|
||||||
void add_point(float p_offset, const Color &p_color);
|
void add_point(float p_offset, const Color &p_color);
|
||||||
void remove_point(int p_index);
|
void remove_point(int p_index);
|
||||||
|
@ -112,3 +112,394 @@ PanoramaSky::~PanoramaSky() {
|
|||||||
|
|
||||||
VS::get_singleton()->free(sky);
|
VS::get_singleton()->free(sky);
|
||||||
}
|
}
|
||||||
|
//////////////////////////////////
|
||||||
|
|
||||||
|
void ProceduralSky::_radiance_changed() {
|
||||||
|
|
||||||
|
if (update_queued)
|
||||||
|
return; //do nothing yet
|
||||||
|
|
||||||
|
static const int size[RADIANCE_SIZE_MAX] = {
|
||||||
|
256, 512, 1024, 2048
|
||||||
|
};
|
||||||
|
VS::get_singleton()->sky_set_texture(sky, texture, size[get_radiance_size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::_update_sky() {
|
||||||
|
|
||||||
|
update_queued = false;
|
||||||
|
|
||||||
|
PoolVector<uint8_t> imgdata;
|
||||||
|
|
||||||
|
static const int size[TEXTURE_SIZE_MAX] = {
|
||||||
|
1024, 2048, 4096
|
||||||
|
};
|
||||||
|
|
||||||
|
int w = size[texture_size];
|
||||||
|
int h = w / 2;
|
||||||
|
|
||||||
|
imgdata.resize(w * h * 4); //RGBE
|
||||||
|
|
||||||
|
{
|
||||||
|
PoolVector<uint8_t>::Write dataw = imgdata.write();
|
||||||
|
|
||||||
|
uint32_t *ptr = (uint32_t *)dataw.ptr();
|
||||||
|
|
||||||
|
Color sky_top_linear = sky_top_color.to_linear();
|
||||||
|
Color sky_horizon_linear = sky_horizon_color.to_linear();
|
||||||
|
|
||||||
|
Color ground_bottom_linear = ground_bottom_color.to_linear();
|
||||||
|
Color ground_horizon_linear = ground_horizon_color.to_linear();
|
||||||
|
|
||||||
|
//Color sun_linear = sun_color.to_linear();
|
||||||
|
|
||||||
|
Vector3 sun(0, 0, -1);
|
||||||
|
|
||||||
|
sun = Basis(Vector3(1, 0, 0), Math::deg2rad(sun_latitude)).xform(sun);
|
||||||
|
sun = Basis(Vector3(0, 1, 0), Math::deg2rad(sun_longitude)).xform(sun);
|
||||||
|
|
||||||
|
sun.normalize();
|
||||||
|
|
||||||
|
for (int i = 0; i < w; i++) {
|
||||||
|
|
||||||
|
float u = float(i) / (w - 1);
|
||||||
|
float phi = u * 2.0 * Math_PI;
|
||||||
|
|
||||||
|
for (int j = 0; j < h; j++) {
|
||||||
|
|
||||||
|
float v = float(j) / (h - 1);
|
||||||
|
float theta = v * Math_PI;
|
||||||
|
|
||||||
|
Vector3 normal(
|
||||||
|
Math::sin(phi) * Math::sin(theta) * -1.0,
|
||||||
|
Math::cos(theta),
|
||||||
|
Math::cos(phi) * Math::sin(theta) * -1.0);
|
||||||
|
|
||||||
|
normal.normalize();
|
||||||
|
|
||||||
|
float v_angle = Math::acos(normal.y);
|
||||||
|
|
||||||
|
Color color;
|
||||||
|
|
||||||
|
if (normal.y < 0) {
|
||||||
|
//ground
|
||||||
|
|
||||||
|
float c = (v_angle - (Math_PI * 0.5)) / (Math_PI * 0.5);
|
||||||
|
color = ground_horizon_linear.linear_interpolate(ground_bottom_linear, Math::ease(c, ground_curve));
|
||||||
|
} else {
|
||||||
|
float c = v_angle / (Math_PI * 0.5);
|
||||||
|
color = sky_horizon_linear.linear_interpolate(sky_top_linear, Math::ease(1.0 - c, sky_curve));
|
||||||
|
|
||||||
|
float sun_angle = Math::rad2deg(Math::acos(sun.dot(normal)));
|
||||||
|
|
||||||
|
if (sun_angle < sun_angle_min) {
|
||||||
|
color = color.blend(sun_color);
|
||||||
|
} else if (sun_angle < sun_angle_max) {
|
||||||
|
|
||||||
|
float c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);
|
||||||
|
c2 = Math::ease(c2, sun_curve);
|
||||||
|
|
||||||
|
color = color.blend(sun_color).linear_interpolate(color, c2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr[j * w + i] = color.to_rgbe9995();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Image> image;
|
||||||
|
image.instance();
|
||||||
|
image->create(w, h, false, Image::FORMAT_RGBE9995, imgdata);
|
||||||
|
|
||||||
|
VS::get_singleton()->texture_allocate(texture, w, h, Image::FORMAT_RGBE9995, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT);
|
||||||
|
VS::get_singleton()->texture_set_data(texture, image);
|
||||||
|
_radiance_changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_sky_top_color(const Color &p_sky_top) {
|
||||||
|
|
||||||
|
sky_top_color = p_sky_top;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
|
||||||
|
Color ProceduralSky::get_sky_top_color() const {
|
||||||
|
|
||||||
|
return sky_top_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_sky_horizon_color(const Color &p_sky_horizon) {
|
||||||
|
|
||||||
|
sky_horizon_color = p_sky_horizon;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
Color ProceduralSky::get_sky_horizon_color() const {
|
||||||
|
|
||||||
|
return sky_horizon_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_sky_curve(float p_curve) {
|
||||||
|
|
||||||
|
sky_curve = p_curve;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
float ProceduralSky::get_sky_curve() const {
|
||||||
|
|
||||||
|
return sky_curve;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_sky_energy(float p_energy) {
|
||||||
|
|
||||||
|
sky_energy = p_energy;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
float ProceduralSky::get_sky_energy() const {
|
||||||
|
|
||||||
|
return sky_energy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_ground_bottom_color(const Color &p_ground_bottom) {
|
||||||
|
|
||||||
|
ground_bottom_color = p_ground_bottom;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
Color ProceduralSky::get_ground_bottom_color() const {
|
||||||
|
|
||||||
|
return ground_bottom_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_ground_horizon_color(const Color &p_ground_horizon) {
|
||||||
|
|
||||||
|
ground_horizon_color = p_ground_horizon;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
Color ProceduralSky::get_ground_horizon_color() const {
|
||||||
|
|
||||||
|
return ground_horizon_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_ground_curve(float p_curve) {
|
||||||
|
|
||||||
|
ground_curve = p_curve;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
float ProceduralSky::get_ground_curve() const {
|
||||||
|
|
||||||
|
return ground_curve;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_ground_energy(float p_energy) {
|
||||||
|
|
||||||
|
ground_energy = p_energy;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
float ProceduralSky::get_ground_energy() const {
|
||||||
|
|
||||||
|
return ground_energy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_sun_color(const Color &p_sun) {
|
||||||
|
|
||||||
|
sun_color = p_sun;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
Color ProceduralSky::get_sun_color() const {
|
||||||
|
|
||||||
|
return sun_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_sun_latitude(float p_angle) {
|
||||||
|
|
||||||
|
sun_latitude = p_angle;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
float ProceduralSky::get_sun_latitude() const {
|
||||||
|
|
||||||
|
return sun_latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_sun_longitude(float p_angle) {
|
||||||
|
|
||||||
|
sun_longitude = p_angle;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
float ProceduralSky::get_sun_longitude() const {
|
||||||
|
|
||||||
|
return sun_longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_sun_angle_min(float p_angle) {
|
||||||
|
|
||||||
|
sun_angle_min = p_angle;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
float ProceduralSky::get_sun_angle_min() const {
|
||||||
|
|
||||||
|
return sun_angle_min;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_sun_angle_max(float p_angle) {
|
||||||
|
|
||||||
|
sun_angle_max = p_angle;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
float ProceduralSky::get_sun_angle_max() const {
|
||||||
|
|
||||||
|
return sun_angle_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_sun_curve(float p_curve) {
|
||||||
|
|
||||||
|
sun_curve = p_curve;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
float ProceduralSky::get_sun_curve() const {
|
||||||
|
|
||||||
|
return sun_curve;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_sun_energy(float p_energy) {
|
||||||
|
|
||||||
|
sun_energy = p_energy;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
float ProceduralSky::get_sun_energy() const {
|
||||||
|
|
||||||
|
return sun_energy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::set_texture_size(TextureSize p_size) {
|
||||||
|
ERR_FAIL_INDEX(p_size, TEXTURE_SIZE_MAX);
|
||||||
|
|
||||||
|
texture_size = p_size;
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
ProceduralSky::TextureSize ProceduralSky::get_texture_size() const {
|
||||||
|
return texture_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
RID ProceduralSky::get_rid() const {
|
||||||
|
return sky;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::_queue_update() {
|
||||||
|
|
||||||
|
if (update_queued)
|
||||||
|
return;
|
||||||
|
|
||||||
|
update_queued = true;
|
||||||
|
call_deferred("_update_sky");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProceduralSky::_bind_methods() {
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("_update_sky"), &ProceduralSky::_update_sky);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_sky_top_color", "color"), &ProceduralSky::set_sky_top_color);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_sky_top_color"), &ProceduralSky::get_sky_top_color);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_sky_horizon_color", "color"), &ProceduralSky::set_sky_horizon_color);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_sky_horizon_color"), &ProceduralSky::get_sky_horizon_color);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_sky_curve", "curve"), &ProceduralSky::set_sky_curve);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_sky_curve"), &ProceduralSky::get_sky_curve);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_sky_energy", "energy"), &ProceduralSky::set_sky_energy);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_sky_energy"), &ProceduralSky::get_sky_energy);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_ground_bottom_color", "color"), &ProceduralSky::set_ground_bottom_color);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_ground_bottom_color"), &ProceduralSky::get_ground_bottom_color);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_ground_horizon_color", "color"), &ProceduralSky::set_ground_horizon_color);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_ground_horizon_color"), &ProceduralSky::get_ground_horizon_color);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_ground_curve", "curve"), &ProceduralSky::set_ground_curve);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_ground_curve"), &ProceduralSky::get_ground_curve);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_ground_energy", "energy"), &ProceduralSky::set_ground_energy);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_ground_energy"), &ProceduralSky::get_ground_energy);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_sun_color", "color"), &ProceduralSky::set_sun_color);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_sun_color"), &ProceduralSky::get_sun_color);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_sun_latitude", "degrees"), &ProceduralSky::set_sun_latitude);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_sun_latitude"), &ProceduralSky::get_sun_latitude);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_sun_longitude", "degrees"), &ProceduralSky::set_sun_longitude);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_sun_longitude"), &ProceduralSky::get_sun_longitude);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_sun_angle_min", "degrees"), &ProceduralSky::set_sun_angle_min);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_sun_angle_min"), &ProceduralSky::get_sun_angle_min);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_sun_angle_max", "degrees"), &ProceduralSky::set_sun_angle_max);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_sun_angle_max"), &ProceduralSky::get_sun_angle_max);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_sun_curve", "curve"), &ProceduralSky::set_sun_curve);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_sun_curve"), &ProceduralSky::get_sun_curve);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_sun_energy", "energy"), &ProceduralSky::set_sun_energy);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_sun_energy"), &ProceduralSky::get_sun_energy);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_texture_size", "size"), &ProceduralSky::set_texture_size);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_texture_size"), &ProceduralSky::get_texture_size);
|
||||||
|
|
||||||
|
ADD_GROUP("Sky", "sky_");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_top_color"), "set_sky_top_color", "get_sky_top_color");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_horizon_color"), "set_sky_horizon_color", "get_sky_horizon_color");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "sky_curve", PROPERTY_HINT_EXP_EASING), "set_sky_curve", "get_sky_curve");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "sky_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sky_energy", "get_sky_energy");
|
||||||
|
|
||||||
|
ADD_GROUP("Ground", "ground_");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_bottom_color"), "set_ground_bottom_color", "get_ground_bottom_color");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_horizon_color"), "set_ground_horizon_color", "get_ground_horizon_color");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ground_curve", PROPERTY_HINT_EXP_EASING), "set_ground_curve", "get_ground_curve");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ground_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_ground_energy", "get_ground_energy");
|
||||||
|
|
||||||
|
ADD_GROUP("Sun", "sun_");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sun_color"), "set_sun_color", "get_sun_color");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_latitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_latitude", "get_sun_latitude");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_longitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_longitude", "get_sun_longitude");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_angle_min", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_min", "get_sun_angle_min");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sun_energy", "get_sun_energy");
|
||||||
|
|
||||||
|
ADD_GROUP("Texture", "texture_");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_size", PROPERTY_HINT_ENUM, "1024,2048,4096"), "set_texture_size", "get_texture_size");
|
||||||
|
}
|
||||||
|
|
||||||
|
ProceduralSky::ProceduralSky() {
|
||||||
|
|
||||||
|
sky = VS::get_singleton()->sky_create();
|
||||||
|
texture = VS::get_singleton()->texture_create();
|
||||||
|
|
||||||
|
update_queued = false;
|
||||||
|
|
||||||
|
sky_top_color = Color::hex(0x4d67e8ff);
|
||||||
|
sky_horizon_color = Color::hex(0x8ed2e8ff);
|
||||||
|
sky_curve = 0.25;
|
||||||
|
sky_energy = 1;
|
||||||
|
|
||||||
|
ground_bottom_color = Color::hex(0x322719ff);
|
||||||
|
ground_horizon_color = Color::hex(0x543610ff);
|
||||||
|
ground_curve = 0.25;
|
||||||
|
ground_energy = 1;
|
||||||
|
|
||||||
|
sun_color = Color(1, 1, 1);
|
||||||
|
sun_latitude = 35;
|
||||||
|
sun_longitude = 0;
|
||||||
|
sun_angle_min = 1;
|
||||||
|
sun_angle_max = 100;
|
||||||
|
sun_curve = 0.05;
|
||||||
|
sun_energy = 16;
|
||||||
|
|
||||||
|
texture_size = TEXTURE_SIZE_1024;
|
||||||
|
|
||||||
|
_queue_update();
|
||||||
|
}
|
||||||
|
|
||||||
|
ProceduralSky::~ProceduralSky() {
|
||||||
|
|
||||||
|
VS::get_singleton()->free(sky);
|
||||||
|
VS::get_singleton()->free(texture);
|
||||||
|
}
|
||||||
|
@ -62,17 +62,6 @@ VARIANT_ENUM_CAST(Sky::RadianceSize)
|
|||||||
class PanoramaSky : public Sky {
|
class PanoramaSky : public Sky {
|
||||||
GDCLASS(PanoramaSky, Sky);
|
GDCLASS(PanoramaSky, Sky);
|
||||||
|
|
||||||
public:
|
|
||||||
enum ImagePath {
|
|
||||||
IMAGE_PATH_NEGATIVE_X,
|
|
||||||
IMAGE_PATH_POSITIVE_X,
|
|
||||||
IMAGE_PATH_NEGATIVE_Y,
|
|
||||||
IMAGE_PATH_POSITIVE_Y,
|
|
||||||
IMAGE_PATH_NEGATIVE_Z,
|
|
||||||
IMAGE_PATH_POSITIVE_Z,
|
|
||||||
IMAGE_PATH_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RID sky;
|
RID sky;
|
||||||
Ref<Texture> panorama;
|
Ref<Texture> panorama;
|
||||||
@ -91,6 +80,105 @@ public:
|
|||||||
~PanoramaSky();
|
~PanoramaSky();
|
||||||
};
|
};
|
||||||
|
|
||||||
VARIANT_ENUM_CAST(PanoramaSky::ImagePath)
|
class ProceduralSky : public Sky {
|
||||||
|
GDCLASS(ProceduralSky, Sky);
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum TextureSize {
|
||||||
|
TEXTURE_SIZE_1024,
|
||||||
|
TEXTURE_SIZE_2048,
|
||||||
|
TEXTURE_SIZE_4096,
|
||||||
|
TEXTURE_SIZE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
Color sky_top_color;
|
||||||
|
Color sky_horizon_color;
|
||||||
|
float sky_curve;
|
||||||
|
float sky_energy;
|
||||||
|
|
||||||
|
Color ground_bottom_color;
|
||||||
|
Color ground_horizon_color;
|
||||||
|
float ground_curve;
|
||||||
|
float ground_energy;
|
||||||
|
|
||||||
|
Color sun_color;
|
||||||
|
float sun_latitude;
|
||||||
|
float sun_longitude;
|
||||||
|
float sun_angle_min;
|
||||||
|
float sun_angle_max;
|
||||||
|
float sun_curve;
|
||||||
|
float sun_energy;
|
||||||
|
|
||||||
|
TextureSize texture_size;
|
||||||
|
|
||||||
|
RID sky;
|
||||||
|
RID texture;
|
||||||
|
|
||||||
|
bool update_queued;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
virtual void _radiance_changed();
|
||||||
|
|
||||||
|
void _update_sky();
|
||||||
|
void _queue_update();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void set_sky_top_color(const Color &p_sky_top);
|
||||||
|
Color get_sky_top_color() const;
|
||||||
|
|
||||||
|
void set_sky_horizon_color(const Color &p_sky_horizon);
|
||||||
|
Color get_sky_horizon_color() const;
|
||||||
|
|
||||||
|
void set_sky_curve(float p_curve);
|
||||||
|
float get_sky_curve() const;
|
||||||
|
|
||||||
|
void set_sky_energy(float p_energy);
|
||||||
|
float get_sky_energy() const;
|
||||||
|
|
||||||
|
void set_ground_bottom_color(const Color &p_ground_bottom);
|
||||||
|
Color get_ground_bottom_color() const;
|
||||||
|
|
||||||
|
void set_ground_horizon_color(const Color &p_ground_horizon);
|
||||||
|
Color get_ground_horizon_color() const;
|
||||||
|
|
||||||
|
void set_ground_curve(float p_curve);
|
||||||
|
float get_ground_curve() const;
|
||||||
|
|
||||||
|
void set_ground_energy(float p_energy);
|
||||||
|
float get_ground_energy() const;
|
||||||
|
|
||||||
|
void set_sun_color(const Color &p_sun);
|
||||||
|
Color get_sun_color() const;
|
||||||
|
|
||||||
|
void set_sun_latitude(float p_angle);
|
||||||
|
float get_sun_latitude() const;
|
||||||
|
|
||||||
|
void set_sun_longitude(float p_angle);
|
||||||
|
float get_sun_longitude() const;
|
||||||
|
|
||||||
|
void set_sun_angle_min(float p_angle);
|
||||||
|
float get_sun_angle_min() const;
|
||||||
|
|
||||||
|
void set_sun_angle_max(float p_angle);
|
||||||
|
float get_sun_angle_max() const;
|
||||||
|
|
||||||
|
void set_sun_curve(float p_curve);
|
||||||
|
float get_sun_curve() const;
|
||||||
|
|
||||||
|
void set_sun_energy(float p_energy);
|
||||||
|
float get_sun_energy() const;
|
||||||
|
|
||||||
|
void set_texture_size(TextureSize p_size);
|
||||||
|
TextureSize get_texture_size() const;
|
||||||
|
|
||||||
|
virtual RID get_rid() const;
|
||||||
|
|
||||||
|
ProceduralSky();
|
||||||
|
~ProceduralSky();
|
||||||
|
};
|
||||||
|
|
||||||
|
VARIANT_ENUM_CAST(ProceduralSky::TextureSize)
|
||||||
|
|
||||||
#endif // Sky_H
|
#endif // Sky_H
|
||||||
|
@ -280,6 +280,20 @@ Ref<Environment> World::get_environment() const {
|
|||||||
return environment;
|
return environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::set_fallback_environment(const Ref<Environment> &p_environment) {
|
||||||
|
|
||||||
|
fallback_environment = p_environment;
|
||||||
|
if (fallback_environment.is_valid())
|
||||||
|
VS::get_singleton()->scenario_set_fallback_environment(scenario, p_environment->get_rid());
|
||||||
|
else
|
||||||
|
VS::get_singleton()->scenario_set_fallback_environment(scenario, RID());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Environment> World::get_fallback_environment() const {
|
||||||
|
|
||||||
|
return fallback_environment;
|
||||||
|
}
|
||||||
|
|
||||||
PhysicsDirectSpaceState *World::get_direct_space_state() {
|
PhysicsDirectSpaceState *World::get_direct_space_state() {
|
||||||
|
|
||||||
return PhysicsServer::get_singleton()->space_get_direct_state(space);
|
return PhysicsServer::get_singleton()->space_get_direct_state(space);
|
||||||
@ -291,8 +305,11 @@ void World::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("get_scenario"), &World::get_scenario);
|
ClassDB::bind_method(D_METHOD("get_scenario"), &World::get_scenario);
|
||||||
ClassDB::bind_method(D_METHOD("set_environment", "env:Environment"), &World::set_environment);
|
ClassDB::bind_method(D_METHOD("set_environment", "env:Environment"), &World::set_environment);
|
||||||
ClassDB::bind_method(D_METHOD("get_environment:Environment"), &World::get_environment);
|
ClassDB::bind_method(D_METHOD("get_environment:Environment"), &World::get_environment);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_fallback_environment", "env:Environment"), &World::set_fallback_environment);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_fallback_environment:Environment"), &World::get_fallback_environment);
|
||||||
ClassDB::bind_method(D_METHOD("get_direct_space_state:PhysicsDirectSpaceState"), &World::get_direct_space_state);
|
ClassDB::bind_method(D_METHOD("get_direct_space_state:PhysicsDirectSpaceState"), &World::get_direct_space_state);
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_fallback_environment", "get_fallback_environment");
|
||||||
}
|
}
|
||||||
|
|
||||||
World::World() {
|
World::World() {
|
||||||
|
@ -48,6 +48,7 @@ private:
|
|||||||
RID scenario;
|
RID scenario;
|
||||||
SpatialIndexer *indexer;
|
SpatialIndexer *indexer;
|
||||||
Ref<Environment> environment;
|
Ref<Environment> environment;
|
||||||
|
Ref<Environment> fallback_environment;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
@ -68,9 +69,13 @@ protected:
|
|||||||
public:
|
public:
|
||||||
RID get_space() const;
|
RID get_space() const;
|
||||||
RID get_scenario() const;
|
RID get_scenario() const;
|
||||||
|
|
||||||
void set_environment(const Ref<Environment> &p_environment);
|
void set_environment(const Ref<Environment> &p_environment);
|
||||||
Ref<Environment> get_environment() const;
|
Ref<Environment> get_environment() const;
|
||||||
|
|
||||||
|
void set_fallback_environment(const Ref<Environment> &p_environment);
|
||||||
|
Ref<Environment> get_fallback_environment() const;
|
||||||
|
|
||||||
PhysicsDirectSpaceState *get_direct_space_state();
|
PhysicsDirectSpaceState *get_direct_space_state();
|
||||||
|
|
||||||
World();
|
World();
|
||||||
|
Loading…
Reference in New Issue
Block a user