Style: Enforce braces around if blocks and loops

Using clang-tidy's `readability-braces-around-statements`.
https://clang.llvm.org/extra/clang-tidy/checks/readability-braces-around-statements.html
This commit is contained in:
Rémi Verschelde 2020-05-14 16:41:43 +02:00
parent 07bc4e2f96
commit 0ee0fa42e6
683 changed files with 22803 additions and 12225 deletions

View File

@ -1,5 +1,5 @@
--- ---
Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-nullptr' Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-nullptr,readability-braces-around-statements'
WarningsAsErrors: '' WarningsAsErrors: ''
HeaderFilterRegex: '.*' HeaderFilterRegex: '.*'
AnalyzeTemporaryDtors: false AnalyzeTemporaryDtors: false
@ -14,8 +14,6 @@ CheckOptions:
value: '1' value: '1'
- key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
value: '1' value: '1'
- key: google-readability-braces-around-statements.ShortStatementLines
value: '1'
- key: google-readability-function-size.StatementThreshold - key: google-readability-function-size.StatementThreshold
value: '800' value: '800'
- key: google-readability-namespace-comments.ShortNamespaceLines - key: google-readability-namespace-comments.ShortNamespaceLines
@ -40,5 +38,7 @@ CheckOptions:
value: '1' value: '1'
- key: modernize-use-nullptr.NullMacros - key: modernize-use-nullptr.NullMacros
value: 'NULL' value: 'NULL'
- key: readability-braces-around-statements.ShortStatementLines
value: '0'
... ...

View File

@ -50,8 +50,9 @@ void Array::_ref(const Array &p_from) const {
ERR_FAIL_COND(!_fp); // should NOT happen. ERR_FAIL_COND(!_fp); // should NOT happen.
if (_fp == _p) if (_fp == _p) {
return; // whatever it is, nothing to do here move along return; // whatever it is, nothing to do here move along
}
bool success = _fp->refcount.ref(); bool success = _fp->refcount.ref();
@ -63,8 +64,9 @@ void Array::_ref(const Array &p_from) const {
} }
void Array::_unref() const { void Array::_unref() const {
if (!_p) if (!_p) {
return; return;
}
if (_p->refcount.unref()) { if (_p->refcount.unref()) {
memdelete(_p); memdelete(_p);
@ -189,8 +191,9 @@ int Array::find(const Variant &p_value, int p_from) const {
} }
int Array::rfind(const Variant &p_value, int p_from) const { int Array::rfind(const Variant &p_value, int p_from) const {
if (_p->array.size() == 0) if (_p->array.size() == 0) {
return -1; return -1;
}
ERR_FAIL_COND_V(!_p->typed.validate(p_value, "rfind"), -1); ERR_FAIL_COND_V(!_p->typed.validate(p_value, "rfind"), -1);
if (p_from < 0) { if (p_from < 0) {
@ -218,8 +221,9 @@ int Array::find_last(const Variant &p_value) const {
int Array::count(const Variant &p_value) const { int Array::count(const Variant &p_value) const {
ERR_FAIL_COND_V(!_p->typed.validate(p_value, "count"), 0); ERR_FAIL_COND_V(!_p->typed.validate(p_value, "count"), 0);
if (_p->array.size() == 0) if (_p->array.size() == 0) {
return 0; return 0;
}
int amount = 0; int amount = 0;
for (int i = 0; i < _p->array.size(); i++) { for (int i = 0; i < _p->array.size(); i++) {
@ -278,14 +282,17 @@ Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { // l
ERR_FAIL_COND_V_MSG(p_step == 0, new_arr, "Array slice step size cannot be zero."); ERR_FAIL_COND_V_MSG(p_step == 0, new_arr, "Array slice step size cannot be zero.");
if (empty()) // Don't try to slice empty arrays. if (empty()) { // Don't try to slice empty arrays.
return new_arr; return new_arr;
}
if (p_step > 0) { if (p_step > 0) {
if (p_begin >= size() || p_end < -size()) if (p_begin >= size() || p_end < -size()) {
return new_arr; return new_arr;
}
} else { // p_step < 0 } else { // p_step < 0
if (p_begin < -size() || p_end >= size()) if (p_begin < -size() || p_end >= size()) {
return new_arr; return new_arr;
}
} }
int begin = _clamp_slice_index(p_begin); int begin = _clamp_slice_index(p_begin);
@ -316,8 +323,9 @@ struct _ArrayVariantSort {
bool valid = false; bool valid = false;
Variant res; Variant res;
Variant::evaluate(Variant::OP_LESS, p_l, p_r, res, valid); Variant::evaluate(Variant::OP_LESS, p_l, p_r, res, valid);
if (!valid) if (!valid) {
res = false; res = false;
}
return res; return res;
} }
}; };
@ -335,8 +343,9 @@ struct _ArrayVariantSortCustom {
const Variant *args[2] = { &p_l, &p_r }; const Variant *args[2] = { &p_l, &p_r };
Callable::CallError err; Callable::CallError err;
bool res = obj->call(func, args, 2, err); bool res = obj->call(func, args, 2, err);
if (err.error != Callable::CallError::CALL_OK) if (err.error != Callable::CallError::CALL_OK) {
res = false; res = false;
}
return res; return res;
} }
}; };
@ -352,8 +361,9 @@ Array &Array::sort_custom(Object *p_obj, const StringName &p_function) {
void Array::shuffle() { void Array::shuffle() {
const int n = _p->array.size(); const int n = _p->array.size();
if (n < 2) if (n < 2) {
return; return;
}
Variant *data = _p->array.ptrw(); Variant *data = _p->array.ptrw();
for (int i = n - 1; i >= 1; i--) { for (int i = n - 1; i >= 1; i--) {
const int j = Math::rand() % (i + 1); const int j = Math::rand() % (i + 1);

View File

@ -230,18 +230,20 @@ int _OS::execute(const String &p_path, const Vector<String> &p_arguments, bool p
OS::ProcessID pid = -2; OS::ProcessID pid = -2;
int exitcode = 0; int exitcode = 0;
List<String> args; List<String> args;
for (int i = 0; i < p_arguments.size(); i++) for (int i = 0; i < p_arguments.size(); i++) {
args.push_back(p_arguments[i]); args.push_back(p_arguments[i]);
}
String pipe; String pipe;
Error err = OS::get_singleton()->execute(p_path, args, p_blocking, &pid, &pipe, &exitcode, p_read_stderr); Error err = OS::get_singleton()->execute(p_path, args, p_blocking, &pid, &pipe, &exitcode, p_read_stderr);
p_output.clear(); p_output.clear();
p_output.push_back(pipe); p_output.push_back(pipe);
if (err != OK) if (err != OK) {
return -1; return -1;
else if (p_blocking) } else if (p_blocking) {
return exitcode; return exitcode;
else } else {
return pid; return pid;
}
} }
Error _OS::kill(int p_pid) { Error _OS::kill(int p_pid) {
@ -564,8 +566,9 @@ void _OS::print_all_textures_by_size() {
ResourceCache::get_cached_resources(&rsrc); ResourceCache::get_cached_resources(&rsrc);
for (List<Ref<Resource>>::Element *E = rsrc.front(); E; E = E->next()) { for (List<Ref<Resource>>::Element *E = rsrc.front(); E; E = E->next()) {
if (!E->get()->is_class("ImageTexture")) if (!E->get()->is_class("ImageTexture")) {
continue; continue;
}
Size2 size = E->get()->call("get_size"); Size2 size = E->get()->call("get_size");
int fmt = E->get()->call("get_format"); int fmt = E->get()->call("get_format");
@ -603,11 +606,13 @@ void _OS::print_resources_by_type(const Vector<String> &p_types) {
bool found = false; bool found = false;
for (int i = 0; i < p_types.size(); i++) { for (int i = 0; i < p_types.size(); i++) {
if (r->is_class(p_types[i])) if (r->is_class(p_types[i])) {
found = true; found = true;
}
} }
if (!found) if (!found) {
continue; continue;
}
if (!type_count.has(r->get_class())) { if (!type_count.has(r->get_class())) {
type_count[r->get_class()] = 0; type_count[r->get_class()] = 0;
@ -889,18 +894,20 @@ Vector3 _Geometry::get_closest_point_to_segment_uncapped(const Vector3 &p_point,
Variant _Geometry::ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) { Variant _Geometry::ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) {
Vector3 res; Vector3 res;
if (Geometry::ray_intersects_triangle(p_from, p_dir, p_v0, p_v1, p_v2, &res)) if (Geometry::ray_intersects_triangle(p_from, p_dir, p_v0, p_v1, p_v2, &res)) {
return res; return res;
else } else {
return Variant(); return Variant();
}
} }
Variant _Geometry::segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) { Variant _Geometry::segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) {
Vector3 res; Vector3 res;
if (Geometry::segment_intersects_triangle(p_from, p_to, p_v0, p_v1, p_v2, &res)) if (Geometry::segment_intersects_triangle(p_from, p_to, p_v0, p_v1, p_v2, &res)) {
return res; return res;
else } else {
return Variant(); return Variant();
}
} }
bool _Geometry::point_is_inside_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) const { bool _Geometry::point_is_inside_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) const {
@ -910,8 +917,9 @@ bool _Geometry::point_is_inside_triangle(const Vector2 &s, const Vector2 &a, con
Vector<Vector3> _Geometry::segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius) { Vector<Vector3> _Geometry::segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius) {
Vector<Vector3> r; Vector<Vector3> r;
Vector3 res, norm; Vector3 res, norm;
if (!Geometry::segment_intersects_sphere(p_from, p_to, p_sphere_pos, p_sphere_radius, &res, &norm)) if (!Geometry::segment_intersects_sphere(p_from, p_to, p_sphere_pos, p_sphere_radius, &res, &norm)) {
return r; return r;
}
r.resize(2); r.resize(2);
r.set(0, res); r.set(0, res);
@ -922,8 +930,9 @@ Vector<Vector3> _Geometry::segment_intersects_sphere(const Vector3 &p_from, cons
Vector<Vector3> _Geometry::segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius) { Vector<Vector3> _Geometry::segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius) {
Vector<Vector3> r; Vector<Vector3> r;
Vector3 res, norm; Vector3 res, norm;
if (!Geometry::segment_intersects_cylinder(p_from, p_to, p_height, p_radius, &res, &norm)) if (!Geometry::segment_intersects_cylinder(p_from, p_to, p_height, p_radius, &res, &norm)) {
return r; return r;
}
r.resize(2); r.resize(2);
r.set(0, res); r.set(0, res);
@ -934,8 +943,9 @@ Vector<Vector3> _Geometry::segment_intersects_cylinder(const Vector3 &p_from, co
Vector<Vector3> _Geometry::segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes) { Vector<Vector3> _Geometry::segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes) {
Vector<Vector3> r; Vector<Vector3> r;
Vector3 res, norm; Vector3 res, norm;
if (!Geometry::segment_intersects_convex(p_from, p_to, p_planes.ptr(), p_planes.size(), &res, &norm)) if (!Geometry::segment_intersects_convex(p_from, p_to, p_planes.ptr(), p_planes.size(), &res, &norm)) {
return r; return r;
}
r.resize(2); r.resize(2);
r.set(0, res); r.set(0, res);
@ -1151,8 +1161,9 @@ void _Geometry::_bind_methods() {
Error _File::open_encrypted(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key) { Error _File::open_encrypted(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key) {
Error err = open(p_path, p_mode_flags); Error err = open(p_path, p_mode_flags);
if (err) if (err) {
return err; return err;
}
FileAccessEncrypted *fae = memnew(FileAccessEncrypted); FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse(f, p_key, (p_mode_flags == WRITE) ? FileAccessEncrypted::MODE_WRITE_AES256 : FileAccessEncrypted::MODE_READ); err = fae->open_and_parse(f, p_key, (p_mode_flags == WRITE) ? FileAccessEncrypted::MODE_WRITE_AES256 : FileAccessEncrypted::MODE_READ);
@ -1167,8 +1178,9 @@ Error _File::open_encrypted(const String &p_path, ModeFlags p_mode_flags, const
Error _File::open_encrypted_pass(const String &p_path, ModeFlags p_mode_flags, const String &p_pass) { Error _File::open_encrypted_pass(const String &p_path, ModeFlags p_mode_flags, const String &p_pass) {
Error err = open(p_path, p_mode_flags); Error err = open(p_path, p_mode_flags);
if (err) if (err) {
return err; return err;
}
FileAccessEncrypted *fae = memnew(FileAccessEncrypted); FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse_password(f, p_pass, (p_mode_flags == WRITE) ? FileAccessEncrypted::MODE_WRITE_AES256 : FileAccessEncrypted::MODE_READ); err = fae->open_and_parse_password(f, p_pass, (p_mode_flags == WRITE) ? FileAccessEncrypted::MODE_WRITE_AES256 : FileAccessEncrypted::MODE_READ);
@ -1202,14 +1214,16 @@ Error _File::open(const String &p_path, ModeFlags p_mode_flags) {
close(); close();
Error err; Error err;
f = FileAccess::open(p_path, p_mode_flags, &err); f = FileAccess::open(p_path, p_mode_flags, &err);
if (f) if (f) {
f->set_endian_swap(eswap); f->set_endian_swap(eswap);
}
return err; return err;
} }
void _File::close() { void _File::close() {
if (f) if (f) {
memdelete(f); memdelete(f);
}
f = nullptr; f = nullptr;
} }
@ -1292,8 +1306,9 @@ Vector<uint8_t> _File::get_buffer(int p_length) const {
ERR_FAIL_COND_V_MSG(!f, data, "File must be opened before use."); ERR_FAIL_COND_V_MSG(!f, data, "File must be opened before use.");
ERR_FAIL_COND_V_MSG(p_length < 0, data, "Length of buffer cannot be smaller than 0."); ERR_FAIL_COND_V_MSG(p_length < 0, data, "Length of buffer cannot be smaller than 0.");
if (p_length == 0) if (p_length == 0) {
return data; return data;
}
Error err = data.resize(p_length); Error err = data.resize(p_length);
ERR_FAIL_COND_V_MSG(err != OK, data, "Can't resize data to " + itos(p_length) + " elements."); ERR_FAIL_COND_V_MSG(err != OK, data, "Can't resize data to " + itos(p_length) + " elements.");
@ -1302,8 +1317,9 @@ Vector<uint8_t> _File::get_buffer(int p_length) const {
int len = f->get_buffer(&w[0], p_length); int len = f->get_buffer(&w[0], p_length);
ERR_FAIL_COND_V(len < 0, Vector<uint8_t>()); ERR_FAIL_COND_V(len < 0, Vector<uint8_t>());
if (len < p_length) if (len < p_length) {
data.resize(p_length); data.resize(p_length);
}
return data; return data;
} }
@ -1352,8 +1368,9 @@ Vector<String> _File::get_csv_line(const String &p_delim) const {
void _File::set_endian_swap(bool p_swap) { void _File::set_endian_swap(bool p_swap) {
eswap = p_swap; eswap = p_swap;
if (f) if (f) {
f->set_endian_swap(p_swap); f->set_endian_swap(p_swap);
}
} }
bool _File::get_endian_swap() { bool _File::get_endian_swap() {
@ -1361,8 +1378,9 @@ bool _File::get_endian_swap() {
} }
Error _File::get_error() const { Error _File::get_error() const {
if (!f) if (!f) {
return ERR_UNCONFIGURED; return ERR_UNCONFIGURED;
}
return f->get_error(); return f->get_error();
} }
@ -1440,8 +1458,9 @@ void _File::store_buffer(const Vector<uint8_t> &p_buffer) {
ERR_FAIL_COND_MSG(!f, "File must be opened before use."); ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
int len = p_buffer.size(); int len = p_buffer.size();
if (len == 0) if (len == 0) {
return; return;
}
const uint8_t *r = p_buffer.ptr(); const uint8_t *r = p_buffer.ptr();
@ -1554,8 +1573,9 @@ void _File::_bind_methods() {
} }
_File::~_File() { _File::~_File() {
if (f) if (f) {
memdelete(f); memdelete(f);
}
} }
////// _Directory ////// ////// _Directory //////
@ -1564,10 +1584,12 @@ Error _Directory::open(const String &p_path) {
Error err; Error err;
DirAccess *alt = DirAccess::open(p_path, &err); DirAccess *alt = DirAccess::open(p_path, &err);
if (!alt) if (!alt) {
return err; return err;
if (d) }
if (d) {
memdelete(d); memdelete(d);
}
d = alt; d = alt;
return OK; return OK;
@ -1733,8 +1755,9 @@ _Directory::_Directory() {
} }
_Directory::~_Directory() { _Directory::~_Directory() {
if (d) if (d) {
memdelete(d); memdelete(d);
}
} }
////// _Marshalls ////// ////// _Marshalls //////
@ -1943,8 +1966,9 @@ Error _Thread::start(Object *p_instance, const StringName &p_method, const Varia
} }
String _Thread::get_id() const { String _Thread::get_id() const {
if (!thread) if (!thread) {
return String(); return String();
}
return itos(thread->get_id()); return itos(thread->get_id());
} }
@ -1962,8 +1986,9 @@ Variant _Thread::wait_to_finish() {
target_method = StringName(); target_method = StringName();
target_instance = nullptr; target_instance = nullptr;
userdata = Variant(); userdata = Variant();
if (thread) if (thread) {
memdelete(thread); memdelete(thread);
}
thread = nullptr; thread = nullptr;
return r; return r;
@ -2032,8 +2057,9 @@ bool _ClassDB::can_instance(const StringName &p_class) const {
Variant _ClassDB::instance(const StringName &p_class) const { Variant _ClassDB::instance(const StringName &p_class) const {
Object *obj = ClassDB::instance(p_class); Object *obj = ClassDB::instance(p_class);
if (!obj) if (!obj) {
return Variant(); return Variant();
}
Reference *r = Object::cast_to<Reference>(obj); Reference *r = Object::cast_to<Reference>(obj);
if (r) { if (r) {

View File

@ -248,8 +248,9 @@ bool ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inh
StringName inherits = p_class; StringName inherits = p_class;
while (inherits.operator String().length()) { while (inherits.operator String().length()) {
if (inherits == p_inherits) if (inherits == p_inherits) {
return true; return true;
}
inherits = get_parent_class(inherits); inherits = get_parent_class(inherits);
} }
@ -274,8 +275,9 @@ void ClassDB::get_inheriters_from_class(const StringName &p_class, List<StringNa
const StringName *k = nullptr; const StringName *k = nullptr;
while ((k = classes.next(k))) { while ((k = classes.next(k))) {
if (*k != p_class && is_parent_class(*k, p_class)) if (*k != p_class && is_parent_class(*k, p_class)) {
p_classes->push_back(*k); p_classes->push_back(*k);
}
} }
} }
@ -285,8 +287,9 @@ void ClassDB::get_direct_inheriters_from_class(const StringName &p_class, List<S
const StringName *k = nullptr; const StringName *k = nullptr;
while ((k = classes.next(k))) { while ((k = classes.next(k))) {
if (*k != p_class && get_parent_class(*k) == p_class) if (*k != p_class && get_parent_class(*k) == p_class) {
p_classes->push_back(*k); p_classes->push_back(*k);
}
} }
} }
@ -294,8 +297,9 @@ StringName ClassDB::get_parent_class_nocheck(const StringName &p_class) {
OBJTYPE_RLOCK; OBJTYPE_RLOCK;
ClassInfo *ti = classes.getptr(p_class); ClassInfo *ti = classes.getptr(p_class);
if (!ti) if (!ti) {
return StringName(); return StringName();
}
return ti->inherits; return ti->inherits;
} }
@ -347,8 +351,9 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
for (List<StringName>::Element *E = names.front(); E; E = E->next()) { for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
ClassInfo *t = classes.getptr(E->get()); ClassInfo *t = classes.getptr(E->get());
ERR_FAIL_COND_V_MSG(!t, 0, "Cannot get class '" + String(E->get()) + "'."); ERR_FAIL_COND_V_MSG(!t, 0, "Cannot get class '" + String(E->get()) + "'.");
if (t->api != p_api || !t->exposed) if (t->api != p_api || !t->exposed) {
continue; continue;
}
hash = hash_djb2_one_64(t->name.hash(), hash); hash = hash_djb2_one_64(t->name.hash(), hash);
hash = hash_djb2_one_64(t->inherits.hash(), hash); hash = hash_djb2_one_64(t->inherits.hash(), hash);
@ -363,8 +368,9 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
ERR_CONTINUE(name.empty()); ERR_CONTINUE(name.empty());
if (name[0] == '_') if (name[0] == '_') {
continue; // Ignore non-virtual methods that start with an underscore continue; // Ignore non-virtual methods that start with an underscore
}
snames.push_back(*k); snames.push_back(*k);
} }
@ -549,8 +555,9 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
while (type) { while (type) {
if (type->disabled) { if (type->disabled) {
if (p_no_inheritance) if (p_no_inheritance) {
break; break;
}
type = type->inherits_ptr; type = type->inherits_ptr;
continue; continue;
@ -568,8 +575,9 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
minfo.name = E->get(); minfo.name = E->get();
minfo.id = method->get_method_id(); minfo.id = method->get_method_id();
if (p_exclude_from_properties && type->methods_in_properties.has(minfo.name)) if (p_exclude_from_properties && type->methods_in_properties.has(minfo.name)) {
continue; continue;
}
for (int i = 0; i < method->get_argument_count(); i++) { for (int i = 0; i < method->get_argument_count(); i++) {
//Variant::Type t=method->get_argument_type(i); //Variant::Type t=method->get_argument_type(i);
@ -581,8 +589,9 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
minfo.flags = method->get_hint_flags(); minfo.flags = method->get_hint_flags();
for (int i = 0; i < method->get_argument_count(); i++) { for (int i = 0; i < method->get_argument_count(); i++) {
if (method->has_default_argument(i)) if (method->has_default_argument(i)) {
minfo.default_arguments.push_back(method->get_default_argument(i)); minfo.default_arguments.push_back(method->get_default_argument(i));
}
} }
p_methods->push_back(minfo); p_methods->push_back(minfo);
@ -601,8 +610,9 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
#endif #endif
if (p_no_inheritance) if (p_no_inheritance) {
break; break;
}
type = type->inherits_ptr; type = type->inherits_ptr;
} }
@ -615,8 +625,9 @@ MethodBind *ClassDB::get_method(StringName p_class, StringName p_name) {
while (type) { while (type) {
MethodBind **method = type->method_map.getptr(p_name); MethodBind **method = type->method_map.getptr(p_name);
if (method && *method) if (method && *method) {
return *method; return *method;
}
type = type->inherits_ptr; type = type->inherits_ptr;
} }
return nullptr; return nullptr;
@ -664,8 +675,9 @@ void ClassDB::get_integer_constant_list(const StringName &p_class, List<String>
while (type) { while (type) {
#ifdef DEBUG_METHODS_ENABLED #ifdef DEBUG_METHODS_ENABLED
for (List<StringName>::Element *E = type->constant_order.front(); E; E = E->next()) for (List<StringName>::Element *E = type->constant_order.front(); E; E = E->next()) {
p_constants->push_back(E->get()); p_constants->push_back(E->get());
}
#else #else
const StringName *K = nullptr; const StringName *K = nullptr;
@ -674,8 +686,9 @@ void ClassDB::get_integer_constant_list(const StringName &p_class, List<String>
} }
#endif #endif
if (p_no_inheritance) if (p_no_inheritance) {
break; break;
}
type = type->inherits_ptr; type = type->inherits_ptr;
} }
@ -689,16 +702,18 @@ int ClassDB::get_integer_constant(const StringName &p_class, const StringName &p
while (type) { while (type) {
int *constant = type->constant_map.getptr(p_name); int *constant = type->constant_map.getptr(p_name);
if (constant) { if (constant) {
if (p_success) if (p_success) {
*p_success = true; *p_success = true;
}
return *constant; return *constant;
} }
type = type->inherits_ptr; type = type->inherits_ptr;
} }
if (p_success) if (p_success) {
*p_success = false; *p_success = false;
}
return 0; return 0;
} }
@ -713,12 +728,14 @@ StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const S
while ((k = type->enum_map.next(k))) { while ((k = type->enum_map.next(k))) {
List<StringName> &constants_list = type->enum_map.get(*k); List<StringName> &constants_list = type->enum_map.get(*k);
const List<StringName>::Element *found = constants_list.find(p_name); const List<StringName>::Element *found = constants_list.find(p_name);
if (found) if (found) {
return *k; return *k;
}
} }
if (p_no_inheritance) if (p_no_inheritance) {
break; break;
}
type = type->inherits_ptr; type = type->inherits_ptr;
} }
@ -737,8 +754,9 @@ void ClassDB::get_enum_list(const StringName &p_class, List<StringName> *p_enums
p_enums->push_back(*k); p_enums->push_back(*k);
} }
if (p_no_inheritance) if (p_no_inheritance) {
break; break;
}
type = type->inherits_ptr; type = type->inherits_ptr;
} }
@ -758,8 +776,9 @@ void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_
} }
} }
if (p_no_inheritance) if (p_no_inheritance) {
break; break;
}
type = type->inherits_ptr; type = type->inherits_ptr;
} }
@ -798,8 +817,9 @@ void ClassDB::get_signal_list(StringName p_class, List<MethodInfo> *p_signals, b
p_signals->push_back(check->signal_map[*S]); p_signals->push_back(check->signal_map[*S]);
} }
if (p_no_inheritance) if (p_no_inheritance) {
return; return;
}
check = check->inherits_ptr; check = check->inherits_ptr;
} }
@ -810,8 +830,9 @@ bool ClassDB::has_signal(StringName p_class, StringName p_signal) {
ClassInfo *type = classes.getptr(p_class); ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type; ClassInfo *check = type;
while (check) { while (check) {
if (check->signal_map.has(p_signal)) if (check->signal_map.has(p_signal)) {
return true; return true;
}
check = check->inherits_ptr; check = check->inherits_ptr;
} }
@ -931,8 +952,9 @@ void ClassDB::get_property_list(StringName p_class, List<PropertyInfo> *p_list,
} }
} }
if (p_no_inheritance) if (p_no_inheritance) {
return; return;
}
check = check->inherits_ptr; check = check->inherits_ptr;
} }
} }
@ -944,8 +966,9 @@ bool ClassDB::set_property(Object *p_object, const StringName &p_property, const
const PropertySetGet *psg = check->property_setget.getptr(p_property); const PropertySetGet *psg = check->property_setget.getptr(p_property);
if (psg) { if (psg) {
if (!psg->setter) { if (!psg->setter) {
if (r_valid) if (r_valid) {
*r_valid = false; *r_valid = false;
}
return true; //return true but do nothing return true; //return true but do nothing
} }
@ -970,8 +993,9 @@ bool ClassDB::set_property(Object *p_object, const StringName &p_property, const
} }
} }
if (r_valid) if (r_valid) {
*r_valid = ce.error == Callable::CallError::CALL_OK; *r_valid = ce.error == Callable::CallError::CALL_OK;
}
return true; return true;
} }
@ -988,8 +1012,9 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia
while (check) { while (check) {
const PropertySetGet *psg = check->property_setget.getptr(p_property); const PropertySetGet *psg = check->property_setget.getptr(p_property);
if (psg) { if (psg) {
if (!psg->getter) if (!psg->getter) {
return true; //return true but do nothing return true; //return true but do nothing
}
if (psg->index >= 0) { if (psg->index >= 0) {
Variant index = psg->index; Variant index = psg->index;
@ -1036,16 +1061,18 @@ int ClassDB::get_property_index(const StringName &p_class, const StringName &p_p
while (check) { while (check) {
const PropertySetGet *psg = check->property_setget.getptr(p_property); const PropertySetGet *psg = check->property_setget.getptr(p_property);
if (psg) { if (psg) {
if (r_is_valid) if (r_is_valid) {
*r_is_valid = true; *r_is_valid = true;
}
return psg->index; return psg->index;
} }
check = check->inherits_ptr; check = check->inherits_ptr;
} }
if (r_is_valid) if (r_is_valid) {
*r_is_valid = false; *r_is_valid = false;
}
return -1; return -1;
} }
@ -1056,16 +1083,18 @@ Variant::Type ClassDB::get_property_type(const StringName &p_class, const String
while (check) { while (check) {
const PropertySetGet *psg = check->property_setget.getptr(p_property); const PropertySetGet *psg = check->property_setget.getptr(p_property);
if (psg) { if (psg) {
if (r_is_valid) if (r_is_valid) {
*r_is_valid = true; *r_is_valid = true;
}
return psg->type; return psg->type;
} }
check = check->inherits_ptr; check = check->inherits_ptr;
} }
if (r_is_valid) if (r_is_valid) {
*r_is_valid = false; *r_is_valid = false;
}
return Variant::NIL; return Variant::NIL;
} }
@ -1104,11 +1133,13 @@ bool ClassDB::has_property(const StringName &p_class, const StringName &p_proper
ClassInfo *type = classes.getptr(p_class); ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type; ClassInfo *check = type;
while (check) { while (check) {
if (check->property_setget.has(p_property)) if (check->property_setget.has(p_property)) {
return true; return true;
}
if (p_no_inheritance) if (p_no_inheritance) {
break; break;
}
check = check->inherits_ptr; check = check->inherits_ptr;
} }
@ -1128,10 +1159,12 @@ bool ClassDB::has_method(StringName p_class, StringName p_method, bool p_no_inhe
ClassInfo *type = classes.getptr(p_class); ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type; ClassInfo *check = type;
while (check) { while (check) {
if (check->method_map.has(p_method)) if (check->method_map.has(p_method)) {
return true; return true;
if (p_no_inheritance) }
if (p_no_inheritance) {
return false; return false;
}
check = check->inherits_ptr; check = check->inherits_ptr;
} }
@ -1202,8 +1235,9 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_
#ifdef DEBUG_METHODS_ENABLED #ifdef DEBUG_METHODS_ENABLED
MethodInfo mi = p_method; MethodInfo mi = p_method;
if (p_virtual) if (p_virtual) {
mi.flags |= METHOD_FLAG_VIRTUAL; mi.flags |= METHOD_FLAG_VIRTUAL;
}
classes[p_class].virtual_methods.push_back(mi); classes[p_class].virtual_methods.push_back(mi);
#endif #endif
@ -1221,8 +1255,9 @@ void ClassDB::get_virtual_methods(const StringName &p_class, List<MethodInfo> *p
p_methods->push_back(E->get()); p_methods->push_back(E->get());
} }
if (p_no_inheritance) if (p_no_inheritance) {
return; return;
}
check = check->inherits_ptr; check = check->inherits_ptr;
} }
@ -1268,8 +1303,9 @@ StringName ClassDB::get_category(const StringName &p_node) {
} }
void ClassDB::add_resource_base_extension(const StringName &p_extension, const StringName &p_class) { void ClassDB::add_resource_base_extension(const StringName &p_extension, const StringName &p_class) {
if (resource_base_extensions.has(p_extension)) if (resource_base_extensions.has(p_extension)) {
return; return;
}
resource_base_extensions[p_extension] = p_class; resource_base_extensions[p_extension] = p_class;
} }
@ -1287,8 +1323,9 @@ void ClassDB::get_extensions_for_type(const StringName &p_class, List<String> *p
while ((K = resource_base_extensions.next(K))) { while ((K = resource_base_extensions.next(K))) {
StringName cmp = resource_base_extensions[*K]; StringName cmp = resource_base_extensions[*K];
if (is_parent_class(p_class, cmp) || is_parent_class(cmp, p_class)) if (is_parent_class(p_class, cmp) || is_parent_class(cmp, p_class)) {
p_extensions->push_back(*K); p_extensions->push_back(*K);
}
} }
} }
@ -1333,19 +1370,22 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con
} }
if (!default_values.has(p_class)) { if (!default_values.has(p_class)) {
if (r_valid != nullptr) if (r_valid != nullptr) {
*r_valid = false; *r_valid = false;
}
return Variant(); return Variant();
} }
if (!default_values[p_class].has(p_property)) { if (!default_values[p_class].has(p_property)) {
if (r_valid != nullptr) if (r_valid != nullptr) {
*r_valid = false; *r_valid = false;
}
return Variant(); return Variant();
} }
if (r_valid != nullptr) if (r_valid != nullptr) {
*r_valid = true; *r_valid = true;
}
return default_values[p_class][p_property]; return default_values[p_class][p_property];
} }

View File

@ -115,20 +115,23 @@ float Color::get_h() const {
float delta = max - min; float delta = max - min;
if (delta == 0) if (delta == 0) {
return 0; return 0;
}
float h; float h;
if (r == max) if (r == max) {
h = (g - b) / delta; // between yellow & magenta h = (g - b) / delta; // between yellow & magenta
else if (g == max) } else if (g == max) {
h = 2 + (b - r) / delta; // between cyan & yellow h = 2 + (b - r) / delta; // between cyan & yellow
else } else {
h = 4 + (r - g) / delta; // between magenta & cyan h = 4 + (r - g) / delta; // between magenta & cyan
}
h /= 6.0; h /= 6.0;
if (h < 0) if (h < 0) {
h += 1.0; h += 1.0;
}
return h; return h;
} }
@ -277,10 +280,11 @@ static float _parse_col(const String &p_str, int p_ofs) {
return -1; return -1;
} }
if (i == 0) if (i == 0) {
ig += v * 16; ig += v * 16;
else } else {
ig += v; ig += v;
}
} }
return ig; return ig;
@ -300,10 +304,12 @@ Color Color::contrasted() const {
Color Color::html(const String &p_color) { Color Color::html(const String &p_color) {
String color = p_color; String color = p_color;
if (color.length() == 0) if (color.length() == 0) {
return Color(); return Color();
if (color[0] == '#') }
if (color[0] == '#') {
color = color.substr(1, color.length() - 1); color = color.substr(1, color.length() - 1);
}
if (color.length() == 3 || color.length() == 4) { if (color.length() == 3 || color.length() == 4) {
String exp_color; String exp_color;
for (int i = 0; i < color.length(); i++) { for (int i = 0; i < color.length(); i++) {
@ -344,10 +350,12 @@ Color Color::html(const String &p_color) {
bool Color::html_is_valid(const String &p_color) { bool Color::html_is_valid(const String &p_color) {
String color = p_color; String color = p_color;
if (color.length() == 0) if (color.length() == 0) {
return false; return false;
if (color[0] == '#') }
if (color[0] == '#') {
color = color.substr(1, color.length() - 1); color = color.substr(1, color.length() - 1);
}
bool alpha = false; bool alpha = false;
@ -385,8 +393,9 @@ bool Color::html_is_valid(const String &p_color) {
} }
Color Color::named(const String &p_name) { Color Color::named(const String &p_name) {
if (_named_colors.empty()) if (_named_colors.empty()) {
_populate_named_colors(); // from color_names.inc _populate_named_colors(); // from color_names.inc
}
String name = p_name; String name = p_name;
// Normalize name // Normalize name
name = name.replace(" ", ""); name = name.replace(" ", "");
@ -409,10 +418,11 @@ String _to_hex(float p_val) {
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
CharType c[2] = { 0, 0 }; CharType c[2] = { 0, 0 };
int lv = v & 0xF; int lv = v & 0xF;
if (lv < 10) if (lv < 10) {
c[0] = '0' + lv; c[0] = '0' + lv;
else } else {
c[0] = 'a' + lv - 10; c[0] = 'a' + lv - 10;
}
v >>= 4; v >>= 4;
String cs = (const CharType *)c; String cs = (const CharType *)c;
@ -427,15 +437,17 @@ String Color::to_html(bool p_alpha) const {
txt += _to_hex(r); txt += _to_hex(r);
txt += _to_hex(g); txt += _to_hex(g);
txt += _to_hex(b); txt += _to_hex(b);
if (p_alpha) if (p_alpha) {
txt = _to_hex(a) + txt; txt = _to_hex(a) + txt;
}
return txt; return txt;
} }
Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const { Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const {
p_h = Math::fmod(p_h * 360.0f, 360.0f); p_h = Math::fmod(p_h * 360.0f, 360.0f);
if (p_h < 0.0) if (p_h < 0.0) {
p_h += 360.0f; p_h += 360.0f;
}
const float h_ = p_h / 60.0f; const float h_ = p_h / 60.0f;
const float c = p_v * p_s; const float c = p_v * p_s;

View File

@ -223,12 +223,15 @@ bool Color::operator<(const Color &p_color) const {
if (g == p_color.g) { if (g == p_color.g) {
if (b == p_color.b) { if (b == p_color.b) {
return (a < p_color.a); return (a < p_color.a);
} else } else {
return (b < p_color.b); return (b < p_color.b);
} else }
} else {
return g < p_color.g; return g < p_color.g;
} else }
} else {
return r < p_color.r; return r < p_color.r;
}
} }
#endif // COLOR_H #endif // COLOR_H

View File

@ -3,8 +3,9 @@
static Map<String, Color> _named_colors; static Map<String, Color> _named_colors;
static void _populate_named_colors() { static void _populate_named_colors() {
if (!_named_colors.empty()) if (!_named_colors.empty()) {
return; return;
}
_named_colors.insert("aliceblue", Color(0.94, 0.97, 1.00)); _named_colors.insert("aliceblue", Color(0.94, 0.97, 1.00));
_named_colors.insert("antiquewhite", Color(0.98, 0.92, 0.84)); _named_colors.insert("antiquewhite", Color(0.98, 0.92, 0.84));
_named_colors.insert("aqua", Color(0.00, 1.00, 1.00)); _named_colors.insert("aqua", Color(0.00, 1.00, 1.00));

View File

@ -94,12 +94,14 @@ tryagain:
} }
CommandQueueMT::CommandQueueMT(bool p_sync) { CommandQueueMT::CommandQueueMT(bool p_sync) {
if (p_sync) if (p_sync) {
sync = memnew(Semaphore); sync = memnew(Semaphore);
}
} }
CommandQueueMT::~CommandQueueMT() { CommandQueueMT::~CommandQueueMT() {
if (sync) if (sync) {
memdelete(sync); memdelete(sync);
}
memfree(command_mem); memfree(command_mem);
} }

View File

@ -413,14 +413,16 @@ class CommandQueueMT {
} }
bool flush_one(bool p_lock = true) { bool flush_one(bool p_lock = true) {
if (p_lock) if (p_lock) {
lock(); lock();
}
tryagain: tryagain:
// tried to read an empty queue // tried to read an empty queue
if (read_ptr == write_ptr) { if (read_ptr == write_ptr) {
if (p_lock) if (p_lock) {
unlock(); unlock();
}
return false; return false;
} }
@ -439,18 +441,21 @@ class CommandQueueMT {
read_ptr += size; read_ptr += size;
if (p_lock) if (p_lock) {
unlock(); unlock();
}
cmd->call(); cmd->call();
if (p_lock) if (p_lock) {
lock(); lock();
}
cmd->post(); cmd->post();
cmd->~CommandBase(); cmd->~CommandBase();
*(uint32_t *)&command_mem[size_ptr] &= ~1; *(uint32_t *)&command_mem[size_ptr] &= ~1;
if (p_lock) if (p_lock) {
unlock(); unlock();
}
return true; return true;
} }
@ -482,8 +487,8 @@ public:
void flush_all() { void flush_all() {
//ERR_FAIL_COND(sync); //ERR_FAIL_COND(sync);
lock(); lock();
while (flush_one(false)) while (flush_one(false)) {
; }
unlock(); unlock();
} }

View File

@ -109,8 +109,9 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
const Vector<Pair<int, CharString>> &b = buckets[i]; const Vector<Pair<int, CharString>> &b = buckets[i];
Map<uint32_t, int> &t = table.write[i]; Map<uint32_t, int> &t = table.write[i];
if (b.size() == 0) if (b.size() == 0) {
continue; continue;
}
int d = 1; int d = 1;
int item = 0; int item = 0;
@ -189,22 +190,24 @@ bool PHashTranslation::_set(const StringName &p_name, const Variant &p_value) {
strings = p_value; strings = p_value;
} else if (name == "load_from") { } else if (name == "load_from") {
generate(p_value); generate(p_value);
} else } else {
return false; return false;
}
return true; return true;
} }
bool PHashTranslation::_get(const StringName &p_name, Variant &r_ret) const { bool PHashTranslation::_get(const StringName &p_name, Variant &r_ret) const {
String name = p_name.operator String(); String name = p_name.operator String();
if (name == "hash_table") if (name == "hash_table") {
r_ret = hash_table; r_ret = hash_table;
else if (name == "bucket_table") } else if (name == "bucket_table") {
r_ret = bucket_table; r_ret = bucket_table;
else if (name == "strings") } else if (name == "strings") {
r_ret = strings; r_ret = strings;
else } else {
return false; return false;
}
return true; return true;
} }
@ -212,8 +215,9 @@ bool PHashTranslation::_get(const StringName &p_name, Variant &r_ret) const {
StringName PHashTranslation::get_message(const StringName &p_src_text) const { StringName PHashTranslation::get_message(const StringName &p_src_text) const {
int htsize = hash_table.size(); int htsize = hash_table.size();
if (htsize == 0) if (htsize == 0) {
return StringName(); return StringName();
}
CharString str = p_src_text.operator String().utf8(); CharString str = p_src_text.operator String().utf8();
uint32_t h = hash(0, str.get_data()); uint32_t h = hash(0, str.get_data());

View File

@ -61,8 +61,9 @@ class PHashTranslation : public Translation {
}; };
_FORCE_INLINE_ uint32_t hash(uint32_t d, const char *p_str) const { _FORCE_INLINE_ uint32_t hash(uint32_t d, const char *p_str) const {
if (d == 0) if (d == 0) {
d = 0x1000193; d = 0x1000193;
}
while (*p_str) { while (*p_str) {
d = (d * 0x1000193) ^ uint32_t(*p_str); d = (d * 0x1000193) ^ uint32_t(*p_str);
p_str++; p_str++;

View File

@ -59,22 +59,25 @@ private:
// internal helpers // internal helpers
_FORCE_INLINE_ uint32_t *_get_refcount() const { _FORCE_INLINE_ uint32_t *_get_refcount() const {
if (!_ptr) if (!_ptr) {
return nullptr; return nullptr;
}
return reinterpret_cast<uint32_t *>(_ptr) - 2; return reinterpret_cast<uint32_t *>(_ptr) - 2;
} }
_FORCE_INLINE_ uint32_t *_get_size() const { _FORCE_INLINE_ uint32_t *_get_size() const {
if (!_ptr) if (!_ptr) {
return nullptr; return nullptr;
}
return reinterpret_cast<uint32_t *>(_ptr) - 1; return reinterpret_cast<uint32_t *>(_ptr) - 1;
} }
_FORCE_INLINE_ T *_get_data() const { _FORCE_INLINE_ T *_get_data() const {
if (!_ptr) if (!_ptr) {
return nullptr; return nullptr;
}
return reinterpret_cast<T *>(_ptr); return reinterpret_cast<T *>(_ptr);
} }
@ -122,10 +125,11 @@ public:
_FORCE_INLINE_ int size() const { _FORCE_INLINE_ int size() const {
uint32_t *size = (uint32_t *)_get_size(); uint32_t *size = (uint32_t *)_get_size();
if (size) if (size) {
return *size; return *size;
else } else {
return 0; return 0;
}
} }
_FORCE_INLINE_ void clear() { resize(0); } _FORCE_INLINE_ void clear() { resize(0); }
@ -165,8 +169,9 @@ public:
Error insert(int p_pos, const T &p_val) { Error insert(int p_pos, const T &p_val) {
ERR_FAIL_INDEX_V(p_pos, size() + 1, ERR_INVALID_PARAMETER); ERR_FAIL_INDEX_V(p_pos, size() + 1, ERR_INVALID_PARAMETER);
resize(size() + 1); resize(size() + 1);
for (int i = (size() - 1); i > p_pos; i--) for (int i = (size() - 1); i > p_pos; i--) {
set(i, get(i - 1)); set(i, get(i - 1));
}
set(p_pos, p_val); set(p_pos, p_val);
return OK; return OK;
@ -181,13 +186,15 @@ public:
template <class T> template <class T>
void CowData<T>::_unref(void *p_data) { void CowData<T>::_unref(void *p_data) {
if (!p_data) if (!p_data) {
return; return;
}
uint32_t *refc = _get_refcount(); uint32_t *refc = _get_refcount();
if (atomic_decrement(refc) > 0) if (atomic_decrement(refc) > 0) {
return; // still in use return; // still in use
}
// clean up // clean up
if (!__has_trivial_destructor(T)) { if (!__has_trivial_destructor(T)) {
@ -206,8 +213,9 @@ void CowData<T>::_unref(void *p_data) {
template <class T> template <class T>
void CowData<T>::_copy_on_write() { void CowData<T>::_copy_on_write() {
if (!_ptr) if (!_ptr) {
return; return;
}
uint32_t *refc = _get_refcount(); uint32_t *refc = _get_refcount();
@ -243,8 +251,9 @@ Error CowData<T>::resize(int p_size) {
int current_size = size(); int current_size = size();
if (p_size == current_size) if (p_size == current_size) {
return OK; return OK;
}
if (p_size == 0) { if (p_size == 0) {
// wants to clean up // wants to clean up
@ -337,14 +346,16 @@ void CowData<T>::_ref(const CowData *p_from) {
template <class T> template <class T>
void CowData<T>::_ref(const CowData &p_from) { void CowData<T>::_ref(const CowData &p_from) {
if (_ptr == p_from._ptr) if (_ptr == p_from._ptr) {
return; // self assign, do nothing. return; // self assign, do nothing.
}
_unref(_ptr); _unref(_ptr);
_ptr = nullptr; _ptr = nullptr;
if (!p_from._ptr) if (!p_from._ptr) {
return; //nothing to do return; //nothing to do
}
if (atomic_conditional_increment(p_from._get_refcount()) > 0) { // could reference if (atomic_conditional_increment(p_from._get_refcount()) > 0) { // could reference
_ptr = p_from._ptr; _ptr = p_from._ptr;

View File

@ -38,8 +38,9 @@
CryptoKey *(*CryptoKey::_create)() = nullptr; CryptoKey *(*CryptoKey::_create)() = nullptr;
CryptoKey *CryptoKey::create() { CryptoKey *CryptoKey::create() {
if (_create) if (_create) {
return _create(); return _create();
}
return nullptr; return nullptr;
} }
@ -50,8 +51,9 @@ void CryptoKey::_bind_methods() {
X509Certificate *(*X509Certificate::_create)() = nullptr; X509Certificate *(*X509Certificate::_create)() = nullptr;
X509Certificate *X509Certificate::create() { X509Certificate *X509Certificate::create() {
if (_create) if (_create) {
return _create(); return _create();
}
return nullptr; return nullptr;
} }
@ -65,14 +67,16 @@ void X509Certificate::_bind_methods() {
void (*Crypto::_load_default_certificates)(String p_path) = nullptr; void (*Crypto::_load_default_certificates)(String p_path) = nullptr;
Crypto *(*Crypto::_create)() = nullptr; Crypto *(*Crypto::_create)() = nullptr;
Crypto *Crypto::create() { Crypto *Crypto::create() {
if (_create) if (_create) {
return _create(); return _create();
}
return memnew(Crypto); return memnew(Crypto);
} }
void Crypto::load_default_certificates(String p_path) { void Crypto::load_default_certificates(String p_path) {
if (_load_default_certificates) if (_load_default_certificates) {
_load_default_certificates(p_path); _load_default_certificates(p_path);
}
} }
void Crypto::_bind_methods() { void Crypto::_bind_methods() {
@ -99,13 +103,15 @@ RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_origi
String el = p_path.get_extension().to_lower(); String el = p_path.get_extension().to_lower();
if (el == "crt") { if (el == "crt") {
X509Certificate *cert = X509Certificate::create(); X509Certificate *cert = X509Certificate::create();
if (cert) if (cert) {
cert->load(p_path); cert->load(p_path);
}
return cert; return cert;
} else if (el == "key") { } else if (el == "key") {
CryptoKey *key = CryptoKey::create(); CryptoKey *key = CryptoKey::create();
if (key) if (key) {
key->load(p_path); key->load(p_path);
}
return key; return key;
} }
return nullptr; return nullptr;
@ -122,10 +128,11 @@ bool ResourceFormatLoaderCrypto::handles_type(const String &p_type) const {
String ResourceFormatLoaderCrypto::get_resource_type(const String &p_path) const { String ResourceFormatLoaderCrypto::get_resource_type(const String &p_path) const {
String el = p_path.get_extension().to_lower(); String el = p_path.get_extension().to_lower();
if (el == "crt") if (el == "crt") {
return "X509Certificate"; return "X509Certificate";
else if (el == "key") } else if (el == "key") {
return "CryptoKey"; return "CryptoKey";
}
return ""; return "";
} }

View File

@ -128,6 +128,7 @@ void HashingContext::_bind_methods() {
} }
HashingContext::~HashingContext() { HashingContext::~HashingContext() {
if (ctx != nullptr) if (ctx != nullptr) {
_delete_ctx(); _delete_ctx();
}
} }

View File

@ -228,8 +228,9 @@ Array DebuggerMarshalls::ScriptStackVariable::serialize(int max_size) {
int len = 0; int len = 0;
Error err = encode_variant(var, nullptr, len, true); Error err = encode_variant(var, nullptr, len, true);
if (err != OK) if (err != OK) {
ERR_PRINT("Failed to encode variant."); ERR_PRINT("Failed to encode variant.");
}
if (len > max_size) { if (len > max_size) {
arr.push_back(Variant()); arr.push_back(Variant());

View File

@ -111,8 +111,9 @@ Error EngineDebugger::capture_parse(const StringName &p_name, const String &p_ms
void EngineDebugger::line_poll() { void EngineDebugger::line_poll() {
// The purpose of this is just processing events every now and then when the script might get too busy otherwise bugs like infinite loops can't be caught // The purpose of this is just processing events every now and then when the script might get too busy otherwise bugs like infinite loops can't be caught
if (poll_every % 2048 == 0) if (poll_every % 2048 == 0) {
poll_events(false); poll_events(false);
}
poll_every++; poll_every++;
} }
@ -124,8 +125,9 @@ void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_idle_ticks, ui
// Notify tick to running profilers // Notify tick to running profilers
for (Map<StringName, Profiler>::Element *E = profilers.front(); E; E = E->next()) { for (Map<StringName, Profiler>::Element *E = profilers.front(); E; E = E->next()) {
Profiler &p = E->get(); Profiler &p = E->get();
if (!p.active || !p.tick) if (!p.active || !p.tick) {
continue; continue;
}
p.tick(p.data, frame_time, idle_time, physics_time, physics_frame_time); p.tick(p.data, frame_time, idle_time, physics_time, physics_frame_time);
} }
singleton->poll_events(true); singleton->poll_events(true);
@ -133,8 +135,9 @@ void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_idle_ticks, ui
void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Vector<String> p_breakpoints) { void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Vector<String> p_breakpoints) {
register_uri_handler("tcp://", RemoteDebuggerPeerTCP::create); // TCP is the default protocol. Platforms/modules can add more. register_uri_handler("tcp://", RemoteDebuggerPeerTCP::create); // TCP is the default protocol. Platforms/modules can add more.
if (p_uri.empty()) if (p_uri.empty()) {
return; return;
}
if (p_uri == "local://") { if (p_uri == "local://") {
singleton = memnew(LocalDebugger); singleton = memnew(LocalDebugger);
script_debugger = memnew(ScriptDebugger); script_debugger = memnew(ScriptDebugger);
@ -142,11 +145,13 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Ve
OS::get_singleton()->initialize_debugging(); OS::get_singleton()->initialize_debugging();
} else if (p_uri.find("://") >= 0) { } else if (p_uri.find("://") >= 0) {
const String proto = p_uri.substr(0, p_uri.find("://") + 3); const String proto = p_uri.substr(0, p_uri.find("://") + 3);
if (!protocols.has(proto)) if (!protocols.has(proto)) {
return; return;
}
RemoteDebuggerPeer *peer = protocols[proto](p_uri); RemoteDebuggerPeer *peer = protocols[proto](p_uri);
if (!peer) if (!peer) {
return; return;
}
singleton = memnew(RemoteDebugger(Ref<RemoteDebuggerPeer>(peer))); singleton = memnew(RemoteDebugger(Ref<RemoteDebuggerPeer>(peer)));
script_debugger = memnew(ScriptDebugger); script_debugger = memnew(ScriptDebugger);
// Notify editor of our pid (to allow focus stealing). // Notify editor of our pid (to allow focus stealing).
@ -154,8 +159,9 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Ve
msg.push_back(OS::get_singleton()->get_process_id()); msg.push_back(OS::get_singleton()->get_process_id());
singleton->send_message("set_pid", msg); singleton->send_message("set_pid", msg);
} }
if (!singleton) if (!singleton) {
return; return;
}
// There is a debugger, parse breakpoints. // There is a debugger, parse breakpoints.
ScriptDebugger *singleton_script_debugger = singleton->get_script_debugger(); ScriptDebugger *singleton_script_debugger = singleton->get_script_debugger();
@ -174,8 +180,9 @@ void EngineDebugger::deinitialize() {
if (singleton) { if (singleton) {
// Stop all profilers // Stop all profilers
for (Map<StringName, Profiler>::Element *E = profilers.front(); E; E = E->next()) { for (Map<StringName, Profiler>::Element *E = profilers.front(); E; E = E->next()) {
if (E->get().active) if (E->get().active) {
singleton->profiler_enable(E->key(), false); singleton->profiler_enable(E->key(), false);
}
} }
// Flush any remaining message // Flush any remaining message
@ -192,8 +199,9 @@ void EngineDebugger::deinitialize() {
} }
EngineDebugger::~EngineDebugger() { EngineDebugger::~EngineDebugger() {
if (script_debugger) if (script_debugger) {
memdelete(script_debugger); memdelete(script_debugger);
}
script_debugger = nullptr; script_debugger = nullptr;
singleton = nullptr; singleton = nullptr;
} }

View File

@ -69,17 +69,19 @@ struct LocalDebugger::ScriptsProfiler {
void _print_frame_data(bool p_accumulated) { void _print_frame_data(bool p_accumulated) {
uint64_t diff = OS::get_singleton()->get_ticks_usec() - idle_accum; uint64_t diff = OS::get_singleton()->get_ticks_usec() - idle_accum;
if (!p_accumulated && diff < 1000000) //show every one second if (!p_accumulated && diff < 1000000) { //show every one second
return; return;
}
idle_accum = OS::get_singleton()->get_ticks_usec(); idle_accum = OS::get_singleton()->get_ticks_usec();
int ofs = 0; int ofs = 0;
for (int i = 0; i < ScriptServer::get_language_count(); i++) { for (int i = 0; i < ScriptServer::get_language_count(); i++) {
if (p_accumulated) if (p_accumulated) {
ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&pinfo.write[ofs], pinfo.size() - ofs); ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&pinfo.write[ofs], pinfo.size() - ofs);
else } else {
ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&pinfo.write[ofs], pinfo.size() - ofs); ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&pinfo.write[ofs], pinfo.size() - ofs);
}
} }
SortArray<ScriptLanguage::ProfilingInfo, ProfileInfoSort> sort; SortArray<ScriptLanguage::ProfilingInfo, ProfileInfoSort> sort;
@ -141,9 +143,9 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
print_line("\nDebugger Break, Reason: '" + script_lang->debug_get_error() + "'"); print_line("\nDebugger Break, Reason: '" + script_lang->debug_get_error() + "'");
print_line("*Frame " + itos(current_frame) + " - " + script_lang->debug_get_stack_level_source(current_frame) + ":" + itos(script_lang->debug_get_stack_level_line(current_frame)) + " in function '" + script_lang->debug_get_stack_level_function(current_frame) + "'"); print_line("*Frame " + itos(current_frame) + " - " + script_lang->debug_get_stack_level_source(current_frame) + ":" + itos(script_lang->debug_get_stack_level_line(current_frame)) + " in function '" + script_lang->debug_get_stack_level_function(current_frame) + "'");
print_line("Enter \"help\" for assistance."); print_line("Enter \"help\" for assistance.");
} else if (line == "c" || line == "continue") } else if (line == "c" || line == "continue") {
break; break;
else if (line == "bt" || line == "breakpoint") { } else if (line == "bt" || line == "breakpoint") {
for (int i = 0; i < total_frames; i++) { for (int i = 0; i < total_frames; i++) {
String cfi = (current_frame == i) ? "*" : " "; //current frame indicator String cfi = (current_frame == i) ? "*" : " "; //current frame indicator
print_line(cfi + "Frame " + itos(i) + " - " + script_lang->debug_get_stack_level_source(i) + ":" + itos(script_lang->debug_get_stack_level_line(i)) + " in function '" + script_lang->debug_get_stack_level_function(i) + "'"); print_line(cfi + "Frame " + itos(i) + " - " + script_lang->debug_get_stack_level_source(i) + ":" + itos(script_lang->debug_get_stack_level_line(i)) + " in function '" + script_lang->debug_get_stack_level_function(i) + "'");
@ -257,8 +259,9 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
String source = breakpoint.first; String source = breakpoint.first;
int linenr = breakpoint.second; int linenr = breakpoint.second;
if (source.empty()) if (source.empty()) {
continue; continue;
}
script_debugger->insert_breakpoint(linenr, source); script_debugger->insert_breakpoint(linenr, source);
@ -282,8 +285,9 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
String source = breakpoint.first; String source = breakpoint.first;
int linenr = breakpoint.second; int linenr = breakpoint.second;
if (source.empty()) if (source.empty()) {
continue; continue;
}
script_debugger->remove_breakpoint(linenr, source); script_debugger->remove_breakpoint(linenr, source);
@ -377,6 +381,7 @@ LocalDebugger::LocalDebugger() {
LocalDebugger::~LocalDebugger() { LocalDebugger::~LocalDebugger() {
unregister_profiler("scripts"); unregister_profiler("scripts");
if (scripts_profiler) if (scripts_profiler) {
memdelete(scripts_profiler); memdelete(scripts_profiler);
}
} }

View File

@ -96,8 +96,9 @@ public:
} }
void init_node(const ObjectID p_node) { void init_node(const ObjectID p_node) {
if (multiplayer_node_data.has(p_node)) if (multiplayer_node_data.has(p_node)) {
return; return;
}
multiplayer_node_data.insert(p_node, DebuggerMarshalls::MultiplayerNodeInfo()); multiplayer_node_data.insert(p_node, DebuggerMarshalls::MultiplayerNodeInfo());
multiplayer_node_data[p_node].node = p_node; multiplayer_node_data[p_node].node = p_node;
multiplayer_node_data[p_node].node_path = Object::cast_to<Node>(ObjectDB::get_instance(p_node))->get_path(); multiplayer_node_data[p_node].node_path = Object::cast_to<Node>(ObjectDB::get_instance(p_node))->get_path();
@ -218,10 +219,11 @@ struct RemoteDebugger::ScriptsProfiler {
void write_frame_data(Vector<FunctionInfo> &r_funcs, uint64_t &r_total, bool p_accumulated) { void write_frame_data(Vector<FunctionInfo> &r_funcs, uint64_t &r_total, bool p_accumulated) {
int ofs = 0; int ofs = 0;
for (int i = 0; i < ScriptServer::get_language_count(); i++) { for (int i = 0; i < ScriptServer::get_language_count(); i++) {
if (p_accumulated) if (p_accumulated) {
ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&info.write[ofs], info.size() - ofs); ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&info.write[ofs], info.size() - ofs);
else } else {
ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&info.write[ofs], info.size() - ofs); ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&info.write[ofs], info.size() - ofs);
}
} }
for (int i = 0; i < ofs; i++) { for (int i = 0; i < ofs; i++) {
@ -358,8 +360,9 @@ struct RemoteDebugger::VisualProfiler {
void tick(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time) { void tick(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time) {
Vector<RS::FrameProfileArea> profile_areas = RS::get_singleton()->get_frame_profile(); Vector<RS::FrameProfileArea> profile_areas = RS::get_singleton()->get_frame_profile();
DebuggerMarshalls::VisualProfilerFrame frame; DebuggerMarshalls::VisualProfilerFrame frame;
if (!profile_areas.size()) if (!profile_areas.size()) {
return; return;
}
frame.frame_number = RS::get_singleton()->get_frame_profile_frame(); frame.frame_number = RS::get_singleton()->get_frame_profile_frame();
frame.areas.append_array(profile_areas); frame.areas.append_array(profile_areas);
@ -374,12 +377,14 @@ struct RemoteDebugger::PerformanceProfiler {
void toggle(bool p_enable, const Array &p_opts) {} void toggle(bool p_enable, const Array &p_opts) {}
void add(const Array &p_data) {} void add(const Array &p_data) {}
void tick(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time) { void tick(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time) {
if (!performance) if (!performance) {
return; return;
}
uint64_t pt = OS::get_singleton()->get_ticks_msec(); uint64_t pt = OS::get_singleton()->get_ticks_msec();
if (pt - last_perf_time < 1000) if (pt - last_perf_time < 1000) {
return; return;
}
last_perf_time = pt; last_perf_time = pt;
int max = performance->get("MONITOR_MAX"); int max = performance->get("MONITOR_MAX");
Array arr; Array arr;
@ -423,25 +428,29 @@ Error RemoteDebugger::_put_msg(String p_message, Array p_data) {
msg.push_back(p_message); msg.push_back(p_message);
msg.push_back(p_data); msg.push_back(p_data);
Error err = peer->put_message(msg); Error err = peer->put_message(msg);
if (err != OK) if (err != OK) {
n_messages_dropped++; n_messages_dropped++;
}
return err; return err;
} }
void RemoteDebugger::_err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, ErrorHandlerType p_type) { void RemoteDebugger::_err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, ErrorHandlerType p_type) {
if (p_type == ERR_HANDLER_SCRIPT) if (p_type == ERR_HANDLER_SCRIPT) {
return; //ignore script errors, those go through debugger return; //ignore script errors, those go through debugger
}
RemoteDebugger *rd = (RemoteDebugger *)p_this; RemoteDebugger *rd = (RemoteDebugger *)p_this;
if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) // Can't handle recursive errors during flush. if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) { // Can't handle recursive errors during flush.
return; return;
}
Vector<ScriptLanguage::StackInfo> si; Vector<ScriptLanguage::StackInfo> si;
for (int i = 0; i < ScriptServer::get_language_count(); i++) { for (int i = 0; i < ScriptServer::get_language_count(); i++) {
si = ScriptServer::get_language(i)->debug_get_current_stack_info(); si = ScriptServer::get_language(i)->debug_get_current_stack_info();
if (si.size()) if (si.size()) {
break; break;
}
} }
// send_error will lock internally. // send_error will lock internally.
@ -451,14 +460,16 @@ void RemoteDebugger::_err_handler(void *p_this, const char *p_func, const char *
void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p_error) { void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p_error) {
RemoteDebugger *rd = (RemoteDebugger *)p_this; RemoteDebugger *rd = (RemoteDebugger *)p_this;
if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) // Can't handle recursive prints during flush. if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) { // Can't handle recursive prints during flush.
return; return;
}
String s = p_string; String s = p_string;
int allowed_chars = MIN(MAX(rd->max_chars_per_second - rd->char_count, 0), s.length()); int allowed_chars = MIN(MAX(rd->max_chars_per_second - rd->char_count, 0), s.length());
if (allowed_chars == 0 && s.length() > 0) if (allowed_chars == 0 && s.length() > 0) {
return; return;
}
if (allowed_chars < s.length()) { if (allowed_chars < s.length()) {
s = s.substr(0, allowed_chars); s = s.substr(0, allowed_chars);
@ -469,8 +480,9 @@ void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p
rd->char_count += allowed_chars; rd->char_count += allowed_chars;
bool overflowed = rd->char_count >= rd->max_chars_per_second; bool overflowed = rd->char_count >= rd->max_chars_per_second;
if (rd->is_peer_connected()) { if (rd->is_peer_connected()) {
if (overflowed) if (overflowed) {
s += "[...]"; s += "[...]";
}
OutputString output_string; OutputString output_string;
output_string.message = s; output_string.message = s;
@ -502,13 +514,15 @@ void RemoteDebugger::flush_output() {
flush_thread = Thread::get_caller_id(); flush_thread = Thread::get_caller_id();
flushing = true; flushing = true;
MutexLock lock(mutex); MutexLock lock(mutex);
if (!is_peer_connected()) if (!is_peer_connected()) {
return; return;
}
if (n_messages_dropped > 0) { if (n_messages_dropped > 0) {
ErrorMessage err_msg = _create_overflow_error("TOO_MANY_MESSAGES", "Too many messages! " + String::num_int64(n_messages_dropped) + " messages were dropped. Profiling might misbheave, try raising 'network/limits/debugger/max_queued_messages' in project setting."); ErrorMessage err_msg = _create_overflow_error("TOO_MANY_MESSAGES", "Too many messages! " + String::num_int64(n_messages_dropped) + " messages were dropped. Profiling might misbheave, try raising 'network/limits/debugger/max_queued_messages' in project setting.");
if (_put_msg("error", err_msg.serialize()) == OK) if (_put_msg("error", err_msg.serialize()) == OK) {
n_messages_dropped = 0; n_messages_dropped = 0;
}
} }
if (output_strings.size()) { if (output_strings.size()) {
@ -585,8 +599,9 @@ void RemoteDebugger::send_error(const String &p_func, const String &p_file, int
oe.msec = time % 1000; oe.msec = time % 1000;
oe.callstack.append_array(script_debugger->get_error_stack_info()); oe.callstack.append_array(script_debugger->get_error_stack_info());
if (flushing && Thread::get_caller_id() == flush_thread) // Can't handle recursive errors during flush. if (flushing && Thread::get_caller_id() == flush_thread) { // Can't handle recursive errors during flush.
return; return;
}
MutexLock lock(mutex); MutexLock lock(mutex);
@ -644,8 +659,9 @@ Error RemoteDebugger::_try_capture(const String &p_msg, const Array &p_data, boo
return OK; return OK;
} }
const String cap = p_msg.substr(0, idx); const String cap = p_msg.substr(0, idx);
if (!has_capture(cap)) if (!has_capture(cap)) {
return ERR_UNAVAILABLE; // Unknown message... return ERR_UNAVAILABLE; // Unknown message...
}
const String msg = p_msg.substr(idx + 1); const String msg = p_msg.substr(idx + 1);
return capture_parse(cap, msg, p_data, r_captured); return capture_parse(cap, msg, p_data, r_captured);
} }
@ -654,13 +670,15 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
//this function is called when there is a debugger break (bug on script) //this function is called when there is a debugger break (bug on script)
//or when execution is paused from editor //or when execution is paused from editor
if (script_debugger->is_skipping_breakpoints() && !p_is_error_breakpoint) if (script_debugger->is_skipping_breakpoints() && !p_is_error_breakpoint) {
return; return;
}
ERR_FAIL_COND_MSG(!is_peer_connected(), "Script Debugger failed to connect, but being used anyway."); ERR_FAIL_COND_MSG(!is_peer_connected(), "Script Debugger failed to connect, but being used anyway.");
if (!peer->can_block()) if (!peer->can_block()) {
return; // Peer does not support blocking IO. We could at least send the error though. return; // Peer does not support blocking IO. We could at least send the error though.
}
ScriptLanguage *script_lang = script_debugger->get_break_language(); ScriptLanguage *script_lang = script_debugger->get_break_language();
const String error_str = script_lang ? script_lang->debug_get_error() : ""; const String error_str = script_lang ? script_lang->debug_get_error() : "";
@ -672,8 +690,9 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
servers_profiler->skip_profile_frame = true; // Avoid frame time spike in debug. servers_profiler->skip_profile_frame = true; // Avoid frame time spike in debug.
Input::MouseMode mouse_mode = Input::get_singleton()->get_mouse_mode(); Input::MouseMode mouse_mode = Input::get_singleton()->get_mouse_mode();
if (mouse_mode != Input::MOUSE_MODE_VISIBLE) if (mouse_mode != Input::MOUSE_MODE_VISIBLE) {
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
}
uint64_t loop_begin_usec = 0; uint64_t loop_begin_usec = 0;
uint64_t loop_time_sec = 0; uint64_t loop_time_sec = 0;
@ -761,10 +780,11 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
} else if (command == "breakpoint") { } else if (command == "breakpoint") {
ERR_FAIL_COND(data.size() < 3); ERR_FAIL_COND(data.size() < 3);
bool set = data[2]; bool set = data[2];
if (set) if (set) {
script_debugger->insert_breakpoint(data[1], data[0]); script_debugger->insert_breakpoint(data[1], data[0]);
else } else {
script_debugger->remove_breakpoint(data[1], data[0]); script_debugger->remove_breakpoint(data[1], data[0]);
}
} else if (command == "set_skip_breakpoints") { } else if (command == "set_skip_breakpoints") {
ERR_FAIL_COND(data.size() < 1); ERR_FAIL_COND(data.size() < 1);
@ -772,8 +792,9 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
} else { } else {
bool captured = false; bool captured = false;
ERR_CONTINUE(_try_capture(command, data, captured) != OK); ERR_CONTINUE(_try_capture(command, data, captured) != OK);
if (!captured) if (!captured) {
WARN_PRINT("Unknown message received from debugger: " + command); WARN_PRINT("Unknown message received from debugger: " + command);
}
} }
} else { } else {
OS::get_singleton()->delay_usec(10000); OS::get_singleton()->delay_usec(10000);
@ -790,13 +811,15 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
send_message("debug_exit", Array()); send_message("debug_exit", Array());
if (mouse_mode != Input::MOUSE_MODE_VISIBLE) if (mouse_mode != Input::MOUSE_MODE_VISIBLE) {
Input::get_singleton()->set_mouse_mode(mouse_mode); Input::get_singleton()->set_mouse_mode(mouse_mode);
}
} }
void RemoteDebugger::poll_events(bool p_is_idle) { void RemoteDebugger::poll_events(bool p_is_idle) {
if (peer.is_null()) if (peer.is_null()) {
return; return;
}
flush_output(); flush_output();
peer->poll(); peer->poll();
@ -816,8 +839,9 @@ void RemoteDebugger::poll_events(bool p_is_idle) {
} }
const String cap = cmd.substr(0, idx); const String cap = cmd.substr(0, idx);
if (!has_capture(cap)) if (!has_capture(cap)) {
continue; // Unknown message... continue; // Unknown message...
}
const String msg = cmd.substr(idx + 1); const String msg = cmd.substr(idx + 1);
capture_parse(cap, msg, arr[1], parsed); capture_parse(cap, msg, arr[1], parsed);
@ -840,10 +864,11 @@ Error RemoteDebugger::_core_capture(const String &p_cmd, const Array &p_data, bo
} else if (p_cmd == "breakpoint") { } else if (p_cmd == "breakpoint") {
ERR_FAIL_COND_V(p_data.size() < 3, ERR_INVALID_DATA); ERR_FAIL_COND_V(p_data.size() < 3, ERR_INVALID_DATA);
bool set = p_data[2]; bool set = p_data[2];
if (set) if (set) {
script_debugger->insert_breakpoint(p_data[1], p_data[0]); script_debugger->insert_breakpoint(p_data[1], p_data[0]);
else } else {
script_debugger->remove_breakpoint(p_data[1], p_data[0]); script_debugger->remove_breakpoint(p_data[1], p_data[0]);
}
} else if (p_cmd == "set_skip_breakpoints") { } else if (p_cmd == "set_skip_breakpoints") {
ERR_FAIL_COND_V(p_data.size() < 1, ERR_INVALID_DATA); ERR_FAIL_COND_V(p_data.size() < 1, ERR_INVALID_DATA);
@ -934,6 +959,7 @@ RemoteDebugger::~RemoteDebugger() {
memdelete(servers_profiler); memdelete(servers_profiler);
memdelete(network_profiler); memdelete(network_profiler);
memdelete(visual_profiler); memdelete(visual_profiler);
if (performance_profiler) if (performance_profiler) {
memdelete(performance_profiler); memdelete(performance_profiler);
}
} }

View File

@ -52,8 +52,9 @@ Array RemoteDebuggerPeerTCP::get_message() {
Error RemoteDebuggerPeerTCP::put_message(const Array &p_arr) { Error RemoteDebuggerPeerTCP::put_message(const Array &p_arr) {
MutexLock lock(mutex); MutexLock lock(mutex);
if (out_queue.size() >= max_queued_messages) if (out_queue.size() >= max_queued_messages) {
return ERR_OUT_OF_MEMORY; return ERR_OUT_OF_MEMORY;
}
out_queue.push_back(p_arr); out_queue.push_back(p_arr);
return OK; return OK;
@ -99,8 +100,9 @@ void RemoteDebuggerPeerTCP::_write_out() {
while (tcp_client->poll(NetSocket::POLL_TYPE_OUT) == OK) { while (tcp_client->poll(NetSocket::POLL_TYPE_OUT) == OK) {
uint8_t *buf = out_buf.ptrw(); uint8_t *buf = out_buf.ptrw();
if (out_left <= 0) { if (out_left <= 0) {
if (out_queue.size() == 0) if (out_queue.size() == 0) {
break; // Nothing left to send break; // Nothing left to send
}
mutex.lock(); mutex.lock();
Variant var = out_queue[0]; Variant var = out_queue[0];
out_queue.pop_front(); out_queue.pop_front();
@ -155,10 +157,11 @@ void RemoteDebuggerPeerTCP::_read_in() {
Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_port) { Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_port) {
IP_Address ip; IP_Address ip;
if (p_host.is_valid_ip_address()) if (p_host.is_valid_ip_address()) {
ip = p_host; ip = p_host;
else } else {
ip = IP::get_singleton()->resolve_hostname(p_host); ip = IP::get_singleton()->resolve_hostname(p_host);
}
int port = p_port; int port = p_port;
@ -194,8 +197,9 @@ void RemoteDebuggerPeerTCP::_thread_func(void *p_ud) {
RemoteDebuggerPeerTCP *peer = (RemoteDebuggerPeerTCP *)p_ud; RemoteDebuggerPeerTCP *peer = (RemoteDebuggerPeerTCP *)p_ud;
while (peer->running && peer->is_peer_connected()) { while (peer->running && peer->is_peer_connected()) {
peer->_poll(); peer->_poll();
if (!peer->is_peer_connected()) if (!peer->is_peer_connected()) {
break; break;
}
peer->tcp_client->poll(NetSocket::POLL_TYPE_IN_OUT, 1); peer->tcp_client->poll(NetSocket::POLL_TYPE_IN_OUT, 1);
} }
} }

View File

@ -49,23 +49,27 @@ int ScriptDebugger::get_depth() const {
} }
void ScriptDebugger::insert_breakpoint(int p_line, const StringName &p_source) { void ScriptDebugger::insert_breakpoint(int p_line, const StringName &p_source) {
if (!breakpoints.has(p_line)) if (!breakpoints.has(p_line)) {
breakpoints[p_line] = Set<StringName>(); breakpoints[p_line] = Set<StringName>();
}
breakpoints[p_line].insert(p_source); breakpoints[p_line].insert(p_source);
} }
void ScriptDebugger::remove_breakpoint(int p_line, const StringName &p_source) { void ScriptDebugger::remove_breakpoint(int p_line, const StringName &p_source) {
if (!breakpoints.has(p_line)) if (!breakpoints.has(p_line)) {
return; return;
}
breakpoints[p_line].erase(p_source); breakpoints[p_line].erase(p_source);
if (breakpoints[p_line].size() == 0) if (breakpoints[p_line].size() == 0) {
breakpoints.erase(p_line); breakpoints.erase(p_line);
}
} }
bool ScriptDebugger::is_breakpoint(int p_line, const StringName &p_source) const { bool ScriptDebugger::is_breakpoint(int p_line, const StringName &p_source) const {
if (!breakpoints.has(p_line)) if (!breakpoints.has(p_line)) {
return false; return false;
}
return breakpoints[p_line].has(p_source); return breakpoints[p_line].has(p_source);
} }

View File

@ -40,8 +40,9 @@ struct DictionaryPrivate {
}; };
void Dictionary::get_key_list(List<Variant> *p_keys) const { void Dictionary::get_key_list(List<Variant> *p_keys) const {
if (_p->variant_map.empty()) if (_p->variant_map.empty()) {
return; return;
}
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) { for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
p_keys->push_back(E.key()); p_keys->push_back(E.key());
@ -83,24 +84,27 @@ const Variant &Dictionary::operator[](const Variant &p_key) const {
const Variant *Dictionary::getptr(const Variant &p_key) const { const Variant *Dictionary::getptr(const Variant &p_key) const {
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key); OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
if (!E) if (!E) {
return nullptr; return nullptr;
}
return &E.get(); return &E.get();
} }
Variant *Dictionary::getptr(const Variant &p_key) { Variant *Dictionary::getptr(const Variant &p_key) {
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(p_key); OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(p_key);
if (!E) if (!E) {
return nullptr; return nullptr;
}
return &E.get(); return &E.get();
} }
Variant Dictionary::get_valid(const Variant &p_key) const { Variant Dictionary::get_valid(const Variant &p_key) const {
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key); OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
if (!E) if (!E) {
return Variant(); return Variant();
}
return E.get(); return E.get();
} }
@ -148,16 +152,18 @@ bool Dictionary::operator!=(const Dictionary &p_dictionary) const {
void Dictionary::_ref(const Dictionary &p_from) const { void Dictionary::_ref(const Dictionary &p_from) const {
//make a copy first (thread safe) //make a copy first (thread safe)
if (!p_from._p->refcount.ref()) if (!p_from._p->refcount.ref()) {
return; // couldn't copy return; // couldn't copy
}
//if this is the same, unreference the other one //if this is the same, unreference the other one
if (p_from._p == _p) { if (p_from._p == _p) {
_p->refcount.unref(); _p->refcount.unref();
return; return;
} }
if (_p) if (_p) {
_unref(); _unref();
}
_p = p_from._p; _p = p_from._p;
} }
@ -186,8 +192,9 @@ uint32_t Dictionary::hash() const {
Array Dictionary::keys() const { Array Dictionary::keys() const {
Array varr; Array varr;
if (_p->variant_map.empty()) if (_p->variant_map.empty()) {
return varr; return varr;
}
varr.resize(size()); varr.resize(size());
@ -202,8 +209,9 @@ Array Dictionary::keys() const {
Array Dictionary::values() const { Array Dictionary::values() const {
Array varr; Array varr;
if (_p->variant_map.empty()) if (_p->variant_map.empty()) {
return varr; return varr;
}
varr.resize(size()); varr.resize(size());
@ -219,14 +227,16 @@ Array Dictionary::values() const {
const Variant *Dictionary::next(const Variant *p_key) const { const Variant *Dictionary::next(const Variant *p_key) const {
if (p_key == nullptr) { if (p_key == nullptr) {
// caller wants to get the first element // caller wants to get the first element
if (_p->variant_map.front()) if (_p->variant_map.front()) {
return &_p->variant_map.front().key(); return &_p->variant_map.front().key();
}
return nullptr; return nullptr;
} }
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(*p_key); OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(*p_key);
if (E && E.next()) if (E && E.next()) {
return &E.next().key(); return &E.next().key();
}
return nullptr; return nullptr;
} }

View File

@ -46,8 +46,9 @@ int Engine::get_iterations_per_second() const {
} }
void Engine::set_physics_jitter_fix(float p_threshold) { void Engine::set_physics_jitter_fix(float p_threshold) {
if (p_threshold < 0) if (p_threshold < 0) {
p_threshold = 0; p_threshold = 0;
}
physics_jitter_fix = p_threshold; physics_jitter_fix = p_threshold;
} }
@ -97,8 +98,9 @@ Dictionary Engine::get_version_info() const {
dict["hash"] = hash.length() == 0 ? String("unknown") : hash; dict["hash"] = hash.length() == 0 ? String("unknown") : hash;
String stringver = String(dict["major"]) + "." + String(dict["minor"]); String stringver = String(dict["major"]) + "." + String(dict["minor"]);
if ((int)dict["patch"] != 0) if ((int)dict["patch"] != 0) {
stringver += "." + String(dict["patch"]); stringver += "." + String(dict["patch"]);
}
stringver += "-" + String(dict["status"]) + " (" + String(dict["build"]) + ")"; stringver += "-" + String(dict["status"]) + " (" + String(dict["build"]) + ")";
dict["string"] = stringver; dict["string"] = stringver;
@ -193,8 +195,9 @@ bool Engine::has_singleton(const String &p_name) const {
}; };
void Engine::get_singletons(List<Singleton> *p_singletons) { void Engine::get_singletons(List<Singleton> *p_singletons) {
for (List<Singleton>::Element *E = singletons.front(); E; E = E->next()) for (List<Singleton>::Element *E = singletons.front(); E; E = E->next()) {
p_singletons->push_back(E->get()); p_singletons->push_back(E->get());
}
} }
Engine *Engine::singleton = nullptr; Engine *Engine::singleton = nullptr;

View File

@ -51,10 +51,11 @@ void remove_error_handler(ErrorHandlerList *p_handler) {
while (l) { while (l) {
if (l == p_handler) { if (l == p_handler) {
if (prev) if (prev) {
prev->next = l->next; prev->next = l->next;
else } else {
error_handler_list = l->next; error_handler_list = l->next;
}
break; break;
} }
prev = l; prev = l;

View File

@ -65,12 +65,14 @@ void FuncRef::set_function(const StringName &p_func) {
} }
bool FuncRef::is_valid() const { bool FuncRef::is_valid() const {
if (id.is_null()) if (id.is_null()) {
return false; return false;
}
Object *obj = ObjectDB::get_instance(id); Object *obj = ObjectDB::get_instance(id);
if (!obj) if (!obj) {
return false; return false;
}
return obj->has_method(function); return obj->has_method(function);
} }

View File

@ -104,8 +104,9 @@ private:
hash_table_power = MIN_HASH_TABLE_POWER; hash_table_power = MIN_HASH_TABLE_POWER;
elements = 0; elements = 0;
for (int i = 0; i < (1 << MIN_HASH_TABLE_POWER); i++) for (int i = 0; i < (1 << MIN_HASH_TABLE_POWER); i++) {
hash_table[i] = nullptr; hash_table[i] = nullptr;
}
} }
void erase_hash_table() { void erase_hash_table() {
@ -136,12 +137,14 @@ private:
new_hash_table_power--; new_hash_table_power--;
} }
if (new_hash_table_power < (int)MIN_HASH_TABLE_POWER) if (new_hash_table_power < (int)MIN_HASH_TABLE_POWER) {
new_hash_table_power = MIN_HASH_TABLE_POWER; new_hash_table_power = MIN_HASH_TABLE_POWER;
}
} }
if (new_hash_table_power == -1) if (new_hash_table_power == -1) {
return; return;
}
Element **new_hash_table = memnew_arr(Element *, ((uint64_t)1 << new_hash_table_power)); Element **new_hash_table = memnew_arr(Element *, ((uint64_t)1 << new_hash_table_power));
ERR_FAIL_COND_MSG(!new_hash_table, "Out of memory."); ERR_FAIL_COND_MSG(!new_hash_table, "Out of memory.");
@ -205,13 +208,15 @@ private:
} }
void copy_from(const HashMap &p_t) { void copy_from(const HashMap &p_t) {
if (&p_t == this) if (&p_t == this) {
return; /* much less bother with that */ return; /* much less bother with that */
}
clear(); clear();
if (!p_t.hash_table || p_t.hash_table_power == 0) if (!p_t.hash_table || p_t.hash_table_power == 0) {
return; /* not copying from empty table */ return; /* not copying from empty table */
}
hash_table = memnew_arr(Element *, (uint64_t)1 << p_t.hash_table_power); hash_table = memnew_arr(Element *, (uint64_t)1 << p_t.hash_table_power);
hash_table_power = p_t.hash_table_power; hash_table_power = p_t.hash_table_power;
@ -243,17 +248,19 @@ public:
Element *set(const Pair &p_pair) { Element *set(const Pair &p_pair) {
Element *e = nullptr; Element *e = nullptr;
if (!hash_table) if (!hash_table) {
make_hash_table(); // if no table, make one make_hash_table(); // if no table, make one
else } else {
e = const_cast<Element *>(get_element(p_pair.key)); e = const_cast<Element *>(get_element(p_pair.key));
}
/* if we made it up to here, the pair doesn't exist, create and assign */ /* if we made it up to here, the pair doesn't exist, create and assign */
if (!e) { if (!e) {
e = create_element(p_pair.key); e = create_element(p_pair.key);
if (!e) if (!e) {
return nullptr; return nullptr;
}
check_hash_table(); // perform mantenience routine check_hash_table(); // perform mantenience routine
} }
@ -289,25 +296,29 @@ public:
*/ */
_FORCE_INLINE_ TData *getptr(const TKey &p_key) { _FORCE_INLINE_ TData *getptr(const TKey &p_key) {
if (unlikely(!hash_table)) if (unlikely(!hash_table)) {
return nullptr; return nullptr;
}
Element *e = const_cast<Element *>(get_element(p_key)); Element *e = const_cast<Element *>(get_element(p_key));
if (e) if (e) {
return &e->pair.data; return &e->pair.data;
}
return nullptr; return nullptr;
} }
_FORCE_INLINE_ const TData *getptr(const TKey &p_key) const { _FORCE_INLINE_ const TData *getptr(const TKey &p_key) const {
if (unlikely(!hash_table)) if (unlikely(!hash_table)) {
return nullptr; return nullptr;
}
const Element *e = const_cast<Element *>(get_element(p_key)); const Element *e = const_cast<Element *>(get_element(p_key));
if (e) if (e) {
return &e->pair.data; return &e->pair.data;
}
return nullptr; return nullptr;
} }
@ -319,8 +330,9 @@ public:
template <class C> template <class C>
_FORCE_INLINE_ TData *custom_getptr(C p_custom_key, uint32_t p_custom_hash) { _FORCE_INLINE_ TData *custom_getptr(C p_custom_key, uint32_t p_custom_hash) {
if (unlikely(!hash_table)) if (unlikely(!hash_table)) {
return nullptr; return nullptr;
}
uint32_t hash = p_custom_hash; uint32_t hash = p_custom_hash;
uint32_t index = hash & ((1 << hash_table_power) - 1); uint32_t index = hash & ((1 << hash_table_power) - 1);
@ -342,8 +354,9 @@ public:
template <class C> template <class C>
_FORCE_INLINE_ const TData *custom_getptr(C p_custom_key, uint32_t p_custom_hash) const { _FORCE_INLINE_ const TData *custom_getptr(C p_custom_key, uint32_t p_custom_hash) const {
if (unlikely(!hash_table)) if (unlikely(!hash_table)) {
return nullptr; return nullptr;
}
uint32_t hash = p_custom_hash; uint32_t hash = p_custom_hash;
uint32_t index = hash & ((1 << hash_table_power) - 1); uint32_t index = hash & ((1 << hash_table_power) - 1);
@ -368,8 +381,9 @@ public:
*/ */
bool erase(const TKey &p_key) { bool erase(const TKey &p_key) {
if (unlikely(!hash_table)) if (unlikely(!hash_table)) {
return false; return false;
}
uint32_t hash = Hasher::hash(p_key); uint32_t hash = Hasher::hash(p_key);
uint32_t index = hash & ((1 << hash_table_power) - 1); uint32_t index = hash & ((1 << hash_table_power) - 1);
@ -389,10 +403,11 @@ public:
memdelete(e); memdelete(e);
elements--; elements--;
if (elements == 0) if (elements == 0) {
erase_hash_table(); erase_hash_table();
else } else {
check_hash_table(); check_hash_table();
}
return true; return true;
} }
@ -410,10 +425,11 @@ public:
inline TData &operator[](const TKey &p_key) { //assignment inline TData &operator[](const TKey &p_key) { //assignment
Element *e = nullptr; Element *e = nullptr;
if (!hash_table) if (!hash_table) {
make_hash_table(); // if no table, make one make_hash_table(); // if no table, make one
else } else {
e = const_cast<Element *>(get_element(p_key)); e = const_cast<Element *>(get_element(p_key));
}
/* if we made it up to here, the pair doesn't exist, create */ /* if we made it up to here, the pair doesn't exist, create */
if (!e) { if (!e) {
@ -441,8 +457,9 @@ public:
* *
*/ */
const TKey *next(const TKey *p_key) const { const TKey *next(const TKey *p_key) const {
if (unlikely(!hash_table)) if (unlikely(!hash_table)) {
return nullptr; return nullptr;
}
if (!p_key) { /* get the first key */ if (!p_key) { /* get the first key */
@ -508,8 +525,9 @@ public:
} }
void get_key_value_ptr_array(const Pair **p_pairs) const { void get_key_value_ptr_array(const Pair **p_pairs) const {
if (unlikely(!hash_table)) if (unlikely(!hash_table)) {
return; return;
}
for (int i = 0; i < (1 << hash_table_power); i++) { for (int i = 0; i < (1 << hash_table_power); i++) {
Element *e = hash_table[i]; Element *e = hash_table[i];
while (e) { while (e) {
@ -521,8 +539,9 @@ public:
} }
void get_key_list(List<TKey> *p_keys) const { void get_key_list(List<TKey> *p_keys) const {
if (unlikely(!hash_table)) if (unlikely(!hash_table)) {
return; return;
}
for (int i = 0; i < (1 << hash_table_power); i++) { for (int i = 0; i < (1 << hash_table_power); i++) {
Element *e = hash_table[i]; Element *e = hash_table[i];
while (e) { while (e) {

View File

@ -53,8 +53,9 @@ static inline uint32_t hash_djb2(const char *p_cstr) {
uint32_t hash = 5381; uint32_t hash = 5381;
uint32_t c; uint32_t c;
while ((c = *chr++)) while ((c = *chr++)) {
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
}
return hash; return hash;
} }
@ -62,8 +63,9 @@ static inline uint32_t hash_djb2(const char *p_cstr) {
static inline uint32_t hash_djb2_buffer(const uint8_t *p_buff, int p_len, uint32_t p_prev = 5381) { static inline uint32_t hash_djb2_buffer(const uint8_t *p_buff, int p_len, uint32_t p_prev = 5381) {
uint32_t hash = p_prev; uint32_t hash = p_prev;
for (int i = 0; i < p_len; i++) for (int i = 0; i < p_len; i++) {
hash = ((hash << 5) + hash) + p_buff[i]; /* hash * 33 + c */ hash = ((hash << 5) + hash) + p_buff[i]; /* hash * 33 + c */
}
return hash; return hash;
} }
@ -90,12 +92,13 @@ static inline uint32_t hash_djb2_one_float(double p_in, uint32_t p_prev = 5381)
} u; } u;
// Normalize +/- 0.0 and NaN values so they hash the same. // Normalize +/- 0.0 and NaN values so they hash the same.
if (p_in == 0.0f) if (p_in == 0.0f) {
u.d = 0.0; u.d = 0.0;
else if (Math::is_nan(p_in)) } else if (Math::is_nan(p_in)) {
u.d = Math_NAN; u.d = Math_NAN;
else } else {
u.d = p_in; u.d = p_in;
}
return ((p_prev << 5) + p_prev) + hash_one_uint64(u.i); return ((p_prev << 5) + p_prev) + hash_one_uint64(u.i);
} }

View File

@ -244,12 +244,13 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) {
} }
int Image::get_format_pixel_rshift(Format p_format) { int Image::get_format_pixel_rshift(Format p_format) {
if (p_format == FORMAT_DXT1 || p_format == FORMAT_RGTC_R || p_format == FORMAT_PVRTC4 || p_format == FORMAT_PVRTC4A || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1) if (p_format == FORMAT_DXT1 || p_format == FORMAT_RGTC_R || p_format == FORMAT_PVRTC4 || p_format == FORMAT_PVRTC4A || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1) {
return 1; return 1;
else if (p_format == FORMAT_PVRTC2 || p_format == FORMAT_PVRTC2A) } else if (p_format == FORMAT_PVRTC2 || p_format == FORMAT_PVRTC2A) {
return 2; return 2;
else } else {
return 0; return 0;
}
} }
int Image::get_format_block_size(Format p_format) { int Image::get_format_block_size(Format p_format) {
@ -380,10 +381,11 @@ bool Image::has_mipmaps() const {
} }
int Image::get_mipmap_count() const { int Image::get_mipmap_count() const {
if (mipmaps) if (mipmaps) {
return get_image_required_mipmaps(width, height, format); return get_image_required_mipmaps(width, height, format);
else } else {
return 0; return 0;
}
} }
//using template generates perfectly optimized code due to constant expression reduction and unused variable removal present in all compilers //using template generates perfectly optimized code due to constant expression reduction and unused variable removal present in all compilers
@ -429,11 +431,13 @@ static void _convert(int p_width, int p_height, const uint8_t *p_src, uint8_t *p
} }
void Image::convert(Format p_new_format) { void Image::convert(Format p_new_format) {
if (data.size() == 0) if (data.size() == 0) {
return; return;
}
if (p_new_format == format) if (p_new_format == format) {
return; return;
}
if (format > FORMAT_RGBE9995 || p_new_format > FORMAT_RGBE9995) { if (format > FORMAT_RGBE9995 || p_new_format > FORMAT_RGBE9995) {
ERR_FAIL_MSG("Cannot convert to <-> from compressed formats. Use compress() and decompress() instead."); ERR_FAIL_MSG("Cannot convert to <-> from compressed formats. Use compress() and decompress() instead.");
@ -561,8 +565,9 @@ void Image::convert(Format p_new_format) {
_copy_internals_from(new_img); _copy_internals_from(new_img);
if (gen_mipmaps) if (gen_mipmaps) {
generate_mipmaps(); generate_mipmaps();
}
} }
Image::Format Image::get_format() const { Image::Format Image::get_format() const {
@ -574,10 +579,11 @@ static double _bicubic_interp_kernel(double x) {
double bc = 0; double bc = 0;
if (x <= 1) if (x <= 1) {
bc = (1.5 * x - 2.5) * x * x + 1; bc = (1.5 * x - 2.5) * x * x + 1;
else if (x < 2) } else if (x < 2) {
bc = ((-0.5 * x + 2.5) * x - 4) * x + 2; bc = ((-0.5 * x + 2.5) * x - 4) * x + 2;
}
return bc; return bc;
} }
@ -624,20 +630,24 @@ static void _scale_cubic(const uint8_t *__restrict p_src, uint8_t *__restrict p_
k1 = _bicubic_interp_kernel(dy - (double)n); k1 = _bicubic_interp_kernel(dy - (double)n);
oy2 = oy1 + n; oy2 = oy1 + n;
if (oy2 < 0) if (oy2 < 0) {
oy2 = 0; oy2 = 0;
if (oy2 > ymax) }
if (oy2 > ymax) {
oy2 = ymax; oy2 = ymax;
}
for (int m = -1; m < 3; m++) { for (int m = -1; m < 3; m++) {
// get X coefficient // get X coefficient
k2 = k1 * _bicubic_interp_kernel((double)m - dx); k2 = k1 * _bicubic_interp_kernel((double)m - dx);
ox2 = ox1 + m; ox2 = ox1 + m;
if (ox2 < 0) if (ox2 < 0) {
ox2 = 0; ox2 = 0;
if (ox2 > xmax) }
if (ox2 > xmax) {
ox2 = xmax; ox2 = xmax;
}
// get pixel of original image // get pixel of original image
const T *__restrict p = ((T *)p_src) + (oy2 * p_src_width + ox2) * CC; const T *__restrict p = ((T *)p_src) + (oy2 * p_src_width + ox2) * CC;
@ -680,8 +690,9 @@ static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict
uint32_t src_yofs_up = src_yofs_up_fp >> FRAC_BITS; uint32_t src_yofs_up = src_yofs_up_fp >> FRAC_BITS;
uint32_t src_yofs_down = (i + 1) * p_src_height / p_dst_height; uint32_t src_yofs_down = (i + 1) * p_src_height / p_dst_height;
if (src_yofs_down >= p_src_height) if (src_yofs_down >= p_src_height) {
src_yofs_down = p_src_height - 1; src_yofs_down = p_src_height - 1;
}
//src_yofs_up*=CC; //src_yofs_up*=CC;
//src_yofs_down*=CC; //src_yofs_down*=CC;
@ -694,8 +705,9 @@ static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict
uint32_t src_xofs_frac = src_xofs_left_fp & FRAC_MASK; uint32_t src_xofs_frac = src_xofs_left_fp & FRAC_MASK;
uint32_t src_xofs_left = src_xofs_left_fp >> FRAC_BITS; uint32_t src_xofs_left = src_xofs_left_fp >> FRAC_BITS;
uint32_t src_xofs_right = (j + 1) * p_src_width / p_dst_width; uint32_t src_xofs_right = (j + 1) * p_src_width / p_dst_width;
if (src_xofs_right >= p_src_width) if (src_xofs_right >= p_src_width) {
src_xofs_right = p_src_width - 1; src_xofs_right = p_src_width - 1;
}
src_xofs_left *= CC; src_xofs_left *= CC;
src_xofs_right *= CC; src_xofs_right *= CC;
@ -805,8 +817,9 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict
int32_t end_x = MIN(src_width - 1, int32_t(src_x) + half_kernel); int32_t end_x = MIN(src_width - 1, int32_t(src_x) + half_kernel);
// Create the kernel used by all the pixels of the column // Create the kernel used by all the pixels of the column
for (int32_t target_x = start_x; target_x <= end_x; target_x++) for (int32_t target_x = start_x; target_x <= end_x; target_x++) {
kernel[target_x - start_x] = _lanczos((target_x + 0.5f - src_x) / scale_factor); kernel[target_x - start_x] = _lanczos((target_x + 0.5f - src_x) / scale_factor);
}
for (int32_t buffer_y = 0; buffer_y < src_height; buffer_y++) { for (int32_t buffer_y = 0; buffer_y < src_height; buffer_y++) {
float pixel[CC] = { 0 }; float pixel[CC] = { 0 };
@ -819,17 +832,19 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict
const T *__restrict src_data = ((const T *)p_src) + (buffer_y * src_width + target_x) * CC; const T *__restrict src_data = ((const T *)p_src) + (buffer_y * src_width + target_x) * CC;
for (uint32_t i = 0; i < CC; i++) { for (uint32_t i = 0; i < CC; i++) {
if (sizeof(T) == 2) //half float if (sizeof(T) == 2) { //half float
pixel[i] += Math::half_to_float(src_data[i]) * lanczos_val; pixel[i] += Math::half_to_float(src_data[i]) * lanczos_val;
else } else {
pixel[i] += src_data[i] * lanczos_val; pixel[i] += src_data[i] * lanczos_val;
}
} }
} }
float *dst_data = ((float *)buffer) + (buffer_y * dst_width + buffer_x) * CC; float *dst_data = ((float *)buffer) + (buffer_y * dst_width + buffer_x) * CC;
for (uint32_t i = 0; i < CC; i++) for (uint32_t i = 0; i < CC; i++) {
dst_data[i] = pixel[i] / weight; // Normalize the sum of all the samples dst_data[i] = pixel[i] / weight; // Normalize the sum of all the samples
}
} }
} }
@ -850,8 +865,9 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict
int32_t start_y = MAX(0, int32_t(buffer_y) - half_kernel + 1); int32_t start_y = MAX(0, int32_t(buffer_y) - half_kernel + 1);
int32_t end_y = MIN(src_height - 1, int32_t(buffer_y) + half_kernel); int32_t end_y = MIN(src_height - 1, int32_t(buffer_y) + half_kernel);
for (int32_t target_y = start_y; target_y <= end_y; target_y++) for (int32_t target_y = start_y; target_y <= end_y; target_y++) {
kernel[target_y - start_y] = _lanczos((target_y + 0.5f - buffer_y) / scale_factor); kernel[target_y - start_y] = _lanczos((target_y + 0.5f - buffer_y) / scale_factor);
}
for (int32_t dst_x = 0; dst_x < dst_width; dst_x++) { for (int32_t dst_x = 0; dst_x < dst_width; dst_x++) {
float pixel[CC] = { 0 }; float pixel[CC] = { 0 };
@ -863,8 +879,9 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict
float *buffer_data = ((float *)buffer) + (target_y * dst_width + dst_x) * CC; float *buffer_data = ((float *)buffer) + (target_y * dst_width + dst_x) * CC;
for (uint32_t i = 0; i < CC; i++) for (uint32_t i = 0; i < CC; i++) {
pixel[i] += buffer_data[i] * lanczos_val; pixel[i] += buffer_data[i] * lanczos_val;
}
} }
T *dst_data = ((T *)p_dst) + (dst_y * dst_width + dst_x) * CC; T *dst_data = ((T *)p_dst) + (dst_y * dst_width + dst_x) * CC;
@ -872,12 +889,13 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict
for (uint32_t i = 0; i < CC; i++) { for (uint32_t i = 0; i < CC; i++) {
pixel[i] /= weight; pixel[i] /= weight;
if (sizeof(T) == 1) //byte if (sizeof(T) == 1) { //byte
dst_data[i] = CLAMP(Math::fast_ftoi(pixel[i]), 0, 255); dst_data[i] = CLAMP(Math::fast_ftoi(pixel[i]), 0, 255);
else if (sizeof(T) == 2) //half float } else if (sizeof(T) == 2) { //half float
dst_data[i] = Math::make_half_float(pixel[i]); dst_data[i] = Math::make_half_float(pixel[i]);
else // float } else { // float
dst_data[i] = pixel[i]; dst_data[i] = pixel[i];
}
} }
} }
} }
@ -910,8 +928,9 @@ void Image::resize_to_po2(bool p_square) {
} }
if (w == width && h == height) { if (w == width && h == height) {
if (!p_square || w == h) if (!p_square || w == h) {
return; //nothing to do return; //nothing to do
}
} }
resize(w, h); resize(w, h);
@ -929,8 +948,9 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, "Image height cannot be greater than " + itos(MAX_HEIGHT) + "."); ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, "Image height cannot be greater than " + itos(MAX_HEIGHT) + ".");
ERR_FAIL_COND_MSG(p_width * p_height > MAX_PIXELS, "Too many pixels for image, maximum is " + itos(MAX_PIXELS)); ERR_FAIL_COND_MSG(p_width * p_height > MAX_PIXELS, "Too many pixels for image, maximum is " + itos(MAX_PIXELS));
if (p_width == width && p_height == height) if (p_width == width && p_height == height) {
return; return;
}
Image dst(p_width, p_height, false, format); Image dst(p_width, p_height, false, format);
@ -1213,8 +1233,9 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
dst._copy_internals_from(dst2); dst._copy_internals_from(dst2);
} }
if (had_mipmaps) if (had_mipmaps) {
dst.generate_mipmaps(); dst.generate_mipmaps();
}
_copy_internals_from(dst); _copy_internals_from(dst);
} }
@ -1233,8 +1254,9 @@ void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) {
will most likely either not be used much, or in critical areas, for now it won't, because will most likely either not be used much, or in critical areas, for now it won't, because
it's a waste of time. */ it's a waste of time. */
if (p_width == width && p_height == height && p_x == 0 && p_y == 0) if (p_width == width && p_height == height && p_x == 0 && p_y == 0) {
return; return;
}
uint8_t pdata[16]; //largest is 16 uint8_t pdata[16]; //largest is 16
uint32_t pixel_size = get_format_pixel_size(format); uint32_t pixel_size = get_format_pixel_size(format);
@ -1250,8 +1272,9 @@ void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) {
for (int y = p_y; y < m_h; y++) { for (int y = p_y; y < m_h; y++) {
for (int x = p_x; x < m_w; x++) { for (int x = p_x; x < m_w; x++) {
if ((x >= width || y >= height)) { if ((x >= width || y >= height)) {
for (uint32_t i = 0; i < pixel_size; i++) for (uint32_t i = 0; i < pixel_size; i++) {
pdata[i] = 0; pdata[i] = 0;
}
} else { } else {
_get_pixelb(x, y, pixel_size, r, pdata); _get_pixelb(x, y, pixel_size, r, pdata);
} }
@ -1261,8 +1284,9 @@ void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) {
} }
} }
if (has_mipmaps()) if (has_mipmaps()) {
dst.generate_mipmaps(); dst.generate_mipmaps();
}
_copy_internals_from(dst); _copy_internals_from(dst);
} }
@ -1362,15 +1386,17 @@ int Image::_get_dst_image_size(int p_width, int p_height, Format p_format, int &
*r_mm_height = bh; *r_mm_height = bh;
} }
if (p_mipmaps >= 0 && mm == p_mipmaps) if (p_mipmaps >= 0 && mm == p_mipmaps) {
break; break;
}
if (p_mipmaps >= 0) { if (p_mipmaps >= 0) {
w = MAX(minw, w >> 1); w = MAX(minw, w >> 1);
h = MAX(minh, h >> 1); h = MAX(minh, h >> 1);
} else { } else {
if (w == minw && h == minh) if (w == minw && h == minh) {
break; break;
}
w = MAX(minw, w >> 1); w = MAX(minw, w >> 1);
h = MAX(minh, h >> 1); h = MAX(minh, h >> 1);
} }
@ -1429,8 +1455,9 @@ void Image::expand_x2_hq2x() {
Format current = format; Format current = format;
if (current != FORMAT_RGBA8) if (current != FORMAT_RGBA8) {
convert(FORMAT_RGBA8); convert(FORMAT_RGBA8);
}
Vector<uint8_t> dest; Vector<uint8_t> dest;
dest.resize(width * 2 * height * 2 * 4); dest.resize(width * 2 * height * 2 * 4);
@ -1448,8 +1475,9 @@ void Image::expand_x2_hq2x() {
height *= 2; height *= 2;
data = dest; data = dest;
if (current != FORMAT_RGBA8) if (current != FORMAT_RGBA8) {
convert(current); convert(current);
}
// FIXME: This is likely meant to use "used_mipmaps" as defined above, but if we do, // FIXME: This is likely meant to use "used_mipmaps" as defined above, but if we do,
// we end up with a regression: GH-22747 // we end up with a regression: GH-22747
@ -1609,17 +1637,19 @@ Error Image::generate_mipmaps(bool p_renormalize) {
_generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
break; break;
case FORMAT_RGB8: case FORMAT_RGB8:
if (p_renormalize) if (p_renormalize) {
_generate_po2_mipmap<uint8_t, 3, true, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); _generate_po2_mipmap<uint8_t, 3, true, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
else } else {
_generate_po2_mipmap<uint8_t, 3, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); _generate_po2_mipmap<uint8_t, 3, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
}
break; break;
case FORMAT_RGBA8: case FORMAT_RGBA8:
if (p_renormalize) if (p_renormalize) {
_generate_po2_mipmap<uint8_t, 4, true, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); _generate_po2_mipmap<uint8_t, 4, true, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
else } else {
_generate_po2_mipmap<uint8_t, 4, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); _generate_po2_mipmap<uint8_t, 4, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
}
break; break;
case FORMAT_RF: case FORMAT_RF:
_generate_po2_mipmap<float, 1, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h); _generate_po2_mipmap<float, 1, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
@ -1628,17 +1658,19 @@ Error Image::generate_mipmaps(bool p_renormalize) {
_generate_po2_mipmap<float, 2, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h); _generate_po2_mipmap<float, 2, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
break; break;
case FORMAT_RGBF: case FORMAT_RGBF:
if (p_renormalize) if (p_renormalize) {
_generate_po2_mipmap<float, 3, true, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h); _generate_po2_mipmap<float, 3, true, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
else } else {
_generate_po2_mipmap<float, 3, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h); _generate_po2_mipmap<float, 3, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
}
break; break;
case FORMAT_RGBAF: case FORMAT_RGBAF:
if (p_renormalize) if (p_renormalize) {
_generate_po2_mipmap<float, 4, true, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h); _generate_po2_mipmap<float, 4, true, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
else } else {
_generate_po2_mipmap<float, 4, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h); _generate_po2_mipmap<float, 4, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
}
break; break;
case FORMAT_RH: case FORMAT_RH:
@ -1648,24 +1680,27 @@ Error Image::generate_mipmaps(bool p_renormalize) {
_generate_po2_mipmap<uint16_t, 2, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h); _generate_po2_mipmap<uint16_t, 2, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
break; break;
case FORMAT_RGBH: case FORMAT_RGBH:
if (p_renormalize) if (p_renormalize) {
_generate_po2_mipmap<uint16_t, 3, true, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h); _generate_po2_mipmap<uint16_t, 3, true, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
else } else {
_generate_po2_mipmap<uint16_t, 3, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h); _generate_po2_mipmap<uint16_t, 3, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
}
break; break;
case FORMAT_RGBAH: case FORMAT_RGBAH:
if (p_renormalize) if (p_renormalize) {
_generate_po2_mipmap<uint16_t, 4, true, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h); _generate_po2_mipmap<uint16_t, 4, true, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
else } else {
_generate_po2_mipmap<uint16_t, 4, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h); _generate_po2_mipmap<uint16_t, 4, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
}
break; break;
case FORMAT_RGBE9995: case FORMAT_RGBE9995:
if (p_renormalize) if (p_renormalize) {
_generate_po2_mipmap<uint32_t, 1, true, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(&wp[prev_ofs]), reinterpret_cast<uint32_t *>(&wp[ofs]), prev_w, prev_h); _generate_po2_mipmap<uint32_t, 1, true, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(&wp[prev_ofs]), reinterpret_cast<uint32_t *>(&wp[ofs]), prev_w, prev_h);
else } else {
_generate_po2_mipmap<uint32_t, 1, false, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(&wp[prev_ofs]), reinterpret_cast<uint32_t *>(&wp[ofs]), prev_w, prev_h); _generate_po2_mipmap<uint32_t, 1, false, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(&wp[prev_ofs]), reinterpret_cast<uint32_t *>(&wp[ofs]), prev_w, prev_h);
}
break; break;
default: { default: {
@ -1877,11 +1912,13 @@ Error Image::generate_mipmap_roughness(RoughnessChannel p_roughness_channel, con
} }
void Image::clear_mipmaps() { void Image::clear_mipmaps() {
if (!mipmaps) if (!mipmaps) {
return; return;
}
if (empty()) if (empty()) {
return; return;
}
int ofs, w, h; int ofs, w, h;
_get_mipmap_offset_and_size(1, ofs, w, h); _get_mipmap_offset_and_size(1, ofs, w, h);
@ -1984,15 +2021,17 @@ void Image::create(const char **p_xpm) {
} }
//skip spaces //skip spaces
while (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == 0) { while (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == 0) {
if (*line_ptr == 0) if (*line_ptr == 0) {
break; break;
}
line_ptr++; line_ptr++;
} }
if (*line_ptr == 'c') { if (*line_ptr == 'c') {
line_ptr++; line_ptr++;
while (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == 0) { while (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == 0) {
if (*line_ptr == 0) if (*line_ptr == 0) {
break; break;
}
line_ptr++; line_ptr++;
} }
@ -2006,14 +2045,15 @@ void Image::create(const char **p_xpm) {
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
char v = line_ptr[i]; char v = line_ptr[i];
if (v >= '0' && v <= '9') if (v >= '0' && v <= '9') {
v -= '0'; v -= '0';
else if (v >= 'A' && v <= 'F') } else if (v >= 'A' && v <= 'F') {
v = (v - 'A') + 10; v = (v - 'A') + 10;
else if (v >= 'a' && v <= 'f') } else if (v >= 'a' && v <= 'f') {
v = (v - 'a') + 10; v = (v - 'a') + 10;
else } else {
break; break;
}
switch (i) { switch (i) {
case 0: case 0:
@ -2057,8 +2097,9 @@ void Image::create(const char **p_xpm) {
int y = line - colormap_size - 1; int y = line - colormap_size - 1;
for (int x = 0; x < size_width; x++) { for (int x = 0; x < size_width; x++) {
char pixelstr[6] = { 0, 0, 0, 0, 0, 0 }; char pixelstr[6] = { 0, 0, 0, 0, 0, 0 };
for (int i = 0; i < pixelchars; i++) for (int i = 0; i < pixelchars; i++) {
pixelstr[i] = line_ptr[x * pixelchars + i]; pixelstr[i] = line_ptr[x * pixelchars + i];
}
Color *colorptr = colormap.getptr(pixelstr); Color *colorptr = colormap.getptr(pixelstr);
ERR_FAIL_COND(!colorptr); ERR_FAIL_COND(!colorptr);
@ -2069,8 +2110,9 @@ void Image::create(const char **p_xpm) {
_put_pixelb(x, y, pixel_size, w, pixel); _put_pixelb(x, y, pixel_size, w, pixel);
} }
if (y == (size_height - 1)) if (y == (size_height - 1)) {
status = DONE; status = DONE;
}
} break; } break;
default: { default: {
} }
@ -2104,13 +2146,15 @@ void Image::create(const char **p_xpm) {
bool Image::is_invisible() const { bool Image::is_invisible() const {
if (format == FORMAT_L8 || if (format == FORMAT_L8 ||
format == FORMAT_RGB8 || format == FORMAT_RG8) format == FORMAT_RGB8 || format == FORMAT_RG8) {
return false; return false;
}
int len = data.size(); int len = data.size();
if (len == 0) if (len == 0) {
return true; return true;
}
int w, h; int w, h;
_get_mipmap_offset_and_size(1, len, w, h); _get_mipmap_offset_and_size(1, len, w, h);
@ -2150,8 +2194,9 @@ bool Image::is_invisible() const {
Image::AlphaMode Image::detect_alpha() const { Image::AlphaMode Image::detect_alpha() const {
int len = data.size(); int len = data.size();
if (len == 0) if (len == 0) {
return ALPHA_NONE; return ALPHA_NONE;
}
int w, h; int w, h;
_get_mipmap_offset_and_size(1, len, w, h); _get_mipmap_offset_and_size(1, len, w, h);
@ -2185,12 +2230,13 @@ Image::AlphaMode Image::detect_alpha() const {
} }
} }
if (detected) if (detected) {
return ALPHA_BLEND; return ALPHA_BLEND;
else if (bit) } else if (bit) {
return ALPHA_BIT; return ALPHA_BIT;
else } else {
return ALPHA_NONE; return ALPHA_NONE;
}
} }
Error Image::load(const String &p_path) { Error Image::load(const String &p_path) {
@ -2203,8 +2249,9 @@ Error Image::load(const String &p_path) {
} }
Error Image::save_png(const String &p_path) const { Error Image::save_png(const String &p_path) const {
if (save_png_func == nullptr) if (save_png_func == nullptr) {
return ERR_UNAVAILABLE; return ERR_UNAVAILABLE;
}
return save_png_func(p_path, Ref<Image>((Image *)this)); return save_png_func(p_path, Ref<Image>((Image *)this));
} }
@ -2218,8 +2265,9 @@ Vector<uint8_t> Image::save_png_to_buffer() const {
} }
Error Image::save_exr(const String &p_path, bool p_grayscale) const { Error Image::save_exr(const String &p_path, bool p_grayscale) const {
if (save_exr_func == nullptr) if (save_exr_func == nullptr) {
return ERR_UNAVAILABLE; return ERR_UNAVAILABLE;
}
return save_exr_func(p_path, Ref<Image>((Image *)this), p_grayscale); return save_exr_func(p_path, Ref<Image>((Image *)this), p_grayscale);
} }
@ -2265,18 +2313,19 @@ bool Image::is_compressed() const {
} }
Error Image::decompress() { Error Image::decompress() {
if (((format >= FORMAT_DXT1 && format <= FORMAT_RGTC_RG) || (format == FORMAT_DXT5_RA_AS_RG)) && _image_decompress_bc) if (((format >= FORMAT_DXT1 && format <= FORMAT_RGTC_RG) || (format == FORMAT_DXT5_RA_AS_RG)) && _image_decompress_bc) {
_image_decompress_bc(this); _image_decompress_bc(this);
else if (format >= FORMAT_BPTC_RGBA && format <= FORMAT_BPTC_RGBFU && _image_decompress_bptc) } else if (format >= FORMAT_BPTC_RGBA && format <= FORMAT_BPTC_RGBFU && _image_decompress_bptc) {
_image_decompress_bptc(this); _image_decompress_bptc(this);
else if (format >= FORMAT_PVRTC2 && format <= FORMAT_PVRTC4A && _image_decompress_pvrtc) } else if (format >= FORMAT_PVRTC2 && format <= FORMAT_PVRTC4A && _image_decompress_pvrtc) {
_image_decompress_pvrtc(this); _image_decompress_pvrtc(this);
else if (format == FORMAT_ETC && _image_decompress_etc1) } else if (format == FORMAT_ETC && _image_decompress_etc1) {
_image_decompress_etc1(this); _image_decompress_etc1(this);
else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RA_AS_RG && _image_decompress_etc2) } else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RA_AS_RG && _image_decompress_etc2) {
_image_decompress_etc2(this); _image_decompress_etc2(this);
else } else {
return ERR_UNAVAILABLE; return ERR_UNAVAILABLE;
}
return OK; return OK;
} }
@ -2343,35 +2392,43 @@ Image::Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const V
} }
Rect2 Image::get_used_rect() const { Rect2 Image::get_used_rect() const {
if (format != FORMAT_LA8 && format != FORMAT_RGBA8 && format != FORMAT_RGBAF && format != FORMAT_RGBAH && format != FORMAT_RGBA4444 && format != FORMAT_RGB565) if (format != FORMAT_LA8 && format != FORMAT_RGBA8 && format != FORMAT_RGBAF && format != FORMAT_RGBAH && format != FORMAT_RGBA4444 && format != FORMAT_RGB565) {
return Rect2(Point2(), Size2(width, height)); return Rect2(Point2(), Size2(width, height));
}
int len = data.size(); int len = data.size();
if (len == 0) if (len == 0) {
return Rect2(); return Rect2();
}
int minx = 0xFFFFFF, miny = 0xFFFFFFF; int minx = 0xFFFFFF, miny = 0xFFFFFFF;
int maxx = -1, maxy = -1; int maxx = -1, maxy = -1;
for (int j = 0; j < height; j++) { for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) { for (int i = 0; i < width; i++) {
if (!(get_pixel(i, j).a > 0)) if (!(get_pixel(i, j).a > 0)) {
continue; continue;
if (i > maxx) }
if (i > maxx) {
maxx = i; maxx = i;
if (j > maxy) }
if (j > maxy) {
maxy = j; maxy = j;
if (i < minx) }
if (i < minx) {
minx = i; minx = i;
if (j < miny) }
if (j < miny) {
miny = j; miny = j;
}
} }
} }
if (maxx == -1) if (maxx == -1) {
return Rect2(); return Rect2();
else } else {
return Rect2(minx, miny, maxx - minx + 1, maxy - miny + 1); return Rect2(minx, miny, maxx - minx + 1, maxy - miny + 1);
}
} }
Ref<Image> Image::get_rect(const Rect2 &p_area) const { Ref<Image> Image::get_rect(const Rect2 &p_area) const {
@ -2391,13 +2448,16 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po
Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect); Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
if (p_dest.x < 0) if (p_dest.x < 0) {
clipped_src_rect.position.x = ABS(p_dest.x); clipped_src_rect.position.x = ABS(p_dest.x);
if (p_dest.y < 0) }
if (p_dest.y < 0) {
clipped_src_rect.position.y = ABS(p_dest.y); clipped_src_rect.position.y = ABS(p_dest.y);
}
if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) {
return; return;
}
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y)); Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size)); Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
@ -2443,13 +2503,16 @@ void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, co
Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect); Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
if (p_dest.x < 0) if (p_dest.x < 0) {
clipped_src_rect.position.x = ABS(p_dest.x); clipped_src_rect.position.x = ABS(p_dest.x);
if (p_dest.y < 0) }
if (p_dest.y < 0) {
clipped_src_rect.position.y = ABS(p_dest.y); clipped_src_rect.position.y = ABS(p_dest.y);
}
if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) {
return; return;
}
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y)); Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size)); Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
@ -2494,13 +2557,16 @@ void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const P
Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect); Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
if (p_dest.x < 0) if (p_dest.x < 0) {
clipped_src_rect.position.x = ABS(p_dest.x); clipped_src_rect.position.x = ABS(p_dest.x);
if (p_dest.y < 0) }
if (p_dest.y < 0) {
clipped_src_rect.position.y = ABS(p_dest.y); clipped_src_rect.position.y = ABS(p_dest.y);
}
if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) {
return; return;
}
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y)); Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size)); Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
@ -2541,13 +2607,16 @@ void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, c
Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect); Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
if (p_dest.x < 0) if (p_dest.x < 0) {
clipped_src_rect.position.x = ABS(p_dest.x); clipped_src_rect.position.x = ABS(p_dest.x);
if (p_dest.y < 0) }
if (p_dest.y < 0) {
clipped_src_rect.position.y = ABS(p_dest.y); clipped_src_rect.position.y = ABS(p_dest.y);
}
if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) {
return; return;
}
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y)); Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size)); Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
@ -2892,14 +2961,18 @@ Image::UsedChannels Image::detect_used_channels(CompressSource p_source) {
for (int j = 0; j < height; j++) { for (int j = 0; j < height; j++) {
Color col = get_pixel(i, j); Color col = get_pixel(i, j);
if (col.r > 0.001) if (col.r > 0.001) {
r = true; r = true;
if (col.g > 0.001) }
if (col.g > 0.001) {
g = true; g = true;
if (col.b > 0.001) }
if (col.b > 0.001) {
b = true; b = true;
if (col.a < 0.999) }
if (col.a < 0.999) {
a = true; a = true;
}
if (col.r != col.b || col.r != col.g || col.b != col.g) { if (col.r != col.b || col.r != col.g || col.b != col.g) {
c = true; c = true;
@ -2909,18 +2982,19 @@ Image::UsedChannels Image::detect_used_channels(CompressSource p_source) {
UsedChannels used_channels; UsedChannels used_channels;
if (!c && !a) if (!c && !a) {
used_channels = USED_CHANNELS_L; used_channels = USED_CHANNELS_L;
else if (!c && a) } else if (!c && a) {
used_channels = USED_CHANNELS_LA; used_channels = USED_CHANNELS_LA;
else if (r && !g && !b && !a) } else if (r && !g && !b && !a) {
used_channels = USED_CHANNELS_R; used_channels = USED_CHANNELS_R;
else if (r && g && !b && !a) } else if (r && g && !b && !a) {
used_channels = USED_CHANNELS_RG; used_channels = USED_CHANNELS_RG;
else if (r && g && b && !a) } else if (r && g && b && !a) {
used_channels = USED_CHANNELS_RGB; used_channels = USED_CHANNELS_RGB;
else } else {
used_channels = USED_CHANNELS_RGBA; used_channels = USED_CHANNELS_RGBA;
}
if (p_source == COMPRESS_SOURCE_SRGB && (used_channels == USED_CHANNELS_R || used_channels == USED_CHANNELS_RG)) { if (p_source == COMPRESS_SOURCE_SRGB && (used_channels == USED_CHANNELS_R || used_channels == USED_CHANNELS_RG)) {
//R and RG do not support SRGB //R and RG do not support SRGB
@ -3129,8 +3203,9 @@ void Image::normalmap_to_xy() {
} }
Ref<Image> Image::rgbe_to_srgb() { Ref<Image> Image::rgbe_to_srgb() {
if (data.size() == 0) if (data.size() == 0) {
return Ref<Image>(); return Ref<Image>();
}
ERR_FAIL_COND_V(format != FORMAT_RGBE9995, Ref<Image>()); ERR_FAIL_COND_V(format != FORMAT_RGBE9995, Ref<Image>());
@ -3193,13 +3268,15 @@ void Image::bumpmap_to_normalmap(float bump_scale) {
for (int ty = 0; ty < height; ty++) { for (int ty = 0; ty < height; ty++) {
int py = ty + 1; int py = ty + 1;
if (py >= height) if (py >= height) {
py -= height; py -= height;
}
for (int tx = 0; tx < width; tx++) { for (int tx = 0; tx < width; tx++) {
int px = tx + 1; int px = tx + 1;
if (px >= width) if (px >= width) {
px -= width; px -= width;
}
float here = read_ptr[ty * width + tx]; float here = read_ptr[ty * width + tx];
float to_right = read_ptr[ty * width + px]; float to_right = read_ptr[ty * width + px];
float above = read_ptr[py * width + tx]; float above = read_ptr[py * width + tx];
@ -3221,8 +3298,9 @@ void Image::bumpmap_to_normalmap(float bump_scale) {
} }
void Image::srgb_to_linear() { void Image::srgb_to_linear() {
if (data.size() == 0) if (data.size() == 0) {
return; return;
}
static const uint8_t srgb2lin[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 26, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 33, 34, 35, 36, 36, 37, 38, 38, 39, 40, 41, 42, 42, 43, 44, 45, 46, 47, 47, 48, 49, 50, 51, 52, 53, 54, 55, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84, 85, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 101, 102, 103, 105, 106, 107, 109, 110, 112, 113, 114, 116, 117, 119, 120, 122, 123, 125, 126, 128, 129, 131, 132, 134, 135, 137, 139, 140, 142, 144, 145, 147, 148, 150, 152, 153, 155, 157, 159, 160, 162, 164, 166, 167, 169, 171, 173, 175, 176, 178, 180, 182, 184, 186, 188, 190, 192, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 218, 220, 222, 224, 226, 228, 230, 232, 235, 237, 239, 241, 243, 245, 248, 250, 252, 255 }; static const uint8_t srgb2lin[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 26, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 33, 34, 35, 36, 36, 37, 38, 38, 39, 40, 41, 42, 42, 43, 44, 45, 46, 47, 47, 48, 49, 50, 51, 52, 53, 54, 55, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84, 85, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 101, 102, 103, 105, 106, 107, 109, 110, 112, 113, 114, 116, 117, 119, 120, 122, 123, 125, 126, 128, 129, 131, 132, 134, 135, 137, 139, 140, 142, 144, 145, 147, 148, 150, 152, 153, 155, 157, 159, 160, 162, 164, 166, 167, 169, 171, 173, 175, 176, 178, 180, 182, 184, 186, 188, 190, 192, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 218, 220, 222, 224, 226, 228, 230, 232, 235, 237, 239, 241, 243, 245, 248, 250, 252, 255 };
@ -3251,11 +3329,13 @@ void Image::srgb_to_linear() {
} }
void Image::premultiply_alpha() { void Image::premultiply_alpha() {
if (data.size() == 0) if (data.size() == 0) {
return; return;
}
if (format != FORMAT_RGBA8) if (format != FORMAT_RGBA8) {
return; //not needed return; //not needed
}
uint8_t *data_ptr = data.ptrw(); uint8_t *data_ptr = data.ptrw();
@ -3271,11 +3351,13 @@ void Image::premultiply_alpha() {
} }
void Image::fix_alpha_edges() { void Image::fix_alpha_edges() {
if (data.size() == 0) if (data.size() == 0) {
return; return;
}
if (format != FORMAT_RGBA8) if (format != FORMAT_RGBA8) {
return; //not needed return; //not needed
}
Vector<uint8_t> dcopy = data; Vector<uint8_t> dcopy = data;
const uint8_t *srcptr = dcopy.ptr(); const uint8_t *srcptr = dcopy.ptr();
@ -3291,8 +3373,9 @@ void Image::fix_alpha_edges() {
const uint8_t *rptr = &srcptr[(i * width + j) * 4]; const uint8_t *rptr = &srcptr[(i * width + j) * 4];
uint8_t *wptr = &data_ptr[(i * width + j) * 4]; uint8_t *wptr = &data_ptr[(i * width + j) * 4];
if (rptr[3] >= alpha_threshold) if (rptr[3] >= alpha_threshold) {
continue; continue;
}
int closest_dist = max_dist; int closest_dist = max_dist;
uint8_t closest_color[3]; uint8_t closest_color[3];
@ -3307,13 +3390,15 @@ void Image::fix_alpha_edges() {
int dy = i - k; int dy = i - k;
int dx = j - l; int dx = j - l;
int dist = dy * dy + dx * dx; int dist = dy * dy + dx * dx;
if (dist >= closest_dist) if (dist >= closest_dist) {
continue; continue;
}
const uint8_t *rp2 = &srcptr[(k * width + l) << 2]; const uint8_t *rp2 = &srcptr[(k * width + l) << 2];
if (rp2[3] < alpha_threshold) if (rp2[3] < alpha_threshold) {
continue; continue;
}
closest_dist = dist; closest_dist = dist;
closest_color[0] = rp2[0]; closest_color[0] = rp2[0];

View File

@ -222,8 +222,9 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
const PropertyInfo &pi = E->get(); const PropertyInfo &pi = E->get();
if (!pi.name.begins_with("input/")) if (!pi.name.begins_with("input/")) {
continue; continue;
}
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length()); String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
r_options->push_back(quote_style + name + quote_style); r_options->push_back(quote_style + name + quote_style);
@ -241,8 +242,9 @@ void Input::SpeedTrack::update(const Vector2 &p_delta_p) {
accum += p_delta_p; accum += p_delta_p;
accum_t += delta_t; accum_t += delta_t;
if (accum_t > max_ref_frame * 10) if (accum_t > max_ref_frame * 10) {
accum_t = max_ref_frame * 10; accum_t = max_ref_frame * 10;
}
while (accum_t >= min_ref_frame) { while (accum_t >= min_ref_frame) {
float slice_t = min_ref_frame / accum_t; float slice_t = min_ref_frame / accum_t;
@ -291,8 +293,9 @@ bool Input::is_action_pressed(const StringName &p_action) const {
bool Input::is_action_just_pressed(const StringName &p_action) const { bool Input::is_action_just_pressed(const StringName &p_action) const {
const Map<StringName, Action>::Element *E = action_state.find(p_action); const Map<StringName, Action>::Element *E = action_state.find(p_action);
if (!E) if (!E) {
return false; return false;
}
if (Engine::get_singleton()->is_in_physics_frame()) { if (Engine::get_singleton()->is_in_physics_frame()) {
return E->get().pressed && E->get().physics_frame == Engine::get_singleton()->get_physics_frames(); return E->get().pressed && E->get().physics_frame == Engine::get_singleton()->get_physics_frames();
@ -303,8 +306,9 @@ bool Input::is_action_just_pressed(const StringName &p_action) const {
bool Input::is_action_just_released(const StringName &p_action) const { bool Input::is_action_just_released(const StringName &p_action) const {
const Map<StringName, Action>::Element *E = action_state.find(p_action); const Map<StringName, Action>::Element *E = action_state.find(p_action);
if (!E) if (!E) {
return false; return false;
}
if (Engine::get_singleton()->is_in_physics_frame()) { if (Engine::get_singleton()->is_in_physics_frame()) {
return !E->get().pressed && E->get().physics_frame == Engine::get_singleton()->get_physics_frames(); return !E->get().pressed && E->get().physics_frame == Engine::get_singleton()->get_physics_frames();
@ -315,8 +319,9 @@ bool Input::is_action_just_released(const StringName &p_action) const {
float Input::get_action_strength(const StringName &p_action) const { float Input::get_action_strength(const StringName &p_action) const {
const Map<StringName, Action>::Element *E = action_state.find(p_action); const Map<StringName, Action>::Element *E = action_state.find(p_action);
if (!E) if (!E) {
return 0.0f; return 0.0f;
}
return E->get().strength; return E->get().strength;
} }
@ -446,10 +451,11 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
Ref<InputEventKey> k = p_event; Ref<InputEventKey> k = p_event;
if (k.is_valid() && !k->is_echo() && k->get_keycode() != 0) { if (k.is_valid() && !k->is_echo() && k->get_keycode() != 0) {
if (k->is_pressed()) if (k->is_pressed()) {
keys_pressed.insert(k->get_keycode()); keys_pressed.insert(k->get_keycode());
else } else {
keys_pressed.erase(k->get_keycode()); keys_pressed.erase(k->get_keycode());
}
} }
Ref<InputEventMouseButton> mb = p_event; Ref<InputEventMouseButton> mb = p_event;
@ -568,10 +574,11 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
if (jb.is_valid()) { if (jb.is_valid()) {
int c = _combine_device(jb->get_button_index(), jb->get_device()); int c = _combine_device(jb->get_button_index(), jb->get_device());
if (jb->is_pressed()) if (jb->is_pressed()) {
joy_buttons_pressed.insert(c); joy_buttons_pressed.insert(c);
else } else {
joy_buttons_pressed.erase(c); joy_buttons_pressed.erase(c);
}
} }
Ref<InputEventJoypadMotion> jm = p_event; Ref<InputEventJoypadMotion> jm = p_event;
@ -603,8 +610,9 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
} }
} }
if (event_dispatch_function) if (event_dispatch_function) {
event_dispatch_function(p_event); event_dispatch_function(p_event);
}
} }
void Input::set_joy_axis(int p_device, int p_axis, float p_value) { void Input::set_joy_axis(int p_device, int p_axis, float p_value) {
@ -776,8 +784,9 @@ Input::CursorShape Input::get_default_cursor_shape() const {
} }
void Input::set_default_cursor_shape(CursorShape p_shape) { void Input::set_default_cursor_shape(CursorShape p_shape) {
if (default_shape == p_shape) if (default_shape == p_shape) {
return; return;
}
default_shape = p_shape; default_shape = p_shape;
// The default shape is set in Viewport::_gui_input_event. To instantly // The default shape is set in Viewport::_gui_input_event. To instantly
@ -794,8 +803,9 @@ Input::CursorShape Input::get_current_cursor_shape() const {
} }
void Input::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { void Input::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
if (Engine::get_singleton()->is_editor_hint()) if (Engine::get_singleton()->is_editor_hint()) {
return; return;
}
set_custom_mouse_cursor_func(p_cursor, p_shape, p_hotspot); set_custom_mouse_cursor_func(p_cursor, p_shape, p_hotspot);
} }
@ -833,8 +843,9 @@ void Input::release_pressed_events() {
_joy_axis.clear(); _joy_axis.clear();
for (Map<StringName, Input::Action>::Element *E = action_state.front(); E; E = E->next()) { for (Map<StringName, Input::Action>::Element *E = action_state.front(); E; E = E->next()) {
if (E->get().pressed) if (E->get().pressed) {
action_release(E->key()); action_release(E->key());
}
} }
} }
@ -1064,8 +1075,9 @@ Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, i
const JoyBinding binding = mapping.bindings[i]; const JoyBinding binding = mapping.bindings[i];
if (binding.inputType == TYPE_AXIS && binding.input.axis.axis == p_axis) { if (binding.inputType == TYPE_AXIS && binding.input.axis.axis == p_axis) {
float value = p_value.value; float value = p_value.value;
if (binding.input.axis.invert) if (binding.input.axis.invert) {
value = -value; value = -value;
}
if (binding.input.axis.range == FULL_AXIS || if (binding.input.axis.range == FULL_AXIS ||
(binding.input.axis.range == POSITIVE_HALF_AXIS && value > 0) || (binding.input.axis.range == POSITIVE_HALF_AXIS && value > 0) ||
(binding.input.axis.range == NEGATIVE_HALF_AXIS && value < 0)) { (binding.input.axis.range == NEGATIVE_HALF_AXIS && value < 0)) {
@ -1152,16 +1164,18 @@ void Input::_get_mapped_hat_events(const JoyDeviceMapping &mapping, int p_hat, J
JoyButtonList Input::_get_output_button(String output) { JoyButtonList Input::_get_output_button(String output) {
for (int i = 0; _joy_buttons[i]; i++) { for (int i = 0; _joy_buttons[i]; i++) {
if (output == _joy_buttons[i]) if (output == _joy_buttons[i]) {
return JoyButtonList(i); return JoyButtonList(i);
}
} }
return JoyButtonList::JOY_INVALID_BUTTON; return JoyButtonList::JOY_INVALID_BUTTON;
} }
JoyAxisList Input::_get_output_axis(String output) { JoyAxisList Input::_get_output_axis(String output) {
for (int i = 0; _joy_axes[i]; i++) { for (int i = 0; _joy_axes[i]; i++) {
if (output == _joy_axes[i]) if (output == _joy_axes[i]) {
return JoyAxisList(i); return JoyAxisList(i);
}
} }
return JoyAxisList::JOY_INVALID_AXIS; return JoyAxisList::JOY_INVALID_AXIS;
} }
@ -1183,25 +1197,28 @@ void Input::parse_mapping(String p_mapping) {
int idx = 1; int idx = 1;
while (++idx < entry.size()) { while (++idx < entry.size()) {
if (entry[idx] == "") if (entry[idx] == "") {
continue; continue;
}
String output = entry[idx].get_slice(":", 0).replace(" ", ""); String output = entry[idx].get_slice(":", 0).replace(" ", "");
String input = entry[idx].get_slice(":", 1).replace(" ", ""); String input = entry[idx].get_slice(":", 1).replace(" ", "");
ERR_CONTINUE_MSG(output.length() < 1 || input.length() < 2, ERR_CONTINUE_MSG(output.length() < 1 || input.length() < 2,
String(entry[idx] + "\nInvalid device mapping entry: " + entry[idx])); String(entry[idx] + "\nInvalid device mapping entry: " + entry[idx]));
if (output == "platform") if (output == "platform") {
continue; continue;
}
JoyAxisRange output_range = FULL_AXIS; JoyAxisRange output_range = FULL_AXIS;
if (output[0] == '+' || output[0] == '-') { if (output[0] == '+' || output[0] == '-') {
ERR_CONTINUE_MSG(output.length() < 2, String(entry[idx] + "\nInvalid output: " + entry[idx])); ERR_CONTINUE_MSG(output.length() < 2, String(entry[idx] + "\nInvalid output: " + entry[idx]));
output = output.right(1); output = output.right(1);
if (output[0] == '+') if (output[0] == '+') {
output_range = POSITIVE_HALF_AXIS; output_range = POSITIVE_HALF_AXIS;
else if (output[0] == '-') } else if (output[0] == '-') {
output_range = NEGATIVE_HALF_AXIS; output_range = NEGATIVE_HALF_AXIS;
}
} }
JoyAxisRange input_range = FULL_AXIS; JoyAxisRange input_range = FULL_AXIS;
@ -1213,8 +1230,9 @@ void Input::parse_mapping(String p_mapping) {
input = input.right(1); input = input.right(1);
} }
bool invert_axis = false; bool invert_axis = false;
if (input[input.length() - 1] == '~') if (input[input.length() - 1] == '~') {
invert_axis = true; invert_axis = true;
}
JoyButtonList output_button = _get_output_button(output); JoyButtonList output_button = _get_output_button(output);
JoyAxisList output_axis = _get_output_axis(output); JoyAxisList output_axis = _get_output_axis(output);
@ -1372,8 +1390,9 @@ Input::Input() {
if (env_mapping != "") { if (env_mapping != "") {
Vector<String> entries = env_mapping.split("\n"); Vector<String> entries = env_mapping.split("\n");
for (int i = 0; i < entries.size(); i++) { for (int i = 0; i < entries.size(); i++) {
if (entries[i] == "") if (entries[i] == "") {
continue; continue;
}
parse_mapping(entries[i]); parse_mapping(entries[i]);
} }
} }

View File

@ -252,36 +252,45 @@ bool InputEventKey::is_echo() const {
uint32_t InputEventKey::get_keycode_with_modifiers() const { uint32_t InputEventKey::get_keycode_with_modifiers() const {
uint32_t sc = keycode; uint32_t sc = keycode;
if (get_control()) if (get_control()) {
sc |= KEY_MASK_CTRL; sc |= KEY_MASK_CTRL;
if (get_alt()) }
if (get_alt()) {
sc |= KEY_MASK_ALT; sc |= KEY_MASK_ALT;
if (get_shift()) }
if (get_shift()) {
sc |= KEY_MASK_SHIFT; sc |= KEY_MASK_SHIFT;
if (get_metakey()) }
if (get_metakey()) {
sc |= KEY_MASK_META; sc |= KEY_MASK_META;
}
return sc; return sc;
} }
uint32_t InputEventKey::get_physical_keycode_with_modifiers() const { uint32_t InputEventKey::get_physical_keycode_with_modifiers() const {
uint32_t sc = physical_keycode; uint32_t sc = physical_keycode;
if (get_control()) if (get_control()) {
sc |= KEY_MASK_CTRL; sc |= KEY_MASK_CTRL;
if (get_alt()) }
if (get_alt()) {
sc |= KEY_MASK_ALT; sc |= KEY_MASK_ALT;
if (get_shift()) }
if (get_shift()) {
sc |= KEY_MASK_SHIFT; sc |= KEY_MASK_SHIFT;
if (get_metakey()) }
if (get_metakey()) {
sc |= KEY_MASK_META; sc |= KEY_MASK_META;
}
return sc; return sc;
} }
String InputEventKey::as_text() const { String InputEventKey::as_text() const {
String kc = keycode_get_string(keycode); String kc = keycode_get_string(keycode);
if (kc == String()) if (kc == String()) {
return kc; return kc;
}
if (get_metakey()) { if (get_metakey()) {
kc = find_keycode_name(KEY_META) + ("+" + kc); kc = find_keycode_name(KEY_META) + ("+" + kc);
@ -300,8 +309,9 @@ String InputEventKey::as_text() const {
bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
Ref<InputEventKey> key = p_event; Ref<InputEventKey> key = p_event;
if (key.is_null()) if (key.is_null()) {
return false; return false;
}
bool match = false; bool match = false;
if (get_keycode() == 0) { if (get_keycode() == 0) {
@ -316,18 +326,21 @@ bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed
match = get_keycode() == key->get_keycode() && (!key->is_pressed() || (code & event_code) == code); match = get_keycode() == key->get_keycode() && (!key->is_pressed() || (code & event_code) == code);
} }
if (match) { if (match) {
if (p_pressed != nullptr) if (p_pressed != nullptr) {
*p_pressed = key->is_pressed(); *p_pressed = key->is_pressed();
if (p_strength != nullptr) }
if (p_strength != nullptr) {
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f; *p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
}
} }
return match; return match;
} }
bool InputEventKey::shortcut_match(const Ref<InputEvent> &p_event) const { bool InputEventKey::shortcut_match(const Ref<InputEvent> &p_event) const {
Ref<InputEventKey> key = p_event; Ref<InputEventKey> key = p_event;
if (key.is_null()) if (key.is_null()) {
return false; return false;
}
uint32_t code = get_keycode_with_modifiers(); uint32_t code = get_keycode_with_modifiers();
uint32_t event_code = key->get_keycode_with_modifiers(); uint32_t event_code = key->get_keycode_with_modifiers();
@ -459,15 +472,18 @@ Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, co
bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
Ref<InputEventMouseButton> mb = p_event; Ref<InputEventMouseButton> mb = p_event;
if (mb.is_null()) if (mb.is_null()) {
return false; return false;
}
bool match = mb->button_index == button_index; bool match = mb->button_index == button_index;
if (match) { if (match) {
if (p_pressed != nullptr) if (p_pressed != nullptr) {
*p_pressed = mb->is_pressed(); *p_pressed = mb->is_pressed();
if (p_strength != nullptr) }
if (p_strength != nullptr) {
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f; *p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
}
} }
return match; return match;
@ -616,8 +632,9 @@ String InputEventMouseMotion::as_text() const {
bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) { bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> motion = p_event; Ref<InputEventMouseMotion> motion = p_event;
if (motion.is_null()) if (motion.is_null()) {
return false; return false;
}
if (get_window_id() != motion->get_window_id()) { if (get_window_id() != motion->get_window_id()) {
return false; return false;
@ -698,15 +715,17 @@ bool InputEventJoypadMotion::is_pressed() const {
bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
Ref<InputEventJoypadMotion> jm = p_event; Ref<InputEventJoypadMotion> jm = p_event;
if (jm.is_null()) if (jm.is_null()) {
return false; return false;
}
bool match = (axis == jm->axis); // Matches even if not in the same direction, but returns a "not pressed" event. bool match = (axis == jm->axis); // Matches even if not in the same direction, but returns a "not pressed" event.
if (match) { if (match) {
bool same_direction = (((axis_value < 0) == (jm->axis_value < 0)) || jm->axis_value == 0); bool same_direction = (((axis_value < 0) == (jm->axis_value < 0)) || jm->axis_value == 0);
bool pressed = same_direction ? Math::abs(jm->get_axis_value()) >= p_deadzone : false; bool pressed = same_direction ? Math::abs(jm->get_axis_value()) >= p_deadzone : false;
if (p_pressed != nullptr) if (p_pressed != nullptr) {
*p_pressed = pressed; *p_pressed = pressed;
}
if (p_strength != nullptr) { if (p_strength != nullptr) {
if (pressed) { if (pressed) {
if (p_deadzone == 1.0f) { if (p_deadzone == 1.0f) {
@ -765,15 +784,18 @@ float InputEventJoypadButton::get_pressure() const {
bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
Ref<InputEventJoypadButton> jb = p_event; Ref<InputEventJoypadButton> jb = p_event;
if (jb.is_null()) if (jb.is_null()) {
return false; return false;
}
bool match = button_index == jb->button_index; bool match = button_index == jb->button_index;
if (match) { if (match) {
if (p_pressed != nullptr) if (p_pressed != nullptr) {
*p_pressed = jb->is_pressed(); *p_pressed = jb->is_pressed();
if (p_strength != nullptr) }
if (p_strength != nullptr) {
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f; *p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
}
} }
return match; return match;
@ -781,8 +803,9 @@ bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *
bool InputEventJoypadButton::shortcut_match(const Ref<InputEvent> &p_event) const { bool InputEventJoypadButton::shortcut_match(const Ref<InputEvent> &p_event) const {
Ref<InputEventJoypadButton> button = p_event; Ref<InputEventJoypadButton> button = p_event;
if (button.is_null()) if (button.is_null()) {
return false; return false;
}
return button_index == button->button_index; return button_index == button->button_index;
} }
@ -963,8 +986,9 @@ float InputEventAction::get_strength() const {
} }
bool InputEventAction::shortcut_match(const Ref<InputEvent> &p_event) const { bool InputEventAction::shortcut_match(const Ref<InputEvent> &p_event) const {
if (p_event.is_null()) if (p_event.is_null()) {
return false; return false;
}
return p_event->is_action(action); return p_event->is_action(action);
} }
@ -975,15 +999,18 @@ bool InputEventAction::is_action(const StringName &p_action) const {
bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
Ref<InputEventAction> act = p_event; Ref<InputEventAction> act = p_event;
if (act.is_null()) if (act.is_null()) {
return false; return false;
}
bool match = action == act->action; bool match = action == act->action;
if (match) { if (match) {
if (p_pressed != nullptr) if (p_pressed != nullptr) {
*p_pressed = act->pressed; *p_pressed = act->pressed;
if (p_strength != nullptr) }
if (p_strength != nullptr) {
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f; *p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
}
} }
return match; return match;
} }

View File

@ -70,8 +70,9 @@ void InputMap::erase_action(const StringName &p_action) {
Array InputMap::_get_actions() { Array InputMap::_get_actions() {
Array ret; Array ret;
List<StringName> actions = get_actions(); List<StringName> actions = get_actions();
if (actions.empty()) if (actions.empty()) {
return ret; return ret;
}
for (const List<StringName>::Element *E = actions.front(); E; E = E->next()) { for (const List<StringName>::Element *E = actions.front(); E; E = E->next()) {
ret.push_back(E->get()); ret.push_back(E->get());
@ -124,8 +125,9 @@ void InputMap::action_set_deadzone(const StringName &p_action, float p_deadzone)
void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event) { void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object."); ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object.");
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'."); ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
if (_find_event(input_map[p_action], p_event)) if (_find_event(input_map[p_action], p_event)) {
return; //already gots return; //already gots
}
input_map[p_action].inputs.push_back(p_event); input_map[p_action].inputs.push_back(p_event);
} }
@ -139,8 +141,9 @@ void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEve
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'."); ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
List<Ref<InputEvent>>::Element *E = _find_event(input_map[p_action], p_event); List<Ref<InputEvent>>::Element *E = _find_event(input_map[p_action], p_event);
if (E) if (E) {
input_map[p_action].inputs.erase(E); input_map[p_action].inputs.erase(E);
}
} }
void InputMap::action_erase_events(const StringName &p_action) { void InputMap::action_erase_events(const StringName &p_action) {
@ -163,8 +166,9 @@ Array InputMap::_get_action_list(const StringName &p_action) {
const List<Ref<InputEvent>> *InputMap::get_action_list(const StringName &p_action) { const List<Ref<InputEvent>> *InputMap::get_action_list(const StringName &p_action) {
const Map<StringName, Action>::Element *E = input_map.find(p_action); const Map<StringName, Action>::Element *E = input_map.find(p_action);
if (!E) if (!E) {
return nullptr; return nullptr;
}
return &E->get().inputs; return &E->get().inputs;
} }
@ -179,10 +183,12 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str
Ref<InputEventAction> input_event_action = p_event; Ref<InputEventAction> input_event_action = p_event;
if (input_event_action.is_valid()) { if (input_event_action.is_valid()) {
if (p_pressed != nullptr) if (p_pressed != nullptr) {
*p_pressed = input_event_action->is_pressed(); *p_pressed = input_event_action->is_pressed();
if (p_strength != nullptr) }
if (p_strength != nullptr) {
*p_strength = (p_pressed != nullptr && *p_pressed) ? input_event_action->get_strength() : 0.0f; *p_strength = (p_pressed != nullptr && *p_pressed) ? input_event_action->get_strength() : 0.0f;
}
return input_event_action->get_action() == p_action; return input_event_action->get_action() == p_action;
} }
@ -190,10 +196,12 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str
float strength; float strength;
List<Ref<InputEvent>>::Element *event = _find_event(E->get(), p_event, &pressed, &strength); List<Ref<InputEvent>>::Element *event = _find_event(E->get(), p_event, &pressed, &strength);
if (event != nullptr) { if (event != nullptr) {
if (p_pressed != nullptr) if (p_pressed != nullptr) {
*p_pressed = pressed; *p_pressed = pressed;
if (p_strength != nullptr) }
if (p_strength != nullptr) {
*p_strength = strength; *p_strength = strength;
}
return true; return true;
} else { } else {
return false; return false;
@ -213,8 +221,9 @@ void InputMap::load_from_globals() {
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
const PropertyInfo &pi = E->get(); const PropertyInfo &pi = E->get();
if (!pi.name.begins_with("input/")) if (!pi.name.begins_with("input/")) {
continue; continue;
}
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length()); String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
@ -225,8 +234,9 @@ void InputMap::load_from_globals() {
add_action(name, deadzone); add_action(name, deadzone);
for (int i = 0; i < events.size(); i++) { for (int i = 0; i < events.size(); i++) {
Ref<InputEvent> event = events[i]; Ref<InputEvent> event = events[i];
if (event.is_null()) if (event.is_null()) {
continue; continue;
}
action_add_event(name, event); action_add_event(name, event);
} }
} }

View File

@ -62,8 +62,9 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,
strm.opaque = Z_NULL; strm.opaque = Z_NULL;
int level = p_mode == MODE_DEFLATE ? zlib_level : gzip_level; int level = p_mode == MODE_DEFLATE ? zlib_level : gzip_level;
int err = deflateInit2(&strm, level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY); int err = deflateInit2(&strm, level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY);
if (err != Z_OK) if (err != Z_OK) {
return -1; return -1;
}
strm.avail_in = p_src_size; strm.avail_in = p_src_size;
int aout = deflateBound(&strm, p_src_size); int aout = deflateBound(&strm, p_src_size);
@ -97,8 +98,9 @@ int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) {
switch (p_mode) { switch (p_mode) {
case MODE_FASTLZ: { case MODE_FASTLZ: {
int ss = p_src_size + p_src_size * 6 / 100; int ss = p_src_size + p_src_size * 6 / 100;
if (ss < 66) if (ss < 66) {
ss = 66; ss = 66;
}
return ss; return ss;
} break; } break;
@ -111,8 +113,9 @@ int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) {
strm.zfree = zipio_free; strm.zfree = zipio_free;
strm.opaque = Z_NULL; strm.opaque = Z_NULL;
int err = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY); int err = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY);
if (err != Z_OK) if (err != Z_OK) {
return -1; return -1;
}
int aout = deflateBound(&strm, p_src_size); int aout = deflateBound(&strm, p_src_size);
deflateEnd(&strm); deflateEnd(&strm);
return aout; return aout;

View File

@ -63,8 +63,9 @@ PackedStringArray ConfigFile::_get_section_keys(const String &p_section) const {
void ConfigFile::set_value(const String &p_section, const String &p_key, const Variant &p_value) { void ConfigFile::set_value(const String &p_section, const String &p_key, const Variant &p_value) {
if (p_value.get_type() == Variant::NIL) { if (p_value.get_type() == Variant::NIL) {
//erase //erase
if (!values.has(p_section)) if (!values.has(p_section)) {
return; // ? return; // ?
}
values[p_section].erase(p_key); values[p_section].erase(p_key);
if (values[p_section].empty()) { if (values[p_section].empty()) {
values.erase(p_section); values.erase(p_section);
@ -94,8 +95,9 @@ bool ConfigFile::has_section(const String &p_section) const {
} }
bool ConfigFile::has_section_key(const String &p_section, const String &p_key) const { bool ConfigFile::has_section_key(const String &p_section, const String &p_key) const {
if (!values.has(p_section)) if (!values.has(p_section)) {
return false; return false;
}
return values[p_section].has(p_key); return values[p_section].has(p_key);
} }
@ -130,8 +132,9 @@ Error ConfigFile::save(const String &p_path) {
FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err); FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err);
if (err) { if (err) {
if (file) if (file) {
memdelete(file); memdelete(file);
}
return err; return err;
} }
@ -142,8 +145,9 @@ Error ConfigFile::save_encrypted(const String &p_path, const Vector<uint8_t> &p_
Error err; Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err); FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err);
if (err) if (err) {
return err; return err;
}
FileAccessEncrypted *fae = memnew(FileAccessEncrypted); FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse(f, p_key, FileAccessEncrypted::MODE_WRITE_AES256); err = fae->open_and_parse(f, p_key, FileAccessEncrypted::MODE_WRITE_AES256);
@ -159,8 +163,9 @@ Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass
Error err; Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err); FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err);
if (err) if (err) {
return err; return err;
}
FileAccessEncrypted *fae = memnew(FileAccessEncrypted); FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse_password(f, p_pass, FileAccessEncrypted::MODE_WRITE_AES256); err = fae->open_and_parse_password(f, p_pass, FileAccessEncrypted::MODE_WRITE_AES256);
@ -175,8 +180,9 @@ Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass
Error ConfigFile::_internal_save(FileAccess *file) { Error ConfigFile::_internal_save(FileAccess *file) {
for (OrderedHashMap<String, OrderedHashMap<String, Variant>>::Element E = values.front(); E; E = E.next()) { for (OrderedHashMap<String, OrderedHashMap<String, Variant>>::Element E = values.front(); E; E = E.next()) {
if (E != values.front()) if (E != values.front()) {
file->store_string("\n"); file->store_string("\n");
}
file->store_string("[" + E.key() + "]\n\n"); file->store_string("[" + E.key() + "]\n\n");
for (OrderedHashMap<String, Variant>::Element F = E.get().front(); F; F = F.next()) { for (OrderedHashMap<String, Variant>::Element F = E.get().front(); F; F = F.next()) {
@ -195,8 +201,9 @@ Error ConfigFile::load(const String &p_path) {
Error err; Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
if (!f) if (!f) {
return err; return err;
}
return _internal_load(p_path, f); return _internal_load(p_path, f);
} }
@ -205,8 +212,9 @@ Error ConfigFile::load_encrypted(const String &p_path, const Vector<uint8_t> &p_
Error err; Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
if (err) if (err) {
return err; return err;
}
FileAccessEncrypted *fae = memnew(FileAccessEncrypted); FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse(f, p_key, FileAccessEncrypted::MODE_READ); err = fae->open_and_parse(f, p_key, FileAccessEncrypted::MODE_READ);
@ -222,8 +230,9 @@ Error ConfigFile::load_encrypted_pass(const String &p_path, const String &p_pass
Error err; Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
if (err) if (err) {
return err; return err;
}
FileAccessEncrypted *fae = memnew(FileAccessEncrypted); FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse_password(f, p_pass, FileAccessEncrypted::MODE_READ); err = fae->open_and_parse_password(f, p_pass, FileAccessEncrypted::MODE_READ);

View File

@ -34,11 +34,12 @@
void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_mode, int p_block_size) { void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_mode, int p_block_size) {
magic = p_magic.ascii().get_data(); magic = p_magic.ascii().get_data();
if (magic.length() > 4) if (magic.length() > 4) {
magic = magic.substr(0, 4); magic = magic.substr(0, 4);
else { } else {
while (magic.length() < 4) while (magic.length() < 4) {
magic += " "; magic += " ";
}
} }
cmode = p_mode; cmode = p_mode;
@ -97,8 +98,9 @@ Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) { Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
ERR_FAIL_COND_V(p_mode_flags == READ_WRITE, ERR_UNAVAILABLE); ERR_FAIL_COND_V(p_mode_flags == READ_WRITE, ERR_UNAVAILABLE);
if (f) if (f) {
close(); close();
}
Error err; Error err;
f = FileAccess::open(p_path, p_mode_flags, &err); f = FileAccess::open(p_path, p_mode_flags, &err);
@ -134,8 +136,9 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
} }
void FileAccessCompressed::close() { void FileAccessCompressed::close() {
if (!f) if (!f) {
return; return;
}
if (writing) { if (writing) {
//save block table and all compressed blocks //save block table and all compressed blocks
@ -165,8 +168,9 @@ void FileAccessCompressed::close() {
} }
f->seek(16); //ok write block sizes f->seek(16); //ok write block sizes
for (int i = 0; i < bc; i++) for (int i = 0; i < bc; i++) {
f->store_32(block_sizes[i]); f->store_32(block_sizes[i]);
}
f->seek_end(); f->seek_end();
f->store_buffer((const uint8_t *)mgc.get_data(), mgc.length()); //magic at the end too f->store_buffer((const uint8_t *)mgc.get_data(), mgc.length()); //magic at the end too
@ -306,8 +310,9 @@ int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const {
} else { } else {
read_block--; read_block--;
at_end = true; at_end = true;
if (i < p_length - 1) if (i < p_length - 1) {
read_eof = true; read_eof = true;
}
return i; return i;
} }
} }
@ -337,22 +342,25 @@ void FileAccessCompressed::store_8(uint8_t p_dest) {
bool FileAccessCompressed::file_exists(const String &p_name) { bool FileAccessCompressed::file_exists(const String &p_name) {
FileAccess *fa = FileAccess::open(p_name, FileAccess::READ); FileAccess *fa = FileAccess::open(p_name, FileAccess::READ);
if (!fa) if (!fa) {
return false; return false;
}
memdelete(fa); memdelete(fa);
return true; return true;
} }
uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) { uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) {
if (f) if (f) {
return f->get_modified_time(p_file); return f->get_modified_time(p_file);
else } else {
return 0; return 0;
}
} }
uint32_t FileAccessCompressed::_get_unix_permissions(const String &p_file) { uint32_t FileAccessCompressed::_get_unix_permissions(const String &p_file) {
if (f) if (f) {
return f->_get_unix_permissions(p_file); return f->_get_unix_permissions(p_file);
}
return 0; return 0;
} }
@ -364,6 +372,7 @@ Error FileAccessCompressed::_set_unix_permissions(const String &p_file, uint32_t
} }
FileAccessCompressed::~FileAccessCompressed() { FileAccessCompressed::~FileAccessCompressed() {
if (f) if (f) {
close(); close();
}
} }

View File

@ -115,8 +115,9 @@ Error FileAccessEncrypted::_open(const String &p_path, int p_mode_flags) {
} }
void FileAccessEncrypted::close() { void FileAccessEncrypted::close() {
if (!file) if (!file) {
return; return;
}
if (writing) { if (writing) {
Vector<uint8_t> compressed; Vector<uint8_t> compressed;
@ -166,22 +167,25 @@ bool FileAccessEncrypted::is_open() const {
} }
String FileAccessEncrypted::get_path() const { String FileAccessEncrypted::get_path() const {
if (file) if (file) {
return file->get_path(); return file->get_path();
else } else {
return ""; return "";
}
} }
String FileAccessEncrypted::get_path_absolute() const { String FileAccessEncrypted::get_path_absolute() const {
if (file) if (file) {
return file->get_path_absolute(); return file->get_path_absolute();
else } else {
return ""; return "";
}
} }
void FileAccessEncrypted::seek(size_t p_position) { void FileAccessEncrypted::seek(size_t p_position) {
if (p_position > (size_t)data.size()) if (p_position > (size_t)data.size()) {
p_position = data.size(); p_position = data.size();
}
pos = p_position; pos = p_position;
eofed = false; eofed = false;
@ -270,8 +274,9 @@ void FileAccessEncrypted::store_8(uint8_t p_dest) {
bool FileAccessEncrypted::file_exists(const String &p_name) { bool FileAccessEncrypted::file_exists(const String &p_name) {
FileAccess *fa = FileAccess::open(p_name, FileAccess::READ); FileAccess *fa = FileAccess::open(p_name, FileAccess::READ);
if (!fa) if (!fa) {
return false; return false;
}
memdelete(fa); memdelete(fa);
return true; return true;
} }
@ -290,6 +295,7 @@ Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, uint32_t
} }
FileAccessEncrypted::~FileAccessEncrypted() { FileAccessEncrypted::~FileAccessEncrypted() {
if (file) if (file) {
close(); close();
}
} }

View File

@ -43,18 +43,20 @@ void FileAccessMemory::register_file(String p_name, Vector<uint8_t> p_data) {
} }
String name; String name;
if (ProjectSettings::get_singleton()) if (ProjectSettings::get_singleton()) {
name = ProjectSettings::get_singleton()->globalize_path(p_name); name = ProjectSettings::get_singleton()->globalize_path(p_name);
else } else {
name = p_name; name = p_name;
}
//name = DirAccess::normalize_path(name); //name = DirAccess::normalize_path(name);
(*files)[name] = p_data; (*files)[name] = p_data;
} }
void FileAccessMemory::cleanup() { void FileAccessMemory::cleanup() {
if (!files) if (!files) {
return; return;
}
memdelete(files); memdelete(files);
} }

View File

@ -115,8 +115,9 @@ void FileAccessNetworkClient::_thread_func() {
} }
} }
if (accesses.has(id)) if (accesses.has(id)) {
fa = accesses[id]; fa = accesses[id];
}
switch (response) { switch (response) {
case FileAccessNetwork::RESPONSE_OPEN: { case FileAccessNetwork::RESPONSE_OPEN: {
@ -140,8 +141,9 @@ void FileAccessNetworkClient::_thread_func() {
block.resize(len); block.resize(len);
client->get_data(block.ptrw(), len); client->get_data(block.ptrw(), len);
if (fa) //may have been queued if (fa) { //may have been queued
fa->_set_block(offset, block); fa->_set_block(offset, block);
}
} break; } break;
case FileAccessNetwork::RESPONSE_FILE_EXISTS: { case FileAccessNetwork::RESPONSE_FILE_EXISTS: {
@ -244,8 +246,9 @@ void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block)
void FileAccessNetwork::_respond(size_t p_len, Error p_status) { void FileAccessNetwork::_respond(size_t p_len, Error p_status) {
DEBUG_PRINT("GOT RESPONSE - len: " + itos(p_len) + " status: " + itos(p_status)); DEBUG_PRINT("GOT RESPONSE - len: " + itos(p_len) + " status: " + itos(p_status));
response = p_status; response = p_status;
if (response != OK) if (response != OK) {
return; return;
}
opened = true; opened = true;
total_size = p_len; total_size = p_len;
int pc = ((total_size - 1) / page_size) + 1; int pc = ((total_size - 1) / page_size) + 1;
@ -254,8 +257,9 @@ void FileAccessNetwork::_respond(size_t p_len, Error p_status) {
Error FileAccessNetwork::_open(const String &p_path, int p_mode_flags) { Error FileAccessNetwork::_open(const String &p_path, int p_mode_flags) {
ERR_FAIL_COND_V(p_mode_flags != READ, ERR_UNAVAILABLE); ERR_FAIL_COND_V(p_mode_flags != READ, ERR_UNAVAILABLE);
if (opened) if (opened) {
close(); close();
}
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton; FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
DEBUG_PRINT("open: " + p_path); DEBUG_PRINT("open: " + p_path);
@ -287,8 +291,9 @@ Error FileAccessNetwork::_open(const String &p_path, int p_mode_flags) {
} }
void FileAccessNetwork::close() { void FileAccessNetwork::close() {
if (!opened) if (!opened) {
return; return;
}
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton; FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
@ -342,8 +347,9 @@ uint8_t FileAccessNetwork::get_8() const {
} }
void FileAccessNetwork::_queue_page(int p_page) const { void FileAccessNetwork::_queue_page(int p_page) const {
if (p_page >= pages.size()) if (p_page >= pages.size()) {
return; return;
}
if (pages[p_page].buffer.empty() && !pages[p_page].queued) { if (pages[p_page].buffer.empty() && !pages[p_page].queued) {
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton; FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
{ {

View File

@ -54,12 +54,14 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o
pf.pack = pkg_path; pf.pack = pkg_path;
pf.offset = ofs; pf.offset = ofs;
pf.size = size; pf.size = size;
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++) {
pf.md5[i] = p_md5[i]; pf.md5[i] = p_md5[i];
}
pf.src = p_src; pf.src = p_src;
if (!exists || p_replace_files) if (!exists || p_replace_files) {
files[pmd5] = pf; files[pmd5] = pf;
}
if (!exists) { if (!exists) {
//search for dir //search for dir
@ -106,8 +108,9 @@ PackedData::PackedData() {
} }
void PackedData::_free_packed_dirs(PackedDir *p_dir) { void PackedData::_free_packed_dirs(PackedDir *p_dir) {
for (Map<String, PackedDir *>::Element *E = p_dir->subdirs.front(); E; E = E->next()) for (Map<String, PackedDir *>::Element *E = p_dir->subdirs.front(); E; E = E->next()) {
_free_packed_dirs(E->get()); _free_packed_dirs(E->get());
}
memdelete(p_dir); memdelete(p_dir);
} }
@ -122,8 +125,9 @@ PackedData::~PackedData() {
bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files) { bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ); FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) if (!f) {
return false; return false;
}
uint32_t magic = f->get_32(); uint32_t magic = f->get_32();
@ -252,8 +256,9 @@ uint8_t FileAccessPack::get_8() const {
} }
int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const { int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const {
if (eof) if (eof) {
return 0; return 0;
}
uint64_t to_read = p_length; uint64_t to_read = p_length;
if (to_read + pos > pf.size) { if (to_read + pos > pf.size) {
@ -263,8 +268,9 @@ int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const {
pos += p_length; pos += p_length;
if (to_read <= 0) if (to_read <= 0) {
return 0; return 0;
}
f->get_buffer(p_dst, to_read); f->get_buffer(p_dst, to_read);
return to_read; return to_read;
@ -276,8 +282,9 @@ void FileAccessPack::set_endian_swap(bool p_swap) {
} }
Error FileAccessPack::get_error() const { Error FileAccessPack::get_error() const {
if (eof) if (eof) {
return ERR_FILE_EOF; return ERR_FILE_EOF;
}
return OK; return OK;
} }
@ -308,8 +315,9 @@ FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFil
} }
FileAccessPack::~FileAccessPack() { FileAccessPack::~FileAccessPack() {
if (f) if (f) {
memdelete(f); memdelete(f);
}
} }
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
@ -378,8 +386,9 @@ Error DirAccessPack::change_dir(String p_dir) {
nd = nd.simplify_path(); nd = nd.simplify_path();
if (nd == "") if (nd == "") {
nd = "."; nd = ".";
}
if (nd.begins_with("/")) { if (nd.begins_with("/")) {
nd = nd.replace_first("/", ""); nd = nd.replace_first("/", "");
@ -390,10 +399,11 @@ Error DirAccessPack::change_dir(String p_dir) {
PackedData::PackedDir *pd; PackedData::PackedDir *pd;
if (absolute) if (absolute) {
pd = PackedData::get_singleton()->root; pd = PackedData::get_singleton()->root;
else } else {
pd = current; pd = current;
}
for (int i = 0; i < paths.size(); i++) { for (int i = 0; i < paths.size(); i++) {
String p = paths[i]; String p = paths[i];

View File

@ -175,10 +175,12 @@ public:
FileAccess *PackedData::try_open_path(const String &p_path) { FileAccess *PackedData::try_open_path(const String &p_path) {
PathMD5 pmd5(p_path.md5_buffer()); PathMD5 pmd5(p_path.md5_buffer());
Map<PathMD5, PackedFile>::Element *E = files.find(pmd5); Map<PathMD5, PackedFile>::Element *E = files.find(pmd5);
if (!E) if (!E) {
return nullptr; //not found return nullptr; //not found
if (E->get().offset == 0) }
if (E->get().offset == 0) {
return nullptr; //was erased return nullptr; //was erased
}
return E->get().src->get_file(p_path, &E->get()); return E->get().src->get_file(p_path, &E->get());
} }

View File

@ -149,14 +149,16 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files) { bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files) {
//printf("opening zip pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz")); //printf("opening zip pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz"));
if (p_path.get_extension().nocasecmp_to("zip") != 0 && p_path.get_extension().nocasecmp_to("pcz") != 0) if (p_path.get_extension().nocasecmp_to("zip") != 0 && p_path.get_extension().nocasecmp_to("pcz") != 0) {
return false; return false;
}
zlib_filefunc_def io; zlib_filefunc_def io;
FileAccess *fa = FileAccess::open(p_path, FileAccess::READ); FileAccess *fa = FileAccess::open(p_path, FileAccess::READ);
if (!fa) if (!fa) {
return false; return false;
}
io.opaque = fa; io.opaque = fa;
io.zopen_file = godot_open; io.zopen_file = godot_open;
io.zread_file = godot_read; io.zread_file = godot_read;
@ -252,8 +254,9 @@ Error FileAccessZip::_open(const String &p_path, int p_mode_flags) {
} }
void FileAccessZip::close() { void FileAccessZip::close() {
if (!zfile) if (!zfile) {
return; return;
}
ZipArchive *arch = ZipArchive::get_singleton(); ZipArchive *arch = ZipArchive::get_singleton();
ERR_FAIL_COND(!arch); ERR_FAIL_COND(!arch);
@ -300,12 +303,14 @@ uint8_t FileAccessZip::get_8() const {
int FileAccessZip::get_buffer(uint8_t *p_dst, int p_length) const { int FileAccessZip::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(!zfile, -1); ERR_FAIL_COND_V(!zfile, -1);
at_eof = unzeof(zfile); at_eof = unzeof(zfile);
if (at_eof) if (at_eof) {
return 0; return 0;
}
int read = unzReadCurrentFile(zfile, p_dst, p_length); int read = unzReadCurrentFile(zfile, p_dst, p_length);
ERR_FAIL_COND_V(read < 0, read); ERR_FAIL_COND_V(read < 0, read);
if (read < p_length) if (read < p_length) {
at_eof = true; at_eof = true;
}
return read; return read;
} }

View File

@ -240,8 +240,9 @@ int HTTPClient::get_response_code() const {
} }
Error HTTPClient::get_response_headers(List<String> *r_response) { Error HTTPClient::get_response_headers(List<String> *r_response) {
if (!response_headers.size()) if (!response_headers.size()) {
return ERR_INVALID_PARAMETER; return ERR_INVALID_PARAMETER;
}
for (int i = 0; i < response_headers.size(); i++) { for (int i = 0; i < response_headers.size(); i++) {
r_response->push_back(response_headers[i]); r_response->push_back(response_headers[i]);
@ -253,8 +254,9 @@ Error HTTPClient::get_response_headers(List<String> *r_response) {
} }
void HTTPClient::close() { void HTTPClient::close() {
if (tcp_connection->get_status() != StreamPeerTCP::STATUS_NONE) if (tcp_connection->get_status() != StreamPeerTCP::STATUS_NONE) {
tcp_connection->disconnect_from_host(); tcp_connection->disconnect_from_host();
}
connection.unref(); connection.unref();
status = STATUS_DISCONNECTED; status = STATUS_DISCONNECTED;
@ -393,8 +395,9 @@ Error HTTPClient::poll() {
return ERR_CONNECTION_ERROR; return ERR_CONNECTION_ERROR;
} }
if (rec == 0) if (rec == 0) {
return OK; // Still requesting, keep trying! return OK; // Still requesting, keep trying!
}
response_str.push_back(byte); response_str.push_back(byte);
int rs = response_str.size(); int rs = response_str.size();
@ -424,8 +427,9 @@ Error HTTPClient::poll() {
for (int i = 0; i < responses.size(); i++) { for (int i = 0; i < responses.size(); i++) {
String header = responses[i].strip_edges(); String header = responses[i].strip_edges();
String s = header.to_lower(); String s = header.to_lower();
if (s.length() == 0) if (s.length() == 0) {
continue; continue;
}
if (s.begins_with("content-length:")) { if (s.begins_with("content-length:")) {
body_size = s.substr(s.find(":") + 1, s.length()).strip_edges().to_int(); body_size = s.substr(s.find(":") + 1, s.length()).strip_edges().to_int();
body_left = body_size; body_left = body_size;
@ -501,8 +505,9 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
int rec = 0; int rec = 0;
err = _get_http_data(&b, 1, rec); err = _get_http_data(&b, 1, rec);
if (rec == 0) if (rec == 0) {
break; break;
}
chunk.push_back(b); chunk.push_back(b);
int cs = chunk.size(); int cs = chunk.size();
@ -524,8 +529,9 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
int rec = 0; int rec = 0;
err = _get_http_data(&b, 1, rec); err = _get_http_data(&b, 1, rec);
if (rec == 0) if (rec == 0) {
break; break;
}
chunk.push_back(b); chunk.push_back(b);
@ -540,13 +546,13 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
for (int i = 0; i < chunk.size() - 2; i++) { for (int i = 0; i < chunk.size() - 2; i++) {
char c = chunk[i]; char c = chunk[i];
int v = 0; int v = 0;
if (c >= '0' && c <= '9') if (c >= '0' && c <= '9') {
v = c - '0'; v = c - '0';
else if (c >= 'a' && c <= 'f') } else if (c >= 'a' && c <= 'f') {
v = c - 'a' + 10; v = c - 'a' + 10;
else if (c >= 'A' && c <= 'F') } else if (c >= 'A' && c <= 'F') {
v = c - 'A' + 10; v = c - 'A' + 10;
else { } else {
ERR_PRINT("HTTP Chunk len not in hex!!"); ERR_PRINT("HTTP Chunk len not in hex!!");
status = STATUS_CONNECTION_ERROR; status = STATUS_CONNECTION_ERROR;
break; break;
@ -615,8 +621,9 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
body_left -= rec; body_left -= rec;
} }
} }
if (err != OK) if (err != OK) {
break; break;
}
} }
} }
@ -727,8 +734,9 @@ Dictionary HTTPClient::_get_response_headers_as_dictionary() {
for (const List<String>::Element *E = rh.front(); E; E = E->next()) { for (const List<String>::Element *E = rh.front(); E; E = E->next()) {
const String &s = E->get(); const String &s = E->get();
int sp = s.find(":"); int sp = s.find(":");
if (sp == -1) if (sp == -1) {
continue; continue;
}
String key = s.substr(0, sp).strip_edges(); String key = s.substr(0, sp).strip_edges();
String value = s.substr(sp + 1, s.length()).strip_edges(); String value = s.substr(sp + 1, s.length()).strip_edges();
ret[key] = value; ret[key] = value;

View File

@ -36,8 +36,9 @@ bool ImageFormatLoader::recognize(const String &p_extension) const {
List<String> extensions; List<String> extensions;
get_recognized_extensions(&extensions); get_recognized_extensions(&extensions);
for (List<String>::Element *E = extensions.front(); E; E = E->next()) { for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
if (E->get().nocasecmp_to(p_extension) == 0) if (E->get().nocasecmp_to(p_extension) == 0) {
return true; return true;
}
} }
return false; return false;
@ -59,23 +60,26 @@ Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_c
String extension = p_file.get_extension(); String extension = p_file.get_extension();
for (int i = 0; i < loader.size(); i++) { for (int i = 0; i < loader.size(); i++) {
if (!loader[i]->recognize(extension)) if (!loader[i]->recognize(extension)) {
continue; continue;
}
Error err = loader[i]->load_image(p_image, f, p_force_linear, p_scale); Error err = loader[i]->load_image(p_image, f, p_force_linear, p_scale);
if (err != OK) { if (err != OK) {
ERR_PRINT("Error loading image: " + p_file); ERR_PRINT("Error loading image: " + p_file);
} }
if (err != ERR_FILE_UNRECOGNIZED) { if (err != ERR_FILE_UNRECOGNIZED) {
if (!p_custom) if (!p_custom) {
memdelete(f); memdelete(f);
}
return err; return err;
} }
} }
if (!p_custom) if (!p_custom) {
memdelete(f); memdelete(f);
}
return ERR_FILE_UNRECOGNIZED; return ERR_FILE_UNRECOGNIZED;
} }
@ -88,8 +92,9 @@ void ImageLoader::get_recognized_extensions(List<String> *p_extensions) {
ImageFormatLoader *ImageLoader::recognize(const String &p_extension) { ImageFormatLoader *ImageLoader::recognize(const String &p_extension) {
for (int i = 0; i < loader.size(); i++) { for (int i = 0; i < loader.size(); i++) {
if (loader[i]->recognize(p_extension)) if (loader[i]->recognize(p_extension)) {
return loader[i]; return loader[i];
}
} }
return nullptr; return nullptr;

View File

@ -61,8 +61,9 @@ struct _IP_ResolverPrivate {
IP::ResolverID find_empty_id() const { IP::ResolverID find_empty_id() const {
for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) { for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) {
if (queue[i].status == IP::RESOLVER_STATUS_NONE) if (queue[i].status == IP::RESOLVER_STATUS_NONE) {
return i; return i;
}
} }
return IP::RESOLVER_INVALID_ID; return IP::RESOLVER_INVALID_ID;
} }
@ -76,14 +77,16 @@ struct _IP_ResolverPrivate {
void resolve_queues() { void resolve_queues() {
for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) { for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) {
if (queue[i].status != IP::RESOLVER_STATUS_WAITING) if (queue[i].status != IP::RESOLVER_STATUS_WAITING) {
continue; continue;
}
queue[i].response = IP::get_singleton()->resolve_hostname(queue[i].hostname, queue[i].type); queue[i].response = IP::get_singleton()->resolve_hostname(queue[i].hostname, queue[i].type);
if (!queue[i].response.is_valid()) if (!queue[i].response.is_valid()) {
queue[i].status = IP::RESOLVER_STATUS_ERROR; queue[i].status = IP::RESOLVER_STATUS_ERROR;
else } else {
queue[i].status = IP::RESOLVER_STATUS_DONE; queue[i].status = IP::RESOLVER_STATUS_DONE;
}
} }
} }
@ -138,10 +141,11 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ
} else { } else {
resolver->queue[id].response = IP_Address(); resolver->queue[id].response = IP_Address();
resolver->queue[id].status = IP::RESOLVER_STATUS_WAITING; resolver->queue[id].status = IP::RESOLVER_STATUS_WAITING;
if (resolver->thread) if (resolver->thread) {
resolver->sem.post(); resolver->sem.post();
else } else {
resolver->resolve_queues(); resolver->resolve_queues();
}
} }
return id; return id;

View File

@ -39,19 +39,23 @@ IP_Address::operator Variant() const {
#include <string.h> #include <string.h>
IP_Address::operator String() const { IP_Address::operator String() const {
if (wildcard) if (wildcard) {
return "*"; return "*";
}
if (!valid) if (!valid) {
return ""; return "";
}
if (is_ipv4()) if (is_ipv4()) {
// IPv4 address mapped to IPv6 // IPv4 address mapped to IPv6
return itos(field8[12]) + "." + itos(field8[13]) + "." + itos(field8[14]) + "." + itos(field8[15]); return itos(field8[12]) + "." + itos(field8[13]) + "." + itos(field8[14]) + "." + itos(field8[15]);
}
String ret; String ret;
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
if (i > 0) if (i > 0) {
ret = ret + ":"; ret = ret + ":";
}
uint16_t num = (field8[i * 2] << 8) + field8[i * 2 + 1]; uint16_t num = (field8[i * 2] << 8) + field8[i * 2 + 1];
ret = ret + String::num_int64(num, 16); ret = ret + String::num_int64(num, 16);
}; };
@ -187,8 +191,9 @@ const uint8_t *IP_Address::get_ipv6() const {
void IP_Address::set_ipv6(const uint8_t *p_buf) { void IP_Address::set_ipv6(const uint8_t *p_buf) {
clear(); clear();
valid = true; valid = true;
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++) {
field8[i] = p_buf[i]; field8[i] = p_buf[i];
}
} }
IP_Address::IP_Address(const String &p_string) { IP_Address::IP_Address(const String &p_string) {

View File

@ -51,23 +51,32 @@ protected:
public: public:
//operator Variant() const; //operator Variant() const;
bool operator==(const IP_Address &p_ip) const { bool operator==(const IP_Address &p_ip) const {
if (p_ip.valid != valid) if (p_ip.valid != valid) {
return false; return false;
if (!valid) }
if (!valid) {
return false; return false;
for (int i = 0; i < 4; i++) }
if (field32[i] != p_ip.field32[i]) for (int i = 0; i < 4; i++) {
if (field32[i] != p_ip.field32[i]) {
return false; return false;
}
}
return true; return true;
} }
bool operator!=(const IP_Address &p_ip) const { bool operator!=(const IP_Address &p_ip) const {
if (p_ip.valid != valid) if (p_ip.valid != valid) {
return true; return true;
if (!valid) }
if (!valid) {
return true; return true;
for (int i = 0; i < 4; i++) }
if (field32[i] != p_ip.field32[i]) for (int i = 0; i < 4; i++) {
if (field32[i] != p_ip.field32[i]) {
return true; return true;
}
}
return false; return false;
} }

View File

@ -48,8 +48,9 @@ const char *JSON::tk_name[TK_MAX] = {
static String _make_indent(const String &p_indent, int p_size) { static String _make_indent(const String &p_indent, int p_size) {
String indent_text = ""; String indent_text = "";
if (!p_indent.empty()) { if (!p_indent.empty()) {
for (int i = 0; i < p_size; i++) for (int i = 0; i < p_size; i++) {
indent_text += p_indent; indent_text += p_indent;
}
} }
return indent_text; return indent_text;
} }
@ -98,8 +99,9 @@ String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_
List<Variant> keys; List<Variant> keys;
d.get_key_list(&keys); d.get_key_list(&keys);
if (p_sort_keys) if (p_sort_keys) {
keys.sort(); keys.sort();
}
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
if (E != keys.front()) { if (E != keys.front()) {
@ -241,8 +243,9 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
str += res; str += res;
} else { } else {
if (p_str[index] == '\n') if (p_str[index] == '\n') {
line++; line++;
}
str += p_str[index]; str += p_str[index];
} }
index++; index++;
@ -294,27 +297,29 @@ Error JSON::_parse_value(Variant &value, Token &token, const CharType *p_str, in
if (token.type == TK_CURLY_BRACKET_OPEN) { if (token.type == TK_CURLY_BRACKET_OPEN) {
Dictionary d; Dictionary d;
Error err = _parse_object(d, p_str, index, p_len, line, r_err_str); Error err = _parse_object(d, p_str, index, p_len, line, r_err_str);
if (err) if (err) {
return err; return err;
}
value = d; value = d;
return OK; return OK;
} else if (token.type == TK_BRACKET_OPEN) { } else if (token.type == TK_BRACKET_OPEN) {
Array a; Array a;
Error err = _parse_array(a, p_str, index, p_len, line, r_err_str); Error err = _parse_array(a, p_str, index, p_len, line, r_err_str);
if (err) if (err) {
return err; return err;
}
value = a; value = a;
return OK; return OK;
} else if (token.type == TK_IDENTIFIER) { } else if (token.type == TK_IDENTIFIER) {
String id = token.value; String id = token.value;
if (id == "true") if (id == "true") {
value = true; value = true;
else if (id == "false") } else if (id == "false") {
value = false; value = false;
else if (id == "null") } else if (id == "null") {
value = Variant(); value = Variant();
else { } else {
r_err_str = "Expected 'true','false' or 'null', got '" + id + "'."; r_err_str = "Expected 'true','false' or 'null', got '" + id + "'.";
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
} }
@ -338,8 +343,9 @@ Error JSON::_parse_array(Array &array, const CharType *p_str, int &index, int p_
while (index < p_len) { while (index < p_len) {
Error err = _get_token(p_str, index, p_len, token, line, r_err_str); Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
if (err != OK) if (err != OK) {
return err; return err;
}
if (token.type == TK_BRACKET_CLOSE) { if (token.type == TK_BRACKET_CLOSE) {
return OK; return OK;
@ -357,8 +363,9 @@ Error JSON::_parse_array(Array &array, const CharType *p_str, int &index, int p_
Variant v; Variant v;
err = _parse_value(v, token, p_str, index, p_len, line, r_err_str); err = _parse_value(v, token, p_str, index, p_len, line, r_err_str);
if (err) if (err) {
return err; return err;
}
array.push_back(v); array.push_back(v);
need_comma = true; need_comma = true;
@ -376,8 +383,9 @@ Error JSON::_parse_object(Dictionary &object, const CharType *p_str, int &index,
while (index < p_len) { while (index < p_len) {
if (at_key) { if (at_key) {
Error err = _get_token(p_str, index, p_len, token, line, r_err_str); Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
if (err != OK) if (err != OK) {
return err; return err;
}
if (token.type == TK_CURLY_BRACKET_CLOSE) { if (token.type == TK_CURLY_BRACKET_CLOSE) {
return OK; return OK;
@ -400,8 +408,9 @@ Error JSON::_parse_object(Dictionary &object, const CharType *p_str, int &index,
key = token.value; key = token.value;
err = _get_token(p_str, index, p_len, token, line, r_err_str); err = _get_token(p_str, index, p_len, token, line, r_err_str);
if (err != OK) if (err != OK) {
return err; return err;
}
if (token.type != TK_COLON) { if (token.type != TK_COLON) {
r_err_str = "Expected ':'"; r_err_str = "Expected ':'";
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
@ -409,13 +418,15 @@ Error JSON::_parse_object(Dictionary &object, const CharType *p_str, int &index,
at_key = false; at_key = false;
} else { } else {
Error err = _get_token(p_str, index, p_len, token, line, r_err_str); Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
if (err != OK) if (err != OK) {
return err; return err;
}
Variant v; Variant v;
err = _parse_value(v, token, p_str, index, p_len, line, r_err_str); err = _parse_value(v, token, p_str, index, p_len, line, r_err_str);
if (err) if (err) {
return err; return err;
}
object[key] = v; object[key] = v;
need_comma = true; need_comma = true;
at_key = true; at_key = true;
@ -434,8 +445,9 @@ Error JSON::parse(const String &p_json, Variant &r_ret, String &r_err_str, int &
String aux_key; String aux_key;
Error err = _get_token(str, idx, len, token, r_err_line, r_err_str); Error err = _get_token(str, idx, len, token, r_err_line, r_err_str);
if (err) if (err) {
return err; return err;
}
err = _parse_value(r_ret, token, str, idx, len, r_err_line, r_err_str); err = _parse_value(r_ret, token, str, idx, len, r_err_line, r_err_str);

View File

@ -67,10 +67,11 @@ void Logger::log_error(const char *p_function, const char *p_file, int p_line, c
} }
const char *err_details; const char *err_details;
if (p_rationale && *p_rationale) if (p_rationale && *p_rationale) {
err_details = p_rationale; err_details = p_rationale;
else } else {
err_details = p_code; err_details = p_code;
}
logf_error("%s: %s\n", err_type, err_details); logf_error("%s: %s\n", err_type, err_details);
logf_error(" at: %s (%s:%i) - %s\n", p_function, p_file, p_line, p_code); logf_error(" at: %s (%s:%i) - %s\n", p_function, p_file, p_line, p_code);

View File

@ -107,8 +107,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
buf += 4; buf += 4;
len -= 4; len -= 4;
if (r_len) if (r_len) {
*r_len = 4; *r_len = 4;
}
switch (type & ENCODE_MASK) { switch (type & ENCODE_MASK) {
case Variant::NIL: { case Variant::NIL: {
@ -118,23 +119,26 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
bool val = decode_uint32(buf); bool val = decode_uint32(buf);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4; (*r_len) += 4;
}
} break; } break;
case Variant::INT: { case Variant::INT: {
if (type & ENCODE_FLAG_64) { if (type & ENCODE_FLAG_64) {
ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA); ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
int64_t val = decode_uint64(buf); int64_t val = decode_uint64(buf);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 8; (*r_len) += 8;
}
} else { } else {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t val = decode_uint32(buf); int32_t val = decode_uint32(buf);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4; (*r_len) += 4;
}
} }
} break; } break;
@ -143,22 +147,25 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA); ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
double val = decode_double(buf); double val = decode_double(buf);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 8; (*r_len) += 8;
}
} else { } else {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
float val = decode_float(buf); float val = decode_float(buf);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4; (*r_len) += 4;
}
} }
} break; } break;
case Variant::STRING: { case Variant::STRING: {
String str; String str;
Error err = _decode_string(buf, len, r_len, str); Error err = _decode_string(buf, len, r_len, str);
if (err) if (err) {
return err; return err;
}
r_variant = str; r_variant = str;
} break; } break;
@ -171,8 +178,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.y = decode_float(&buf[4]); val.y = decode_float(&buf[4]);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4 * 2; (*r_len) += 4 * 2;
}
} break; } break;
case Variant::VECTOR2I: { case Variant::VECTOR2I: {
@ -182,8 +190,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.y = decode_uint32(&buf[4]); val.y = decode_uint32(&buf[4]);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4 * 2; (*r_len) += 4 * 2;
}
} break; } break;
case Variant::RECT2: { case Variant::RECT2: {
@ -195,8 +204,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.size.y = decode_float(&buf[12]); val.size.y = decode_float(&buf[12]);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4 * 4; (*r_len) += 4 * 4;
}
} break; } break;
case Variant::RECT2I: { case Variant::RECT2I: {
@ -208,8 +218,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.size.y = decode_uint32(&buf[12]); val.size.y = decode_uint32(&buf[12]);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4 * 4; (*r_len) += 4 * 4;
}
} break; } break;
case Variant::VECTOR3: { case Variant::VECTOR3: {
@ -220,8 +231,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.z = decode_float(&buf[8]); val.z = decode_float(&buf[8]);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4 * 3; (*r_len) += 4 * 3;
}
} break; } break;
case Variant::VECTOR3I: { case Variant::VECTOR3I: {
@ -232,8 +244,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.z = decode_uint32(&buf[8]); val.z = decode_uint32(&buf[8]);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4 * 3; (*r_len) += 4 * 3;
}
} break; } break;
case Variant::TRANSFORM2D: { case Variant::TRANSFORM2D: {
@ -247,8 +260,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4 * 6; (*r_len) += 4 * 6;
}
} break; } break;
case Variant::PLANE: { case Variant::PLANE: {
@ -260,8 +274,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.d = decode_float(&buf[12]); val.d = decode_float(&buf[12]);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4 * 4; (*r_len) += 4 * 4;
}
} break; } break;
case Variant::QUAT: { case Variant::QUAT: {
@ -273,8 +288,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.w = decode_float(&buf[12]); val.w = decode_float(&buf[12]);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4 * 4; (*r_len) += 4 * 4;
}
} break; } break;
case Variant::AABB: { case Variant::AABB: {
@ -288,8 +304,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.size.z = decode_float(&buf[20]); val.size.z = decode_float(&buf[20]);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4 * 6; (*r_len) += 4 * 6;
}
} break; } break;
case Variant::BASIS: { case Variant::BASIS: {
@ -303,8 +320,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4 * 9; (*r_len) += 4 * 9;
}
} break; } break;
case Variant::TRANSFORM: { case Variant::TRANSFORM: {
@ -321,8 +339,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4 * 12; (*r_len) += 4 * 12;
}
} break; } break;
@ -336,15 +355,17 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.a = decode_float(&buf[12]); val.a = decode_float(&buf[12]);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4 * 4; (*r_len) += 4 * 4;
}
} break; } break;
case Variant::STRING_NAME: { case Variant::STRING_NAME: {
String str; String str;
Error err = _decode_string(buf, len, r_len, str); Error err = _decode_string(buf, len, r_len, str);
if (err) if (err) {
return err; return err;
}
r_variant = StringName(str); r_variant = StringName(str);
} break; } break;
@ -366,24 +387,28 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
len -= 12; len -= 12;
buf += 12; buf += 12;
if (flags & 2) // Obsolete format with property separate from subpath if (flags & 2) { // Obsolete format with property separate from subpath
subnamecount++; subnamecount++;
}
uint32_t total = namecount + subnamecount; uint32_t total = namecount + subnamecount;
if (r_len) if (r_len) {
(*r_len) += 12; (*r_len) += 12;
}
for (uint32_t i = 0; i < total; i++) { for (uint32_t i = 0; i < total; i++) {
String str; String str;
Error err = _decode_string(buf, len, r_len, str); Error err = _decode_string(buf, len, r_len, str);
if (err) if (err) {
return err; return err;
}
if (i < namecount) if (i < namecount) {
names.push_back(str); names.push_back(str);
else } else {
subnames.push_back(str); subnames.push_back(str);
}
} }
r_variant = NodePath(names, subnames, flags & 1); r_variant = NodePath(names, subnames, flags & 1);
@ -403,8 +428,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
//this _is_ allowed //this _is_ allowed
ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA); ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
ObjectID val = ObjectID(decode_uint64(buf)); ObjectID val = ObjectID(decode_uint64(buf));
if (r_len) if (r_len) {
(*r_len) += 8; (*r_len) += 8;
}
if (val.is_null()) { if (val.is_null()) {
r_variant = (Object *)nullptr; r_variant = (Object *)nullptr;
@ -421,8 +447,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
String str; String str;
Error err = _decode_string(buf, len, r_len, str); Error err = _decode_string(buf, len, r_len, str);
if (err) if (err) {
return err; return err;
}
if (str == String()) { if (str == String()) {
r_variant = (Object *)nullptr; r_variant = (Object *)nullptr;
@ -442,14 +469,16 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
str = String(); str = String();
err = _decode_string(buf, len, r_len, str); err = _decode_string(buf, len, r_len, str);
if (err) if (err) {
return err; return err;
}
Variant value; Variant value;
int used; int used;
err = decode_variant(value, buf, len, &used, p_allow_objects); err = decode_variant(value, buf, len, &used, p_allow_objects);
if (err) if (err) {
return err; return err;
}
buf += used; buf += used;
len -= used; len -= used;
@ -573,8 +602,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
r_variant = data; r_variant = data;
if (r_len) { if (r_len) {
if (count % 4) if (count % 4) {
(*r_len) += 4 - count % 4; (*r_len) += 4 - count % 4;
}
(*r_len) += 4 + count; (*r_len) += 4 + count;
} }
@ -685,15 +715,17 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
buf += 4; buf += 4;
len -= 4; len -= 4;
if (r_len) if (r_len) {
(*r_len) += 4; (*r_len) += 4;
}
//printf("string count: %i\n",count); //printf("string count: %i\n",count);
for (int32_t i = 0; i < count; i++) { for (int32_t i = 0; i < count; i++) {
String str; String str;
Error err = _decode_string(buf, len, r_len, str); Error err = _decode_string(buf, len, r_len, str);
if (err) if (err) {
return err; return err;
}
strings.push_back(str); strings.push_back(str);
} }
@ -726,8 +758,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
int adv = 4 * 2 * count; int adv = 4 * 2 * count;
if (r_len) if (r_len) {
(*r_len) += adv; (*r_len) += adv;
}
} }
r_variant = varray; r_variant = varray;
@ -760,8 +793,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
int adv = 4 * 3 * count; int adv = 4 * 3 * count;
if (r_len) if (r_len) {
(*r_len) += adv; (*r_len) += adv;
}
} }
r_variant = varray; r_variant = varray;
@ -795,8 +829,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
int adv = 4 * 4 * count; int adv = 4 * 4 * count;
if (r_len) if (r_len) {
(*r_len) += adv; (*r_len) += adv;
}
} }
r_variant = carray; r_variant = carray;
@ -927,8 +962,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
encode_uint32(uint32_t(np.get_name_count()) | 0x80000000, buf); //for compatibility with the old format encode_uint32(uint32_t(np.get_name_count()) | 0x80000000, buf); //for compatibility with the old format
encode_uint32(np.get_subname_count(), buf + 4); encode_uint32(np.get_subname_count(), buf + 4);
uint32_t np_flags = 0; uint32_t np_flags = 0;
if (np.is_absolute()) if (np.is_absolute()) {
np_flags |= 1; np_flags |= 1;
}
encode_uint32(np_flags, buf + 8); encode_uint32(np_flags, buf + 8);
@ -942,17 +978,19 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
for (int i = 0; i < total; i++) { for (int i = 0; i < total; i++) {
String str; String str;
if (i < np.get_name_count()) if (i < np.get_name_count()) {
str = np.get_name(i); str = np.get_name(i);
else } else {
str = np.get_subname(i - np.get_name_count()); str = np.get_subname(i - np.get_name_count());
}
CharString utf8 = str.utf8(); CharString utf8 = str.utf8();
int pad = 0; int pad = 0;
if (utf8.length() % 4) if (utf8.length() % 4) {
pad = 4 - utf8.length() % 4; pad = 4 - utf8.length() % 4;
}
if (buf) { if (buf) {
encode_uint32(utf8.length(), buf); encode_uint32(utf8.length(), buf);
@ -1157,8 +1195,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
int pc = 0; int pc = 0;
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue; continue;
}
pc++; pc++;
} }
@ -1170,19 +1209,22 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4; r_len += 4;
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue; continue;
}
_encode_string(E->get().name, buf, r_len); _encode_string(E->get().name, buf, r_len);
int len; int len;
Error err = encode_variant(obj->get(E->get().name), buf, len, p_full_objects); Error err = encode_variant(obj->get(E->get().name), buf, len, p_full_objects);
if (err) if (err) {
return err; return err;
}
ERR_FAIL_COND_V(len % 4, ERR_BUG); ERR_FAIL_COND_V(len % 4, ERR_BUG);
r_len += len; r_len += len;
if (buf) if (buf) {
buf += len; buf += len;
}
} }
} }
} else { } else {
@ -1230,15 +1272,17 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
encode_variant(E->get(), buf, len, p_full_objects); encode_variant(E->get(), buf, len, p_full_objects);
ERR_FAIL_COND_V(len % 4, ERR_BUG); ERR_FAIL_COND_V(len % 4, ERR_BUG);
r_len += len; r_len += len;
if (buf) if (buf) {
buf += len; buf += len;
}
Variant *v = d.getptr(E->get()); Variant *v = d.getptr(E->get());
ERR_FAIL_COND_V(!v, ERR_BUG); ERR_FAIL_COND_V(!v, ERR_BUG);
encode_variant(*v, buf, len, p_full_objects); encode_variant(*v, buf, len, p_full_objects);
ERR_FAIL_COND_V(len % 4, ERR_BUG); ERR_FAIL_COND_V(len % 4, ERR_BUG);
r_len += len; r_len += len;
if (buf) if (buf) {
buf += len; buf += len;
}
} }
} break; } break;
@ -1257,8 +1301,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
encode_variant(v.get(i), buf, len, p_full_objects); encode_variant(v.get(i), buf, len, p_full_objects);
ERR_FAIL_COND_V(len % 4, ERR_BUG); ERR_FAIL_COND_V(len % 4, ERR_BUG);
r_len += len; r_len += len;
if (buf) if (buf) {
buf += len; buf += len;
}
} }
} break; } break;
@ -1279,8 +1324,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4 + datalen * datasize; r_len += 4 + datalen * datasize;
while (r_len % 4) { while (r_len % 4) {
r_len++; r_len++;
if (buf) if (buf) {
*(buf++) = 0; *(buf++) = 0;
}
} }
} break; } break;
@ -1293,8 +1339,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
encode_uint32(datalen, buf); encode_uint32(datalen, buf);
buf += 4; buf += 4;
const int32_t *r = data.ptr(); const int32_t *r = data.ptr();
for (int32_t i = 0; i < datalen; i++) for (int32_t i = 0; i < datalen; i++) {
encode_uint32(r[i], &buf[i * datasize]); encode_uint32(r[i], &buf[i * datasize]);
}
} }
r_len += 4 + datalen * datasize; r_len += 4 + datalen * datasize;
@ -1309,8 +1356,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
encode_uint64(datalen, buf); encode_uint64(datalen, buf);
buf += 4; buf += 4;
const int64_t *r = data.ptr(); const int64_t *r = data.ptr();
for (int64_t i = 0; i < datalen; i++) for (int64_t i = 0; i < datalen; i++) {
encode_uint64(r[i], &buf[i * datasize]); encode_uint64(r[i], &buf[i * datasize]);
}
} }
r_len += 4 + datalen * datasize; r_len += 4 + datalen * datasize;
@ -1325,8 +1373,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
encode_uint32(datalen, buf); encode_uint32(datalen, buf);
buf += 4; buf += 4;
const float *r = data.ptr(); const float *r = data.ptr();
for (int i = 0; i < datalen; i++) for (int i = 0; i < datalen; i++) {
encode_float(r[i], &buf[i * datasize]); encode_float(r[i], &buf[i * datasize]);
}
} }
r_len += 4 + datalen * datasize; r_len += 4 + datalen * datasize;
@ -1341,8 +1390,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
encode_uint32(datalen, buf); encode_uint32(datalen, buf);
buf += 4; buf += 4;
const double *r = data.ptr(); const double *r = data.ptr();
for (int i = 0; i < datalen; i++) for (int i = 0; i < datalen; i++) {
encode_double(r[i], &buf[i * datasize]); encode_double(r[i], &buf[i * datasize]);
}
} }
r_len += 4 + datalen * datasize; r_len += 4 + datalen * datasize;
@ -1372,8 +1422,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4 + utf8.length() + 1; r_len += 4 + utf8.length() + 1;
while (r_len % 4) { while (r_len % 4) {
r_len++; //pad r_len++; //pad
if (buf) if (buf) {
*(buf++) = 0; *(buf++) = 0;
}
} }
} }

View File

@ -108,8 +108,9 @@ static inline int encode_cstring(const char *p_string, uint8_t *p_data) {
len++; len++;
}; };
if (p_data) if (p_data) {
*p_data = 0; *p_data = 0;
}
return len + 1; return len + 1;
} }

View File

@ -53,8 +53,9 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas
// Do nothing also. Remote cannot produce a local call. // Do nothing also. Remote cannot produce a local call.
} break; } break;
case MultiplayerAPI::RPC_MODE_MASTERSYNC: { case MultiplayerAPI::RPC_MODE_MASTERSYNC: {
if (is_master) if (is_master) {
r_skip_rpc = true; // I am the master, so skip remote call. r_skip_rpc = true; // I am the master, so skip remote call.
}
[[fallthrough]]; [[fallthrough]];
} }
case MultiplayerAPI::RPC_MODE_REMOTESYNC: case MultiplayerAPI::RPC_MODE_REMOTESYNC:
@ -63,8 +64,9 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas
return true; return true;
} break; } break;
case MultiplayerAPI::RPC_MODE_MASTER: { case MultiplayerAPI::RPC_MODE_MASTER: {
if (is_master) if (is_master) {
r_skip_rpc = true; // I am the master, so skip remote call. r_skip_rpc = true; // I am the master, so skip remote call.
}
return is_master; return is_master;
} break; } break;
case MultiplayerAPI::RPC_MODE_PUPPET: { case MultiplayerAPI::RPC_MODE_PUPPET: {
@ -97,13 +99,15 @@ _FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, i
} }
void MultiplayerAPI::poll() { void MultiplayerAPI::poll() {
if (!network_peer.is_valid() || network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED) if (!network_peer.is_valid() || network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED) {
return; return;
}
network_peer->poll(); network_peer->poll();
if (!network_peer.is_valid()) // It's possible that polling might have resulted in a disconnection, so check here. if (!network_peer.is_valid()) { // It's possible that polling might have resulted in a disconnection, so check here.
return; return;
}
while (network_peer->get_available_packet_count()) { while (network_peer->get_available_packet_count()) {
int sender = network_peer->get_packet_peer(); int sender = network_peer->get_packet_peer();
@ -139,8 +143,9 @@ void MultiplayerAPI::set_root_node(Node *p_node) {
} }
void MultiplayerAPI::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_peer) { void MultiplayerAPI::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_peer) {
if (p_peer == network_peer) if (p_peer == network_peer) {
return; // Nothing to do return; // Nothing to do
}
ERR_FAIL_COND_MSG(p_peer.is_valid() && p_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED, ERR_FAIL_COND_MSG(p_peer.is_valid() && p_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED,
"Supplied NetworkedMultiplayerPeer must be connecting or connected."); "Supplied NetworkedMultiplayerPeer must be connecting or connected.");
@ -325,8 +330,9 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, uin
node = root_node->get_node(np); node = root_node->get_node(np);
if (!node) if (!node) {
ERR_PRINT("Failed to get path from RPC: " + String(np) + "."); ERR_PRINT("Failed to get path from RPC: " + String(np) + ".");
}
} else { } else {
// Use cached path. // Use cached path.
int id = p_node_target; int id = p_node_target;
@ -341,8 +347,9 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, uin
// Do proper caching later. // Do proper caching later.
node = root_node->get_node(ni->path); node = root_node->get_node(ni->path);
if (!node) if (!node) {
ERR_PRINT("Failed to get cached path from RPC: " + String(ni->path) + "."); ERR_PRINT("Failed to get cached path from RPC: " + String(ni->path) + ".");
}
} }
return node; return node;
} }
@ -529,11 +536,13 @@ bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentC
List<int> peers_to_add; // If one is missing, take note to add it. List<int> peers_to_add; // If one is missing, take note to add it.
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) { for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
if (p_target < 0 && E->get() == -p_target) if (p_target < 0 && E->get() == -p_target) {
continue; // Continue, excluded. continue; // Continue, excluded.
}
if (p_target > 0 && E->get() != p_target) if (p_target > 0 && E->get() != p_target) {
continue; // Continue, not for this peer. continue; // Continue, not for this peer.
}
Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get()); Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get());
@ -658,8 +667,9 @@ Error MultiplayerAPI::_encode_and_compress_variant(const Variant &p_variant, uin
default: default:
// Any other case is not yet compressed. // Any other case is not yet compressed.
Error err = encode_variant(p_variant, r_buffer, r_len, allow_object_decoding); Error err = encode_variant(p_variant, r_buffer, r_len, allow_object_decoding);
if (err != OK) if (err != OK) {
return err; return err;
}
if (r_buffer) { if (r_buffer) {
// The first byte is not used by the marshaling, so store the type // The first byte is not used by the marshaling, so store the type
// so we know how to decompress and decode this variant. // so we know how to decompress and decode this variant.
@ -684,48 +694,55 @@ Error MultiplayerAPI::_decode_and_decompress_variant(Variant &r_variant, const u
case Variant::BOOL: { case Variant::BOOL: {
bool val = (buf[0] & VARIANT_META_BOOL_MASK) > 0; bool val = (buf[0] & VARIANT_META_BOOL_MASK) > 0;
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
*r_len = 1; *r_len = 1;
}
} break; } break;
case Variant::INT: { case Variant::INT: {
buf += 1; buf += 1;
len -= 1; len -= 1;
if (r_len) if (r_len) {
*r_len = 1; *r_len = 1;
}
if (encode_mode == ENCODE_8) { if (encode_mode == ENCODE_8) {
// 8 bits. // 8 bits.
ERR_FAIL_COND_V(len < 1, ERR_INVALID_DATA); ERR_FAIL_COND_V(len < 1, ERR_INVALID_DATA);
int8_t val = buf[0]; int8_t val = buf[0];
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 1; (*r_len) += 1;
}
} else if (encode_mode == ENCODE_16) { } else if (encode_mode == ENCODE_16) {
// 16 bits. // 16 bits.
ERR_FAIL_COND_V(len < 2, ERR_INVALID_DATA); ERR_FAIL_COND_V(len < 2, ERR_INVALID_DATA);
int16_t val = decode_uint16(buf); int16_t val = decode_uint16(buf);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 2; (*r_len) += 2;
}
} else if (encode_mode == ENCODE_32) { } else if (encode_mode == ENCODE_32) {
// 32 bits. // 32 bits.
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t val = decode_uint32(buf); int32_t val = decode_uint32(buf);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 4; (*r_len) += 4;
}
} else { } else {
// 64 bits. // 64 bits.
ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA); ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
int64_t val = decode_uint64(buf); int64_t val = decode_uint64(buf);
r_variant = val; r_variant = val;
if (r_len) if (r_len) {
(*r_len) += 8; (*r_len) += 8;
}
} }
} break; } break;
default: default:
Error err = decode_variant(r_variant, p_buffer, p_len, r_len, allow_object_decoding); Error err = decode_variant(r_variant, p_buffer, p_len, r_len, allow_object_decoding);
if (err != OK) if (err != OK) {
return err; return err;
}
} }
return OK; return OK;
@ -925,11 +942,13 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
encode_cstring(pname.get_data(), &(packet_cache.write[ofs])); encode_cstring(pname.get_data(), &(packet_cache.write[ofs]));
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) { for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
if (p_to < 0 && E->get() == -p_to) if (p_to < 0 && E->get() == -p_to) {
continue; // Continue, excluded. continue; // Continue, excluded.
}
if (p_to > 0 && E->get() != p_to) if (p_to > 0 && E->get() != p_to) {
continue; // Continue, not for this peer. continue; // Continue, not for this peer.
}
Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get()); Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get());
ERR_CONTINUE(!F); // Should never happen. ERR_CONTINUE(!F); // Should never happen.

View File

@ -33,8 +33,9 @@
NetSocket *(*NetSocket::_create)() = nullptr; NetSocket *(*NetSocket::_create)() = nullptr;
NetSocket *NetSocket::create() { NetSocket *NetSocket::create() {
if (_create) if (_create) {
return _create(); return _create();
}
ERR_PRINT("Unable to create network socket, platform not supported"); ERR_PRINT("Unable to create network socket, platform not supported");
return nullptr; return nullptr;

View File

@ -50,24 +50,28 @@ Error PacketPeer::get_packet_buffer(Vector<uint8_t> &r_buffer) {
const uint8_t *buffer; const uint8_t *buffer;
int buffer_size; int buffer_size;
Error err = get_packet(&buffer, buffer_size); Error err = get_packet(&buffer, buffer_size);
if (err) if (err) {
return err; return err;
}
r_buffer.resize(buffer_size); r_buffer.resize(buffer_size);
if (buffer_size == 0) if (buffer_size == 0) {
return OK; return OK;
}
uint8_t *w = r_buffer.ptrw(); uint8_t *w = r_buffer.ptrw();
for (int i = 0; i < buffer_size; i++) for (int i = 0; i < buffer_size; i++) {
w[i] = buffer[i]; w[i] = buffer[i];
}
return OK; return OK;
} }
Error PacketPeer::put_packet_buffer(const Vector<uint8_t> &p_buffer) { Error PacketPeer::put_packet_buffer(const Vector<uint8_t> &p_buffer) {
int len = p_buffer.size(); int len = p_buffer.size();
if (len == 0) if (len == 0) {
return OK; return OK;
}
const uint8_t *r = p_buffer.ptr(); const uint8_t *r = p_buffer.ptr();
return put_packet(&r[0], len); return put_packet(&r[0], len);
@ -77,8 +81,9 @@ Error PacketPeer::get_var(Variant &r_variant, bool p_allow_objects) {
const uint8_t *buffer; const uint8_t *buffer;
int buffer_size; int buffer_size;
Error err = get_packet(&buffer, buffer_size); Error err = get_packet(&buffer, buffer_size);
if (err) if (err) {
return err; return err;
}
return decode_variant(r_variant, buffer, buffer_size, nullptr, p_allow_objects); return decode_variant(r_variant, buffer, buffer_size, nullptr, p_allow_objects);
} }
@ -86,11 +91,13 @@ Error PacketPeer::get_var(Variant &r_variant, bool p_allow_objects) {
Error PacketPeer::put_var(const Variant &p_packet, bool p_full_objects) { Error PacketPeer::put_var(const Variant &p_packet, bool p_full_objects) {
int len; int len;
Error err = encode_variant(p_packet, nullptr, len, p_full_objects); // compute len first Error err = encode_variant(p_packet, nullptr, len, p_full_objects); // compute len first
if (err) if (err) {
return err; return err;
}
if (len == 0) if (len == 0) {
return OK; return OK;
}
ERR_FAIL_COND_V_MSG(len > encode_buffer_max_size, ERR_OUT_OF_MEMORY, "Failed to encode variant, encode size is bigger then encode_buffer_max_size. Consider raising it via 'set_encode_buffer_max_size'."); ERR_FAIL_COND_V_MSG(len > encode_buffer_max_size, ERR_OUT_OF_MEMORY, "Failed to encode variant, encode size is bigger then encode_buffer_max_size. Consider raising it via 'set_encode_buffer_max_size'.");
@ -168,10 +175,12 @@ Error PacketPeerStream::_poll_buffer() const {
int read = 0; int read = 0;
ERR_FAIL_COND_V(input_buffer.size() < ring_buffer.space_left(), ERR_UNAVAILABLE); ERR_FAIL_COND_V(input_buffer.size() < ring_buffer.space_left(), ERR_UNAVAILABLE);
Error err = peer->get_partial_data(input_buffer.ptrw(), ring_buffer.space_left(), read); Error err = peer->get_partial_data(input_buffer.ptrw(), ring_buffer.space_left(), read);
if (err) if (err) {
return err; return err;
if (read == 0) }
if (read == 0) {
return OK; return OK;
}
int w = ring_buffer.write(&input_buffer[0], read); int w = ring_buffer.write(&input_buffer[0], read);
ERR_FAIL_COND_V(w != read, ERR_BUG); ERR_FAIL_COND_V(w != read, ERR_BUG);
@ -193,8 +202,9 @@ int PacketPeerStream::get_available_packet_count() const {
uint32_t len = decode_uint32(lbuf); uint32_t len = decode_uint32(lbuf);
remaining -= 4; remaining -= 4;
ofs += 4; ofs += 4;
if (len > remaining) if (len > remaining) {
break; break;
}
remaining -= len; remaining -= len;
ofs += len; ofs += len;
count++; count++;
@ -228,19 +238,22 @@ Error PacketPeerStream::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED); ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED);
Error err = _poll_buffer(); //won't hurt to poll here too Error err = _poll_buffer(); //won't hurt to poll here too
if (err) if (err) {
return err; return err;
}
if (p_buffer_size == 0) if (p_buffer_size == 0) {
return OK; return OK;
}
ERR_FAIL_COND_V(p_buffer_size < 0, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(p_buffer_size < 0, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_buffer_size + 4 > output_buffer.size(), ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(p_buffer_size + 4 > output_buffer.size(), ERR_INVALID_PARAMETER);
encode_uint32(p_buffer_size, output_buffer.ptrw()); encode_uint32(p_buffer_size, output_buffer.ptrw());
uint8_t *dst = &output_buffer.write[4]; uint8_t *dst = &output_buffer.write[4];
for (int i = 0; i < p_buffer_size; i++) for (int i = 0; i < p_buffer_size; i++) {
dst[i] = p_buffer[i]; dst[i] = p_buffer[i];
}
return peer->put_data(&output_buffer[0], p_buffer_size + 4); return peer->put_data(&output_buffer[0], p_buffer_size + 4);
} }

View File

@ -38,8 +38,9 @@ void PacketPeerUDP::set_blocking_mode(bool p_enable) {
void PacketPeerUDP::set_broadcast_enabled(bool p_enabled) { void PacketPeerUDP::set_broadcast_enabled(bool p_enabled) {
broadcast = p_enabled; broadcast = p_enabled;
if (_sock.is_valid() && _sock->is_open()) if (_sock.is_valid() && _sock->is_open()) {
_sock->set_broadcasting_enabled(p_enabled); _sock->set_broadcasting_enabled(p_enabled);
}
} }
Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_if_name) { Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_if_name) {
@ -72,8 +73,9 @@ Error PacketPeerUDP::_set_dest_address(const String &p_address, int p_port) {
ip = p_address; ip = p_address;
} else { } else {
ip = IP::get_singleton()->resolve_hostname(p_address); ip = IP::get_singleton()->resolve_hostname(p_address);
if (!ip.is_valid()) if (!ip.is_valid()) {
return ERR_CANT_RESOLVE; return ERR_CANT_RESOLVE;
}
} }
set_dest_address(ip, p_port); set_dest_address(ip, p_port);
@ -83,18 +85,21 @@ Error PacketPeerUDP::_set_dest_address(const String &p_address, int p_port) {
int PacketPeerUDP::get_available_packet_count() const { int PacketPeerUDP::get_available_packet_count() const {
// TODO we should deprecate this, and expose poll instead! // TODO we should deprecate this, and expose poll instead!
Error err = const_cast<PacketPeerUDP *>(this)->_poll(); Error err = const_cast<PacketPeerUDP *>(this)->_poll();
if (err != OK) if (err != OK) {
return -1; return -1;
}
return queue_count; return queue_count;
} }
Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
Error err = _poll(); Error err = _poll();
if (err != OK) if (err != OK) {
return err; return err;
if (queue_count == 0) }
if (queue_count == 0) {
return ERR_UNAVAILABLE; return ERR_UNAVAILABLE;
}
uint32_t size = 0; uint32_t size = 0;
uint8_t ipv6[16]; uint8_t ipv6[16];
@ -131,10 +136,11 @@ Error PacketPeerUDP::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
err = _sock->sendto(p_buffer, p_buffer_size, sent, peer_addr, peer_port); err = _sock->sendto(p_buffer, p_buffer_size, sent, peer_addr, peer_port);
} }
if (err != OK) { if (err != OK) {
if (err != ERR_BUSY) if (err != ERR_BUSY) {
return FAILED; return FAILED;
else if (!blocking) } else if (!blocking) {
return ERR_BUSY; return ERR_BUSY;
}
// Keep trying to send full packet // Keep trying to send full packet
continue; continue;
} }
@ -157,13 +163,15 @@ Error PacketPeerUDP::listen(int p_port, const IP_Address &p_bind_address, int p_
Error err; Error err;
IP::Type ip_type = IP::TYPE_ANY; IP::Type ip_type = IP::TYPE_ANY;
if (p_bind_address.is_valid()) if (p_bind_address.is_valid()) {
ip_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6; ip_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
}
err = _sock->open(NetSocket::TYPE_UDP, ip_type); err = _sock->open(NetSocket::TYPE_UDP, ip_type);
if (err != OK) if (err != OK) {
return ERR_CANT_CREATE; return ERR_CANT_CREATE;
}
_sock->set_blocking_enabled(false); _sock->set_blocking_enabled(false);
_sock->set_reuse_address_enabled(true); _sock->set_reuse_address_enabled(true);
@ -235,8 +243,9 @@ bool PacketPeerUDP::is_connected_to_host() const {
} }
void PacketPeerUDP::close() { void PacketPeerUDP::close() {
if (_sock.is_valid()) if (_sock.is_valid()) {
_sock->close(); _sock->close();
}
rb.resize(16); rb.resize(16);
queue_count = 0; queue_count = 0;
connected = false; connected = false;
@ -269,8 +278,9 @@ Error PacketPeerUDP::_poll() {
} }
if (err != OK) { if (err != OK) {
if (err == ERR_BUSY) if (err == ERR_BUSY) {
break; break;
}
return FAILED; return FAILED;
} }

View File

@ -35,14 +35,16 @@
#include "core/version.h" #include "core/version.h"
static uint64_t _align(uint64_t p_n, int p_alignment) { static uint64_t _align(uint64_t p_n, int p_alignment) {
if (p_alignment == 0) if (p_alignment == 0) {
return p_n; return p_n;
}
uint64_t rest = p_n % p_alignment; uint64_t rest = p_n % p_alignment;
if (rest == 0) if (rest == 0) {
return p_n; return p_n;
else } else {
return p_n + (p_alignment - rest); return p_n + (p_alignment - rest);
}
}; };
static void _pad(FileAccess *p_file, int p_bytes) { static void _pad(FileAccess *p_file, int p_bytes) {
@ -160,8 +162,9 @@ Error PCKPacker::flush(bool p_verbose) {
}; };
}; };
if (p_verbose) if (p_verbose) {
printf("\n"); printf("\n");
}
file->close(); file->close();
memdelete_arr(buf); memdelete_arr(buf);

View File

@ -96,8 +96,9 @@ enum {
void ResourceLoaderBinary::_advance_padding(uint32_t p_len) { void ResourceLoaderBinary::_advance_padding(uint32_t p_len) {
uint32_t extra = 4 - (p_len % 4); uint32_t extra = 4 - (p_len % 4);
if (extra < 4) { if (extra < 4) {
for (uint32_t i = 0; i < extra; i++) for (uint32_t i = 0; i < extra; i++) {
f->get_8(); //pad to 32 f->get_8(); //pad to 32
}
} }
} }
@ -108,8 +109,9 @@ StringName ResourceLoaderBinary::_get_string() {
if ((int)len > str_buf.size()) { if ((int)len > str_buf.size()) {
str_buf.resize(len); str_buf.resize(len);
} }
if (len == 0) if (len == 0) {
return StringName(); return StringName();
}
f->get_buffer((uint8_t *)&str_buf[0], len); f->get_buffer((uint8_t *)&str_buf[0], len);
String s; String s;
s.parse_utf8(&str_buf[0]); s.parse_utf8(&str_buf[0]);
@ -286,10 +288,12 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
subname_count += 1; // has a property field, so we should count it as well subname_count += 1; // has a property field, so we should count it as well
} }
for (int i = 0; i < name_count; i++) for (int i = 0; i < name_count; i++) {
names.push_back(_get_string()); names.push_back(_get_string());
for (uint32_t i = 0; i < subname_count; i++) }
for (uint32_t i = 0; i < subname_count; i++) {
subnames.push_back(_get_string()); subnames.push_back(_get_string());
}
NodePath np = NodePath(names, subnames, absolute); NodePath np = NodePath(names, subnames, absolute);
@ -512,8 +516,9 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
Vector<String> array; Vector<String> array;
array.resize(len); array.resize(len);
String *w = array.ptrw(); String *w = array.ptrw();
for (uint32_t i = 0; i < len; i++) for (uint32_t i = 0; i < len; i++) {
w[i] = get_unicode_string(); w[i] = get_unicode_string();
}
r_v = array; r_v = array;
@ -609,8 +614,9 @@ Ref<Resource> ResourceLoaderBinary::get_resource() {
} }
Error ResourceLoaderBinary::load() { Error ResourceLoaderBinary::load() {
if (error != OK) if (error != OK) {
return error; return error;
}
int stage = 0; int stage = 0;
@ -680,8 +686,9 @@ Error ResourceLoaderBinary::load() {
} }
} }
} else { } else {
if (!use_nocache && !ResourceCache::has(res_path)) if (!use_nocache && !ResourceCache::has(res_path)) {
path = res_path; path = res_path;
}
} }
uint64_t offset = internal_resources[i].offset; uint64_t offset = internal_resources[i].offset;
@ -730,8 +737,9 @@ Error ResourceLoaderBinary::load() {
Variant value; Variant value;
error = parse_variant(value); error = parse_variant(value);
if (error) if (error) {
return error; return error;
}
res->set(name, value); res->set(name, value);
} }
@ -783,8 +791,9 @@ String ResourceLoaderBinary::get_unicode_string() {
if (len > str_buf.size()) { if (len > str_buf.size()) {
str_buf.resize(len); str_buf.resize(len);
} }
if (len == 0) if (len == 0) {
return String(); return String();
}
f->get_buffer((uint8_t *)&str_buf[0], len); f->get_buffer((uint8_t *)&str_buf[0], len);
String s; String s;
s.parse_utf8(&str_buf[0]); s.parse_utf8(&str_buf[0]);
@ -793,8 +802,9 @@ String ResourceLoaderBinary::get_unicode_string() {
void ResourceLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types) { void ResourceLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types) {
open(p_f); open(p_f);
if (error) if (error) {
return; return;
}
for (int i = 0; i < external_resources.size(); i++) { for (int i = 0; i < external_resources.size(); i++) {
String dep = external_resources[i].path; String dep = external_resources[i].path;
@ -861,8 +871,9 @@ void ResourceLoaderBinary::open(FileAccess *p_f) {
print_bl("type: " + type); print_bl("type: " + type);
importmd_ofs = f->get_64(); importmd_ofs = f->get_64();
for (int i = 0; i < 14; i++) for (int i = 0; i < 14; i++) {
f->get_32(); //skip a few reserved fields f->get_32(); //skip a few reserved fields
}
uint32_t string_table_size = f->get_32(); uint32_t string_table_size = f->get_32();
string_map.resize(string_table_size); string_map.resize(string_table_size);
@ -946,13 +957,15 @@ String ResourceLoaderBinary::recognize(FileAccess *p_f) {
} }
ResourceLoaderBinary::~ResourceLoaderBinary() { ResourceLoaderBinary::~ResourceLoaderBinary() {
if (f) if (f) {
memdelete(f); memdelete(f);
}
} }
RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error) if (r_error) {
*r_error = ERR_FILE_CANT_OPEN; *r_error = ERR_FILE_CANT_OPEN;
}
Error err; Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
@ -1240,8 +1253,9 @@ String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const
void ResourceFormatSaverBinaryInstance::_pad_buffer(FileAccess *f, int p_bytes) { void ResourceFormatSaverBinaryInstance::_pad_buffer(FileAccess *f, int p_bytes) {
int extra = 4 - (p_bytes % 4); int extra = 4 - (p_bytes % 4);
if (extra < 4) { if (extra < 4) {
for (int i = 0; i < extra; i++) for (int i = 0; i < extra; i++) {
f->store_8(0); //pad to 32 f->store_8(0); //pad to 32
}
} }
} }
@ -1430,8 +1444,9 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
NodePath np = p_property; NodePath np = p_property;
f->store_16(np.get_name_count()); f->store_16(np.get_name_count());
uint16_t snc = np.get_subname_count(); uint16_t snc = np.get_subname_count();
if (np.is_absolute()) if (np.is_absolute()) {
snc |= 0x8000; snc |= 0x8000;
}
f->store_16(snc); f->store_16(snc);
for (int i = 0; i < np.get_name_count(); i++) { for (int i = 0; i < np.get_name_count(); i++) {
if (string_map.has(np.get_name(i))) { if (string_map.has(np.get_name(i))) {
@ -1531,8 +1546,9 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
int len = arr.size(); int len = arr.size();
f->store_32(len); f->store_32(len);
const int32_t *r = arr.ptr(); const int32_t *r = arr.ptr();
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++) {
f->store_32(r[i]); f->store_32(r[i]);
}
} break; } break;
case Variant::PACKED_INT64_ARRAY: { case Variant::PACKED_INT64_ARRAY: {
@ -1541,8 +1557,9 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
int len = arr.size(); int len = arr.size();
f->store_32(len); f->store_32(len);
const int64_t *r = arr.ptr(); const int64_t *r = arr.ptr();
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++) {
f->store_64(r[i]); f->store_64(r[i]);
}
} break; } break;
case Variant::PACKED_FLOAT32_ARRAY: { case Variant::PACKED_FLOAT32_ARRAY: {
@ -1628,8 +1645,9 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
case Variant::OBJECT: { case Variant::OBJECT: {
RES res = p_variant; RES res = p_variant;
if (res.is_null() || external_resources.has(res)) if (res.is_null() || external_resources.has(res)) {
return; return;
}
if (!p_main && (!bundle_resources) && res->get_path().length() && res->get_path().find("::") == -1) { if (!p_main && (!bundle_resources) && res->get_path().length() && res->get_path().find("::") == -1) {
if (res->get_path() == path) { if (res->get_path() == path) {
@ -1641,8 +1659,9 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
return; return;
} }
if (resource_set.has(res)) if (resource_set.has(res)) {
return; return;
}
List<PropertyInfo> property_list; List<PropertyInfo> property_list;
@ -1695,10 +1714,12 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
case Variant::NODE_PATH: { case Variant::NODE_PATH: {
//take the chance and save node path strings //take the chance and save node path strings
NodePath np = p_variant; NodePath np = p_variant;
for (int i = 0; i < np.get_name_count(); i++) for (int i = 0; i < np.get_name_count(); i++) {
get_string_index(np.get_name(i)); get_string_index(np.get_name(i));
for (int i = 0; i < np.get_subname_count(); i++) }
for (int i = 0; i < np.get_subname_count(); i++) {
get_string_index(np.get_subname(i)); get_string_index(np.get_subname(i));
}
} break; } break;
default: { default: {
@ -1718,8 +1739,9 @@ void ResourceFormatSaverBinaryInstance::save_unicode_string(FileAccess *f, const
int ResourceFormatSaverBinaryInstance::get_string_index(const String &p_string) { int ResourceFormatSaverBinaryInstance::get_string_index(const String &p_string) {
StringName s = p_string; StringName s = p_string;
if (string_map.has(s)) if (string_map.has(s)) {
return string_map[s]; return string_map[s];
}
string_map[s] = strings.size(); string_map[s] = strings.size();
strings.push_back(s); strings.push_back(s);
@ -1733,8 +1755,9 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
fac->configure("RSCC"); fac->configure("RSCC");
f = fac; f = fac;
err = fac->_open(p_path, FileAccess::WRITE); err = fac->_open(p_path, FileAccess::WRITE);
if (err) if (err) {
memdelete(f); memdelete(f);
}
} else { } else {
f = FileAccess::open(p_path, FileAccess::WRITE, &err); f = FileAccess::open(p_path, FileAccess::WRITE, &err);
@ -1748,8 +1771,9 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
big_endian = p_flags & ResourceSaver::FLAG_SAVE_BIG_ENDIAN; big_endian = p_flags & ResourceSaver::FLAG_SAVE_BIG_ENDIAN;
takeover_paths = p_flags & ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; takeover_paths = p_flags & ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
if (!p_path.begins_with("res://")) if (!p_path.begins_with("res://")) {
takeover_paths = false; takeover_paths = false;
}
local_path = p_path.get_base_dir(); local_path = p_path.get_base_dir();
path = ProjectSettings::get_singleton()->localize_path(p_path); path = ProjectSettings::get_singleton()->localize_path(p_path);
@ -1765,8 +1789,9 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
if (big_endian) { if (big_endian) {
f->store_32(1); f->store_32(1);
f->set_endian_swap(true); f->set_endian_swap(true);
} else } else {
f->store_32(0); f->store_32(0);
}
f->store_32(0); //64 bits file, false for now f->store_32(0); //64 bits file, false for now
f->store_32(VERSION_MAJOR); f->store_32(VERSION_MAJOR);
@ -1781,8 +1806,9 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
save_unicode_string(f, p_resource->get_class()); save_unicode_string(f, p_resource->get_class());
f->store_64(0); //offset to import metadata f->store_64(0); //offset to import metadata
for (int i = 0; i < 14; i++) for (int i = 0; i < 14; i++) {
f->store_32(0); // reserved f->store_32(0); // reserved
}
List<ResourceData> resources; List<ResourceData> resources;
@ -1795,8 +1821,9 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
E->get()->get_property_list(&property_list); E->get()->get_property_list(&property_list);
for (List<PropertyInfo>::Element *F = property_list.front(); F; F = F->next()) { for (List<PropertyInfo>::Element *F = property_list.front(); F; F = F->next()) {
if (skip_editor && F->get().name.begins_with("__editor")) if (skip_editor && F->get().name.begins_with("__editor")) {
continue; continue;
}
if ((F->get().usage & PROPERTY_USAGE_STORAGE)) { if ((F->get().usage & PROPERTY_USAGE_STORAGE)) {
Property p; Property p;
p.name_idx = get_string_index(F->get().name); p.name_idx = get_string_index(F->get().name);
@ -1942,8 +1969,9 @@ bool ResourceFormatSaverBinary::recognize(const RES &p_resource) const {
void ResourceFormatSaverBinary::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { void ResourceFormatSaverBinary::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
String base = p_resource->get_base_extension().to_lower(); String base = p_resource->get_base_extension().to_lower();
p_extensions->push_back(base); p_extensions->push_back(base);
if (base != "res") if (base != "res") {
p_extensions->push_back("res"); p_extensions->push_back("res");
}
} }
ResourceFormatSaverBinary *ResourceFormatSaverBinary::singleton = nullptr; ResourceFormatSaverBinary *ResourceFormatSaverBinary::singleton = nullptr;

View File

@ -120,8 +120,9 @@ RES ResourceFormatImporter::load(const String &p_path, const String &p_original_
Error err = _get_path_and_type(p_path, pat); Error err = _get_path_and_type(p_path, pat);
if (err != OK) { if (err != OK) {
if (r_error) if (r_error) {
*r_error = err; *r_error = err;
}
return RES(); return RES();
} }
@ -163,11 +164,13 @@ void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_
for (int i = 0; i < importers.size(); i++) { for (int i = 0; i < importers.size(); i++) {
String res_type = importers[i]->get_resource_type(); String res_type = importers[i]->get_resource_type();
if (res_type == String()) if (res_type == String()) {
continue; continue;
}
if (!ClassDB::is_parent_class(res_type, p_type)) if (!ClassDB::is_parent_class(res_type, p_type)) {
continue; continue;
}
List<String> local_exts; List<String> local_exts;
importers[i]->get_recognized_extensions(&local_exts); importers[i]->get_recognized_extensions(&local_exts);
@ -206,8 +209,9 @@ int ResourceFormatImporter::get_import_order(const String &p_path) const {
importer = get_importer_by_extension(p_path.get_extension().to_lower()); importer = get_importer_by_extension(p_path.get_extension().to_lower());
} }
if (importer.is_valid()) if (importer.is_valid()) {
return importer->get_import_order(); return importer->get_import_order();
}
return 0; return 0;
} }
@ -215,10 +219,12 @@ int ResourceFormatImporter::get_import_order(const String &p_path) const {
bool ResourceFormatImporter::handles_type(const String &p_type) const { bool ResourceFormatImporter::handles_type(const String &p_type) const {
for (int i = 0; i < importers.size(); i++) { for (int i = 0; i < importers.size(); i++) {
String res_type = importers[i]->get_resource_type(); String res_type = importers[i]->get_resource_type();
if (res_type == String()) if (res_type == String()) {
continue; continue;
if (ClassDB::is_parent_class(res_type, p_type)) }
if (ClassDB::is_parent_class(res_type, p_type)) {
return true; return true;
}
} }
return true; return true;
@ -239,8 +245,9 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat
Error err; Error err;
FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err); FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err);
if (!f) if (!f) {
return; return;
}
VariantParser::StreamFile stream; VariantParser::StreamFile stream;
stream.f = f; stream.f = f;

View File

@ -59,8 +59,9 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_
} }
for (List<String>::Element *E = extensions.front(); E; E = E->next()) { for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
if (E->get().nocasecmp_to(extension) == 0) if (E->get().nocasecmp_to(extension) == 0) {
return true; return true;
}
} }
return false; return false;
@ -84,8 +85,9 @@ String ResourceFormatLoader::get_resource_type(const String &p_path) const {
} }
void ResourceFormatLoader::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const { void ResourceFormatLoader::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
if (p_type == "" || handles_type(p_type)) if (p_type == "" || handles_type(p_type)) {
get_recognized_extensions(p_extensions); get_recognized_extensions(p_extensions);
}
} }
void ResourceLoader::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) { void ResourceLoader::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) {
@ -116,12 +118,14 @@ RES ResourceFormatLoader::load(const String &p_path, const String &p_original_pa
Variant res = get_script_instance()->call("load", p_path, p_original_path, p_use_sub_threads); Variant res = get_script_instance()->call("load", p_path, p_original_path, p_use_sub_threads);
if (res.get_type() == Variant::INT) { if (res.get_type() == Variant::INT) {
if (r_error) if (r_error) {
*r_error = (Error)res.operator int64_t(); *r_error = (Error)res.operator int64_t();
}
} else { } else {
if (r_error) if (r_error) {
*r_error = OK; *r_error = OK;
}
return res; return res;
} }
@ -240,8 +244,9 @@ void ResourceLoader::_thread_load_function(void *p_userdata) {
if (load_task.resource.is_valid()) { if (load_task.resource.is_valid()) {
load_task.resource->set_path(load_task.local_path); load_task.resource->set_path(load_task.local_path);
if (load_task.xl_remapped) if (load_task.xl_remapped) {
load_task.resource->set_as_translation_remapped(true); load_task.resource->set_as_translation_remapped(true);
}
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
@ -263,10 +268,11 @@ void ResourceLoader::_thread_load_function(void *p_userdata) {
Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, const String &p_source_resource) { Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, const String &p_source_resource) {
String local_path; String local_path;
if (p_path.is_rel_path()) if (p_path.is_rel_path()) {
local_path = "res://" + p_path; local_path = "res://" + p_path;
else } else {
local_path = ProjectSettings::get_singleton()->localize_path(p_path); local_path = ProjectSettings::get_singleton()->localize_path(p_path);
}
thread_load_mutex->lock(); thread_load_mutex->lock();
@ -392,10 +398,11 @@ float ResourceLoader::_dependency_get_progress(const String &p_path) {
ResourceLoader::ThreadLoadStatus ResourceLoader::load_threaded_get_status(const String &p_path, float *r_progress) { ResourceLoader::ThreadLoadStatus ResourceLoader::load_threaded_get_status(const String &p_path, float *r_progress) {
String local_path; String local_path;
if (p_path.is_rel_path()) if (p_path.is_rel_path()) {
local_path = "res://" + p_path; local_path = "res://" + p_path;
else } else {
local_path = ProjectSettings::get_singleton()->localize_path(p_path); local_path = ProjectSettings::get_singleton()->localize_path(p_path);
}
thread_load_mutex->lock(); thread_load_mutex->lock();
if (!thread_load_tasks.has(local_path)) { if (!thread_load_tasks.has(local_path)) {
@ -416,10 +423,11 @@ ResourceLoader::ThreadLoadStatus ResourceLoader::load_threaded_get_status(const
RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) { RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) {
String local_path; String local_path;
if (p_path.is_rel_path()) if (p_path.is_rel_path()) {
local_path = "res://" + p_path; local_path = "res://" + p_path;
else } else {
local_path = ProjectSettings::get_singleton()->localize_path(p_path); local_path = ProjectSettings::get_singleton()->localize_path(p_path);
}
thread_load_mutex->lock(); thread_load_mutex->lock();
if (!thread_load_tasks.has(local_path)) { if (!thread_load_tasks.has(local_path)) {
@ -496,14 +504,16 @@ RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) {
} }
RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) { RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {
if (r_error) if (r_error) {
*r_error = ERR_CANT_OPEN; *r_error = ERR_CANT_OPEN;
}
String local_path; String local_path;
if (p_path.is_rel_path()) if (p_path.is_rel_path()) {
local_path = "res://" + p_path; local_path = "res://" + p_path;
else } else {
local_path = ProjectSettings::get_singleton()->localize_path(p_path); local_path = ProjectSettings::get_singleton()->localize_path(p_path);
}
if (!p_no_cache) { if (!p_no_cache) {
thread_load_mutex->lock(); thread_load_mutex->lock();
@ -586,8 +596,9 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
return RES(); return RES();
} }
if (xl_remapped) if (xl_remapped) {
res->set_as_translation_remapped(true); res->set_as_translation_remapped(true);
}
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
@ -605,10 +616,11 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
bool ResourceLoader::exists(const String &p_path, const String &p_type_hint) { bool ResourceLoader::exists(const String &p_path, const String &p_type_hint) {
String local_path; String local_path;
if (p_path.is_rel_path()) if (p_path.is_rel_path()) {
local_path = "res://" + p_path; local_path = "res://" + p_path;
else } else {
local_path = ProjectSettings::get_singleton()->localize_path(p_path); local_path = ProjectSettings::get_singleton()->localize_path(p_path);
}
if (ResourceCache::has(local_path)) { if (ResourceCache::has(local_path)) {
return true; // If cached, it probably exists return true; // If cached, it probably exists
@ -623,8 +635,9 @@ bool ResourceLoader::exists(const String &p_path, const String &p_type_hint) {
continue; continue;
} }
if (loader[i]->exists(path)) if (loader[i]->exists(path)) {
return true; return true;
}
} }
return false; return false;
@ -651,8 +664,9 @@ void ResourceLoader::remove_resource_format_loader(Ref<ResourceFormatLoader> p_f
// Find loader // Find loader
int i = 0; int i = 0;
for (; i < loader_count; ++i) { for (; i < loader_count; ++i) {
if (loader[i] == p_format_loader) if (loader[i] == p_format_loader) {
break; break;
}
} }
ERR_FAIL_COND(i >= loader_count); // Not found ERR_FAIL_COND(i >= loader_count); // Not found
@ -669,14 +683,16 @@ int ResourceLoader::get_import_order(const String &p_path) {
String path = _path_remap(p_path); String path = _path_remap(p_path);
String local_path; String local_path;
if (path.is_rel_path()) if (path.is_rel_path()) {
local_path = "res://" + path; local_path = "res://" + path;
else } else {
local_path = ProjectSettings::get_singleton()->localize_path(path); local_path = ProjectSettings::get_singleton()->localize_path(path);
}
for (int i = 0; i < loader_count; i++) { for (int i = 0; i < loader_count; i++) {
if (!loader[i]->recognize_path(local_path)) if (!loader[i]->recognize_path(local_path)) {
continue; continue;
}
/* /*
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint)) if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
continue; continue;
@ -692,14 +708,16 @@ String ResourceLoader::get_import_group_file(const String &p_path) {
String path = _path_remap(p_path); String path = _path_remap(p_path);
String local_path; String local_path;
if (path.is_rel_path()) if (path.is_rel_path()) {
local_path = "res://" + path; local_path = "res://" + path;
else } else {
local_path = ProjectSettings::get_singleton()->localize_path(path); local_path = ProjectSettings::get_singleton()->localize_path(path);
}
for (int i = 0; i < loader_count; i++) { for (int i = 0; i < loader_count; i++) {
if (!loader[i]->recognize_path(local_path)) if (!loader[i]->recognize_path(local_path)) {
continue; continue;
}
/* /*
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint)) if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
continue; continue;
@ -715,14 +733,16 @@ bool ResourceLoader::is_import_valid(const String &p_path) {
String path = _path_remap(p_path); String path = _path_remap(p_path);
String local_path; String local_path;
if (path.is_rel_path()) if (path.is_rel_path()) {
local_path = "res://" + path; local_path = "res://" + path;
else } else {
local_path = ProjectSettings::get_singleton()->localize_path(path); local_path = ProjectSettings::get_singleton()->localize_path(path);
}
for (int i = 0; i < loader_count; i++) { for (int i = 0; i < loader_count; i++) {
if (!loader[i]->recognize_path(local_path)) if (!loader[i]->recognize_path(local_path)) {
continue; continue;
}
/* /*
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint)) if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
continue; continue;
@ -738,14 +758,16 @@ bool ResourceLoader::is_imported(const String &p_path) {
String path = _path_remap(p_path); String path = _path_remap(p_path);
String local_path; String local_path;
if (path.is_rel_path()) if (path.is_rel_path()) {
local_path = "res://" + path; local_path = "res://" + path;
else } else {
local_path = ProjectSettings::get_singleton()->localize_path(path); local_path = ProjectSettings::get_singleton()->localize_path(path);
}
for (int i = 0; i < loader_count; i++) { for (int i = 0; i < loader_count; i++) {
if (!loader[i]->recognize_path(local_path)) if (!loader[i]->recognize_path(local_path)) {
continue; continue;
}
/* /*
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint)) if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
continue; continue;
@ -761,14 +783,16 @@ void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_depe
String path = _path_remap(p_path); String path = _path_remap(p_path);
String local_path; String local_path;
if (path.is_rel_path()) if (path.is_rel_path()) {
local_path = "res://" + path; local_path = "res://" + path;
else } else {
local_path = ProjectSettings::get_singleton()->localize_path(path); local_path = ProjectSettings::get_singleton()->localize_path(path);
}
for (int i = 0; i < loader_count; i++) { for (int i = 0; i < loader_count; i++) {
if (!loader[i]->recognize_path(local_path)) if (!loader[i]->recognize_path(local_path)) {
continue; continue;
}
/* /*
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint)) if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
continue; continue;
@ -782,14 +806,16 @@ Error ResourceLoader::rename_dependencies(const String &p_path, const Map<String
String path = _path_remap(p_path); String path = _path_remap(p_path);
String local_path; String local_path;
if (path.is_rel_path()) if (path.is_rel_path()) {
local_path = "res://" + path; local_path = "res://" + path;
else } else {
local_path = ProjectSettings::get_singleton()->localize_path(path); local_path = ProjectSettings::get_singleton()->localize_path(path);
}
for (int i = 0; i < loader_count; i++) { for (int i = 0; i < loader_count; i++) {
if (!loader[i]->recognize_path(local_path)) if (!loader[i]->recognize_path(local_path)) {
continue; continue;
}
/* /*
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint)) if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
continue; continue;
@ -803,10 +829,11 @@ Error ResourceLoader::rename_dependencies(const String &p_path, const Map<String
String ResourceLoader::get_resource_type(const String &p_path) { String ResourceLoader::get_resource_type(const String &p_path) {
String local_path; String local_path;
if (p_path.is_rel_path()) if (p_path.is_rel_path()) {
local_path = "res://" + p_path; local_path = "res://" + p_path;
else } else {
local_path = ProjectSettings::get_singleton()->localize_path(p_path); local_path = ProjectSettings::get_singleton()->localize_path(p_path);
}
for (int i = 0; i < loader_count; i++) { for (int i = 0; i < loader_count; i++) {
String result = loader[i]->get_resource_type(local_path); String result = loader[i]->get_resource_type(local_path);
@ -951,8 +978,9 @@ void ResourceLoader::reload_translation_remaps() {
} }
void ResourceLoader::load_translation_remaps() { void ResourceLoader::load_translation_remaps() {
if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) {
return; return;
}
Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps"); Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
List<Variant> keys; List<Variant> keys;
@ -974,8 +1002,9 @@ void ResourceLoader::clear_translation_remaps() {
} }
void ResourceLoader::load_path_remaps() { void ResourceLoader::load_path_remaps() {
if (!ProjectSettings::get_singleton()->has_setting("path_remap/remapped_paths")) if (!ProjectSettings::get_singleton()->has_setting("path_remap/remapped_paths")) {
return; return;
}
Vector<String> remaps = ProjectSettings::get_singleton()->get("path_remap/remapped_paths"); Vector<String> remaps = ProjectSettings::get_singleton()->get("path_remap/remapped_paths");
int rc = remaps.size(); int rc = remaps.size();
@ -1007,8 +1036,9 @@ Ref<ResourceFormatLoader> ResourceLoader::_find_custom_resource_format_loader(St
} }
bool ResourceLoader::add_custom_resource_format_loader(String script_path) { bool ResourceLoader::add_custom_resource_format_loader(String script_path) {
if (_find_custom_resource_format_loader(script_path).is_valid()) if (_find_custom_resource_format_loader(script_path).is_valid()) {
return false; return false;
}
Ref<Resource> res = ResourceLoader::load(script_path); Ref<Resource> res = ResourceLoader::load(script_path);
ERR_FAIL_COND_V(res.is_null(), false); ERR_FAIL_COND_V(res.is_null(), false);
@ -1032,8 +1062,9 @@ bool ResourceLoader::add_custom_resource_format_loader(String script_path) {
void ResourceLoader::remove_custom_resource_format_loader(String script_path) { void ResourceLoader::remove_custom_resource_format_loader(String script_path) {
Ref<ResourceFormatLoader> custom_loader = _find_custom_resource_format_loader(script_path); Ref<ResourceFormatLoader> custom_loader = _find_custom_resource_format_loader(script_path);
if (custom_loader.is_valid()) if (custom_loader.is_valid()) {
remove_resource_format_loader(custom_loader); remove_resource_format_loader(custom_loader);
}
} }
void ResourceLoader::add_custom_loaders() { void ResourceLoader::add_custom_loaders() {

View File

@ -158,8 +158,9 @@ public:
static bool get_timestamp_on_load() { return timestamp_on_load; } static bool get_timestamp_on_load() { return timestamp_on_load; }
static void notify_load_error(const String &p_err) { static void notify_load_error(const String &p_err) {
if (err_notify) if (err_notify) {
err_notify(err_notify_ud, p_err); err_notify(err_notify_ud, p_err);
}
} }
static void set_error_notify_func(void *p_ud, ResourceLoadErrorNotify p_err_notify) { static void set_error_notify_func(void *p_ud, ResourceLoadErrorNotify p_err_notify) {
err_notify = p_err_notify; err_notify = p_err_notify;
@ -167,8 +168,9 @@ public:
} }
static void notify_dependency_error(const String &p_path, const String &p_dependency, const String &p_type) { static void notify_dependency_error(const String &p_path, const String &p_dependency, const String &p_type) {
if (dep_err_notify) if (dep_err_notify) {
dep_err_notify(dep_err_notify_ud, p_path, p_dependency, p_type); dep_err_notify(dep_err_notify_ud, p_path, p_dependency, p_type);
}
} }
static void set_dependency_error_notify_func(void *p_ud, DependencyErrorNotify p_err_notify) { static void set_dependency_error_notify_func(void *p_ud, DependencyErrorNotify p_err_notify) {
dep_err_notify = p_err_notify; dep_err_notify = p_err_notify;

View File

@ -86,28 +86,32 @@ Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t
Error err = ERR_FILE_UNRECOGNIZED; Error err = ERR_FILE_UNRECOGNIZED;
for (int i = 0; i < saver_count; i++) { for (int i = 0; i < saver_count; i++) {
if (!saver[i]->recognize(p_resource)) if (!saver[i]->recognize(p_resource)) {
continue; continue;
}
List<String> extensions; List<String> extensions;
bool recognized = false; bool recognized = false;
saver[i]->get_recognized_extensions(p_resource, &extensions); saver[i]->get_recognized_extensions(p_resource, &extensions);
for (List<String>::Element *E = extensions.front(); E; E = E->next()) { for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
if (E->get().nocasecmp_to(extension) == 0) if (E->get().nocasecmp_to(extension) == 0) {
recognized = true; recognized = true;
}
} }
if (!recognized) if (!recognized) {
continue; continue;
}
String old_path = p_resource->get_path(); String old_path = p_resource->get_path();
String local_path = ProjectSettings::get_singleton()->localize_path(p_path); String local_path = ProjectSettings::get_singleton()->localize_path(p_path);
RES rwcopy = p_resource; RES rwcopy = p_resource;
if (p_flags & FLAG_CHANGE_PATH) if (p_flags & FLAG_CHANGE_PATH) {
rwcopy->set_path(local_path); rwcopy->set_path(local_path);
}
err = saver[i]->save(p_path, p_resource, p_flags); err = saver[i]->save(p_path, p_resource, p_flags);
@ -122,11 +126,13 @@ Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t
} }
#endif #endif
if (p_flags & FLAG_CHANGE_PATH) if (p_flags & FLAG_CHANGE_PATH) {
rwcopy->set_path(old_path); rwcopy->set_path(old_path);
}
if (save_callback && p_path.begins_with("res://")) if (save_callback && p_path.begins_with("res://")) {
save_callback(p_resource, p_path); save_callback(p_resource, p_path);
}
return OK; return OK;
} }
@ -166,8 +172,9 @@ void ResourceSaver::remove_resource_format_saver(Ref<ResourceFormatSaver> p_form
// Find saver // Find saver
int i = 0; int i = 0;
for (; i < saver_count; ++i) { for (; i < saver_count; ++i) {
if (saver[i] == p_format_saver) if (saver[i] == p_format_saver) {
break; break;
}
} }
ERR_FAIL_COND(i >= saver_count); // Not found ERR_FAIL_COND(i >= saver_count); // Not found
@ -190,8 +197,9 @@ Ref<ResourceFormatSaver> ResourceSaver::_find_custom_resource_format_saver(Strin
} }
bool ResourceSaver::add_custom_resource_format_saver(String script_path) { bool ResourceSaver::add_custom_resource_format_saver(String script_path) {
if (_find_custom_resource_format_saver(script_path).is_valid()) if (_find_custom_resource_format_saver(script_path).is_valid()) {
return false; return false;
}
Ref<Resource> res = ResourceLoader::load(script_path); Ref<Resource> res = ResourceLoader::load(script_path);
ERR_FAIL_COND_V(res.is_null(), false); ERR_FAIL_COND_V(res.is_null(), false);
@ -215,8 +223,9 @@ bool ResourceSaver::add_custom_resource_format_saver(String script_path) {
void ResourceSaver::remove_custom_resource_format_saver(String script_path) { void ResourceSaver::remove_custom_resource_format_saver(String script_path) {
Ref<ResourceFormatSaver> custom_saver = _find_custom_resource_format_saver(script_path); Ref<ResourceFormatSaver> custom_saver = _find_custom_resource_format_saver(script_path);
if (custom_saver.is_valid()) if (custom_saver.is_valid()) {
remove_resource_format_saver(custom_saver); remove_resource_format_saver(custom_saver);
}
} }
void ResourceSaver::add_custom_savers() { void ResourceSaver::add_custom_savers() {

View File

@ -34,8 +34,9 @@
Error StreamPeer::_put_data(const Vector<uint8_t> &p_data) { Error StreamPeer::_put_data(const Vector<uint8_t> &p_data) {
int len = p_data.size(); int len = p_data.size();
if (len == 0) if (len == 0) {
return OK; return OK;
}
const uint8_t *r = p_data.ptr(); const uint8_t *r = p_data.ptr();
return put_data(&r[0], len); return put_data(&r[0], len);
} }
@ -318,8 +319,9 @@ double StreamPeer::get_double() {
} }
String StreamPeer::get_string(int p_bytes) { String StreamPeer::get_string(int p_bytes) {
if (p_bytes < 0) if (p_bytes < 0) {
p_bytes = get_u32(); p_bytes = get_u32();
}
ERR_FAIL_COND_V(p_bytes < 0, String()); ERR_FAIL_COND_V(p_bytes < 0, String());
Vector<char> buf; Vector<char> buf;
@ -332,8 +334,9 @@ String StreamPeer::get_string(int p_bytes) {
} }
String StreamPeer::get_utf8_string(int p_bytes) { String StreamPeer::get_utf8_string(int p_bytes) {
if (p_bytes < 0) if (p_bytes < 0) {
p_bytes = get_u32(); p_bytes = get_u32();
}
ERR_FAIL_COND_V(p_bytes < 0, String()); ERR_FAIL_COND_V(p_bytes < 0, String());
Vector<uint8_t> buf; Vector<uint8_t> buf;
@ -421,8 +424,9 @@ void StreamPeerBuffer::_bind_methods() {
} }
Error StreamPeerBuffer::put_data(const uint8_t *p_data, int p_bytes) { Error StreamPeerBuffer::put_data(const uint8_t *p_data, int p_bytes) {
if (p_bytes <= 0) if (p_bytes <= 0) {
return OK; return OK;
}
if (pointer + p_bytes > data.size()) { if (pointer + p_bytes > data.size()) {
data.resize(pointer + p_bytes); data.resize(pointer + p_bytes);
@ -443,8 +447,9 @@ Error StreamPeerBuffer::put_partial_data(const uint8_t *p_data, int p_bytes, int
Error StreamPeerBuffer::get_data(uint8_t *p_buffer, int p_bytes) { Error StreamPeerBuffer::get_data(uint8_t *p_buffer, int p_bytes) {
int recv; int recv;
get_partial_data(p_buffer, p_bytes, recv); get_partial_data(p_buffer, p_bytes, recv);
if (recv != p_bytes) if (recv != p_bytes) {
return ERR_INVALID_PARAMETER; return ERR_INVALID_PARAMETER;
}
return OK; return OK;
} }

View File

@ -35,8 +35,9 @@
StreamPeerSSL *(*StreamPeerSSL::_create)() = nullptr; StreamPeerSSL *(*StreamPeerSSL::_create)() = nullptr;
StreamPeerSSL *StreamPeerSSL::create() { StreamPeerSSL *StreamPeerSSL::create() {
if (_create) if (_create) {
return _create(); return _create();
}
return nullptr; return nullptr;
} }

View File

@ -117,8 +117,9 @@ Error StreamPeerTCP::write(const uint8_t *p_data, int p_bytes, int &r_sent, bool
} }
} }
if (!_sock->is_open()) if (!_sock->is_open()) {
return FAILED; return FAILED;
}
Error err; Error err;
int data_to_send = p_bytes; int data_to_send = p_bytes;
@ -257,8 +258,9 @@ StreamPeerTCP::Status StreamPeerTCP::get_status() {
} }
void StreamPeerTCP::disconnect_from_host() { void StreamPeerTCP::disconnect_from_host() {
if (_sock.is_valid() && _sock->is_open()) if (_sock.is_valid() && _sock->is_open()) {
_sock->close(); _sock->close();
}
timeout = 0; timeout = 0;
status = STATUS_NONE; status = STATUS_NONE;
@ -308,8 +310,9 @@ Error StreamPeerTCP::_connect(const String &p_address, int p_port) {
ip = p_address; ip = p_address;
} else { } else {
ip = IP::get_singleton()->resolve_hostname(p_address); ip = IP::get_singleton()->resolve_hostname(p_address);
if (!ip.is_valid()) if (!ip.is_valid()) {
return ERR_CANT_RESOLVE; return ERR_CANT_RESOLVE;
}
} }
return connect_to_host(ip, p_port); return connect_to_host(ip, p_port);

View File

@ -47,8 +47,9 @@ Error TCP_Server::listen(uint16_t p_port, const IP_Address &p_bind_address) {
IP::Type ip_type = IP::TYPE_ANY; IP::Type ip_type = IP::TYPE_ANY;
// If the bind address is valid use its type as the socket type // If the bind address is valid use its type as the socket type
if (p_bind_address.is_valid()) if (p_bind_address.is_valid()) {
ip_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6; ip_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
}
err = _sock->open(NetSocket::TYPE_TCP, ip_type); err = _sock->open(NetSocket::TYPE_TCP, ip_type);
@ -82,8 +83,9 @@ bool TCP_Server::is_listening() const {
bool TCP_Server::is_connection_available() const { bool TCP_Server::is_connection_available() const {
ERR_FAIL_COND_V(!_sock.is_valid(), false); ERR_FAIL_COND_V(!_sock.is_valid(), false);
if (!_sock->is_open()) if (!_sock->is_open()) {
return false; return false;
}
Error err = _sock->poll(NetSocket::POLL_TYPE_IN, 0); Error err = _sock->poll(NetSocket::POLL_TYPE_IN, 0);
return (err == OK); return (err == OK);
@ -99,8 +101,9 @@ Ref<StreamPeerTCP> TCP_Server::take_connection() {
IP_Address ip; IP_Address ip;
uint16_t port = 0; uint16_t port = 0;
ns = _sock->accept(ip, port); ns = _sock->accept(ip, port);
if (!ns.is_valid()) if (!ns.is_valid()) {
return conn; return conn;
}
conn = Ref<StreamPeerTCP>(memnew(StreamPeerTCP)); conn = Ref<StreamPeerTCP>(memnew(StreamPeerTCP));
conn->accept_socket(ns, ip, port); conn->accept_socket(ns, ip, port);

View File

@ -47,8 +47,9 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
String msg_str; String msg_str;
String config; String config;
if (r_error) if (r_error) {
*r_error = ERR_FILE_CORRUPT; *r_error = ERR_FILE_CORRUPT;
}
Ref<Translation> translation = Ref<Translation>(memnew(Translation)); Ref<Translation> translation = Ref<Translation>(memnew(Translation));
int line = 1; int line = 1;
@ -77,10 +78,12 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
} }
if (msg_id != "") { if (msg_id != "") {
if (!skip_this) if (!skip_this) {
translation->add_message(msg_id, msg_str); translation->add_message(msg_id, msg_str);
} else if (config == "") }
} else if (config == "") {
config = msg_str; config = msg_str;
}
l = l.substr(5, l.length()).strip_edges(); l = l.substr(5, l.length()).strip_edges();
status = STATUS_READING_ID; status = STATUS_READING_ID;
@ -135,10 +138,11 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
l = l.substr(0, end_pos); l = l.substr(0, end_pos);
l = l.c_unescape(); l = l.c_unescape();
if (status == STATUS_READING_ID) if (status == STATUS_READING_ID) {
msg_id += l; msg_id += l;
else } else {
msg_str += l; msg_str += l;
}
line++; line++;
} }
@ -148,10 +152,12 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
if (status == STATUS_READING_STRING) { if (status == STATUS_READING_STRING) {
if (msg_id != "") { if (msg_id != "") {
if (!skip_this) if (!skip_this) {
translation->add_message(msg_id, msg_str); translation->add_message(msg_id, msg_str);
} else if (config == "") }
} else if (config == "") {
config = msg_str; config = msg_str;
}
} }
ERR_FAIL_COND_V_MSG(config == "", RES(), "No config found in file: " + f->get_path() + "."); ERR_FAIL_COND_V_MSG(config == "", RES(), "No config found in file: " + f->get_path() + ".");
@ -160,8 +166,9 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
for (int i = 0; i < configs.size(); i++) { for (int i = 0; i < configs.size(); i++) {
String c = configs[i].strip_edges(); String c = configs[i].strip_edges();
int p = c.find(":"); int p = c.find(":");
if (p == -1) if (p == -1) {
continue; continue;
}
String prop = c.substr(0, p).strip_edges(); String prop = c.substr(0, p).strip_edges();
String value = c.substr(p + 1, c.length()).strip_edges(); String value = c.substr(p + 1, c.length()).strip_edges();
@ -170,15 +177,17 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
} }
} }
if (r_error) if (r_error) {
*r_error = OK; *r_error = OK;
}
return translation; return translation;
} }
RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error) if (r_error) {
*r_error = ERR_CANT_OPEN; *r_error = ERR_CANT_OPEN;
}
FileAccess *f = FileAccess::open(p_path, FileAccess::READ); FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_V_MSG(!f, RES(), "Cannot open file '" + p_path + "'."); ERR_FAIL_COND_V_MSG(!f, RES(), "Cannot open file '" + p_path + "'.");
@ -196,7 +205,8 @@ bool TranslationLoaderPO::handles_type(const String &p_type) const {
} }
String TranslationLoaderPO::get_resource_type(const String &p_path) const { String TranslationLoaderPO::get_resource_type(const String &p_path) const {
if (p_path.get_extension().to_lower() == "po") if (p_path.get_extension().to_lower() == "po") {
return "Translation"; return "Translation";
}
return ""; return "";
} }

View File

@ -46,13 +46,15 @@ Error UDPServer::listen(uint16_t p_port, const IP_Address &p_bind_address) {
Error err; Error err;
IP::Type ip_type = IP::TYPE_ANY; IP::Type ip_type = IP::TYPE_ANY;
if (p_bind_address.is_valid()) if (p_bind_address.is_valid()) {
ip_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6; ip_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
}
err = _sock->open(NetSocket::TYPE_UDP, ip_type); err = _sock->open(NetSocket::TYPE_UDP, ip_type);
if (err != OK) if (err != OK) {
return ERR_CANT_CREATE; return ERR_CANT_CREATE;
}
_sock->set_blocking_enabled(false); _sock->set_blocking_enabled(false);
_sock->set_reuse_address_enabled(true); _sock->set_reuse_address_enabled(true);
@ -76,8 +78,9 @@ bool UDPServer::is_listening() const {
bool UDPServer::is_connection_available() const { bool UDPServer::is_connection_available() const {
ERR_FAIL_COND_V(!_sock.is_valid(), false); ERR_FAIL_COND_V(!_sock.is_valid(), false);
if (!_sock->is_open()) if (!_sock->is_open()) {
return false; return false;
}
Error err = _sock->poll(NetSocket::POLL_TYPE_IN, 0); Error err = _sock->poll(NetSocket::POLL_TYPE_IN, 0);
return (err == OK); return (err == OK);

View File

@ -38,9 +38,11 @@ VARIANT_ENUM_CAST(XMLParser::NodeType);
static bool _equalsn(const CharType *str1, const CharType *str2, int len) { static bool _equalsn(const CharType *str1, const CharType *str2, int len) {
int i; int i;
for (i = 0; i < len && str1[i] && str2[i]; ++i) for (i = 0; i < len && str1[i] && str2[i]; ++i) {
if (str1[i] != str2[i]) if (str1[i] != str2[i]) {
return false; return false;
}
}
// if one (or both) of the strings was smaller then they // if one (or both) of the strings was smaller then they
// are only equal if they have the same length // are only equal if they have the same length
@ -51,8 +53,9 @@ String XMLParser::_replace_special_characters(const String &origstr) {
int pos = origstr.find("&"); int pos = origstr.find("&");
int oldPos = 0; int oldPos = 0;
if (pos == -1) if (pos == -1) {
return origstr; return origstr;
}
String newstr; String newstr;
@ -83,8 +86,9 @@ String XMLParser::_replace_special_characters(const String &origstr) {
pos = origstr.find("&", pos); pos = origstr.find("&", pos);
} }
if (oldPos < origstr.length() - 1) if (oldPos < origstr.length() - 1) {
newstr += (origstr.substr(oldPos, origstr.length() - oldPos)); newstr += (origstr.substr(oldPos, origstr.length() - oldPos));
}
return newstr; return newstr;
} }
@ -99,12 +103,15 @@ bool XMLParser::_set_text(char *start, char *end) {
// only white space, so that this text won't be reported // only white space, so that this text won't be reported
if (end - start < 3) { if (end - start < 3) {
char *p = start; char *p = start;
for (; p != end; ++p) for (; p != end; ++p) {
if (!_is_white_space(*p)) if (!_is_white_space(*p)) {
break; break;
}
}
if (p == end) if (p == end) {
return false; return false;
}
} }
// set current text to the parsed text, and replace xml special characters // set current text to the parsed text, and replace xml special characters
@ -125,8 +132,9 @@ void XMLParser::_parse_closing_xml_element() {
++P; ++P;
const char *pBeginClose = P; const char *pBeginClose = P;
while (*P != '>') while (*P != '>') {
++P; ++P;
}
node_name = String::utf8(pBeginClose, (int)(P - pBeginClose)); node_name = String::utf8(pBeginClose, (int)(P - pBeginClose));
#ifdef DEBUG_XML #ifdef DEBUG_XML
@ -140,15 +148,17 @@ void XMLParser::_ignore_definition() {
char *F = P; char *F = P;
// move until end marked with '>' reached // move until end marked with '>' reached
while (*P != '>') while (*P != '>') {
++P; ++P;
}
node_name.parse_utf8(F, P - F); node_name.parse_utf8(F, P - F);
++P; ++P;
} }
bool XMLParser::_parse_cdata() { bool XMLParser::_parse_cdata() {
if (*(P + 1) != '[') if (*(P + 1) != '[') {
return false; return false;
}
node_type = NODE_CDATA; node_type = NODE_CDATA;
@ -159,8 +169,9 @@ bool XMLParser::_parse_cdata() {
++count; ++count;
} }
if (!*P) if (!*P) {
return true; return true;
}
char *cDataBegin = P; char *cDataBegin = P;
char *cDataEnd = nullptr; char *cDataEnd = nullptr;
@ -176,10 +187,11 @@ bool XMLParser::_parse_cdata() {
++P; ++P;
} }
if (cDataEnd) if (cDataEnd) {
node_name = String::utf8(cDataBegin, (int)(cDataEnd - cDataBegin)); node_name = String::utf8(cDataBegin, (int)(cDataEnd - cDataBegin));
else } else {
node_name = ""; node_name = "";
}
#ifdef DEBUG_XML #ifdef DEBUG_XML
print_line("XML CDATA: " + node_name); print_line("XML CDATA: " + node_name);
#endif #endif
@ -197,10 +209,11 @@ void XMLParser::_parse_comment() {
// move until end of comment reached // move until end of comment reached
while (count) { while (count) {
if (*P == '>') if (*P == '>') {
--count; --count;
else if (*P == '<') } else if (*P == '<') {
++count; ++count;
}
++P; ++P;
} }
@ -222,46 +235,52 @@ void XMLParser::_parse_opening_xml_element() {
const char *startName = P; const char *startName = P;
// find end of element // find end of element
while (*P != '>' && !_is_white_space(*P)) while (*P != '>' && !_is_white_space(*P)) {
++P; ++P;
}
const char *endName = P; const char *endName = P;
// find attributes // find attributes
while (*P != '>') { while (*P != '>') {
if (_is_white_space(*P)) if (_is_white_space(*P)) {
++P; ++P;
else { } else {
if (*P != '/') { if (*P != '/') {
// we've got an attribute // we've got an attribute
// read the attribute names // read the attribute names
const char *attributeNameBegin = P; const char *attributeNameBegin = P;
while (!_is_white_space(*P) && *P != '=') while (!_is_white_space(*P) && *P != '=') {
++P; ++P;
}
const char *attributeNameEnd = P; const char *attributeNameEnd = P;
++P; ++P;
// read the attribute value // read the attribute value
// check for quotes and single quotes, thx to murphy // check for quotes and single quotes, thx to murphy
while ((*P != '\"') && (*P != '\'') && *P) while ((*P != '\"') && (*P != '\'') && *P) {
++P; ++P;
}
if (!*P) // malformatted xml file if (!*P) { // malformatted xml file
return; return;
}
const char attributeQuoteChar = *P; const char attributeQuoteChar = *P;
++P; ++P;
const char *attributeValueBegin = P; const char *attributeValueBegin = P;
while (*P != attributeQuoteChar && *P) while (*P != attributeQuoteChar && *P) {
++P; ++P;
}
if (!*P) // malformatted xml file if (!*P) { // malformatted xml file
return; return;
}
const char *attributeValueEnd = P; const char *attributeValueEnd = P;
++P; ++P;
@ -304,16 +323,19 @@ void XMLParser::_parse_current_node() {
node_offset = P - data; node_offset = P - data;
// more forward until '<' found // more forward until '<' found
while (*P != '<' && *P) while (*P != '<' && *P) {
++P; ++P;
}
if (!*P) if (!*P) {
return; return;
}
if (P - start > 0) { if (P - start > 0) {
// we found some text, store it // we found some text, store it
if (_set_text(start, P)) if (_set_text(start, P)) {
return; return;
}
} }
++P; ++P;
@ -327,8 +349,9 @@ void XMLParser::_parse_current_node() {
_ignore_definition(); _ignore_definition();
break; break;
case '!': case '!':
if (!_parse_cdata()) if (!_parse_cdata()) {
_parse_comment(); _parse_comment();
}
break; break;
default: default:
_parse_opening_xml_element(); _parse_opening_xml_element();
@ -417,8 +440,9 @@ String XMLParser::get_attribute_value(int p_idx) const {
bool XMLParser::has_attribute(const String &p_name) const { bool XMLParser::has_attribute(const String &p_name) const {
for (int i = 0; i < attributes.size(); i++) { for (int i = 0; i < attributes.size(); i++) {
if (attributes[i].name == p_name) if (attributes[i].name == p_name) {
return true; return true;
}
} }
return false; return false;
@ -447,8 +471,9 @@ String XMLParser::get_attribute_value_safe(const String &p_name) const {
} }
} }
if (idx < 0) if (idx < 0) {
return ""; return "";
}
return attributes[idx].value; return attributes[idx].value;
} }
@ -496,8 +521,9 @@ Error XMLParser::open(const String &p_path) {
void XMLParser::skip_section() { void XMLParser::skip_section() {
// skip if this element is empty anyway. // skip if this element is empty anyway.
if (is_empty()) if (is_empty()) {
return; return;
}
// read until we've reached the last element in this section // read until we've reached the last element in this section
int tagcount = 1; int tagcount = 1;
@ -506,14 +532,16 @@ void XMLParser::skip_section() {
if (get_node_type() == XMLParser::NODE_ELEMENT && if (get_node_type() == XMLParser::NODE_ELEMENT &&
!is_empty()) { !is_empty()) {
++tagcount; ++tagcount;
} else if (get_node_type() == XMLParser::NODE_ELEMENT_END) } else if (get_node_type() == XMLParser::NODE_ELEMENT_END) {
--tagcount; --tagcount;
}
} }
} }
void XMLParser::close() { void XMLParser::close() {
if (data) if (data) {
memdelete_arr(data); memdelete_arr(data);
}
data = nullptr; data = nullptr;
length = 0; length = 0;
P = nullptr; P = nullptr;
@ -535,6 +563,7 @@ XMLParser::XMLParser() {
} }
XMLParser::~XMLParser() { XMLParser::~XMLParser() {
if (data) if (data) {
memdelete_arr(data); memdelete_arr(data);
}
} }

View File

@ -44,8 +44,9 @@ void *zipio_open(void *data, const char *p_fname, int mode) {
f = FileAccess::open(fname, FileAccess::READ); f = FileAccess::open(fname, FileAccess::READ);
} }
if (!f) if (!f) {
return nullptr; return nullptr;
}
return data; return data;
} }

View File

@ -149,14 +149,17 @@ private:
first = p_I->next_ptr; first = p_I->next_ptr;
}; };
if (last == p_I) if (last == p_I) {
last = p_I->prev_ptr; last = p_I->prev_ptr;
}
if (p_I->prev_ptr) if (p_I->prev_ptr) {
p_I->prev_ptr->next_ptr = p_I->next_ptr; p_I->prev_ptr->next_ptr = p_I->next_ptr;
}
if (p_I->next_ptr) if (p_I->next_ptr) {
p_I->next_ptr->prev_ptr = p_I->prev_ptr; p_I->next_ptr->prev_ptr = p_I->prev_ptr;
}
memdelete_allocator<Element, A>(const_cast<Element *>(p_I)); memdelete_allocator<Element, A>(const_cast<Element *>(p_I));
size_cache--; size_cache--;
@ -220,8 +223,9 @@ public:
_data->last = n; _data->last = n;
if (!_data->first) if (!_data->first) {
_data->first = n; _data->first = n;
}
_data->size_cache++; _data->size_cache++;
@ -229,8 +233,9 @@ public:
}; };
void pop_back() { void pop_back() {
if (_data && _data->last) if (_data && _data->last) {
erase(_data->last); erase(_data->last);
}
} }
/** /**
@ -256,8 +261,9 @@ public:
_data->first = n; _data->first = n;
if (!_data->last) if (!_data->last) {
_data->last = n; _data->last = n;
}
_data->size_cache++; _data->size_cache++;
@ -265,8 +271,9 @@ public:
}; };
void pop_front() { void pop_front() {
if (_data && _data->first) if (_data && _data->first) {
erase(_data->first); erase(_data->first);
}
} }
Element *insert_after(Element *p_element, const T &p_value) { Element *insert_after(Element *p_element, const T &p_value) {
@ -328,8 +335,9 @@ public:
Element *find(const T_v &p_val) { Element *find(const T_v &p_val) {
Element *it = front(); Element *it = front();
while (it) { while (it) {
if (it->value == p_val) if (it->value == p_val) {
return it; return it;
}
it = it->next(); it = it->next();
}; };
@ -396,15 +404,19 @@ public:
p_B->next_ptr = A_next; p_B->next_ptr = A_next;
p_B->prev_ptr = A_prev; p_B->prev_ptr = A_prev;
if (p_A->prev_ptr) if (p_A->prev_ptr) {
p_A->prev_ptr->next_ptr = p_A; p_A->prev_ptr->next_ptr = p_A;
if (p_A->next_ptr) }
if (p_A->next_ptr) {
p_A->next_ptr->prev_ptr = p_A; p_A->next_ptr->prev_ptr = p_A;
}
if (p_B->prev_ptr) if (p_B->prev_ptr) {
p_B->prev_ptr->next_ptr = p_B; p_B->prev_ptr->next_ptr = p_B;
if (p_B->next_ptr) }
if (p_B->next_ptr) {
p_B->next_ptr->prev_ptr = p_B; p_B->next_ptr->prev_ptr = p_B;
}
} }
/** /**
* copy the list * copy the list
@ -446,18 +458,21 @@ public:
void move_to_back(Element *p_I) { void move_to_back(Element *p_I) {
ERR_FAIL_COND(p_I->data != _data); ERR_FAIL_COND(p_I->data != _data);
if (!p_I->next_ptr) if (!p_I->next_ptr) {
return; return;
}
if (_data->first == p_I) { if (_data->first == p_I) {
_data->first = p_I->next_ptr; _data->first = p_I->next_ptr;
}; };
if (_data->last == p_I) if (_data->last == p_I) {
_data->last = p_I->prev_ptr; _data->last = p_I->prev_ptr;
}
if (p_I->prev_ptr) if (p_I->prev_ptr) {
p_I->prev_ptr->next_ptr = p_I->next_ptr; p_I->prev_ptr->next_ptr = p_I->next_ptr;
}
p_I->next_ptr->prev_ptr = p_I->prev_ptr; p_I->next_ptr->prev_ptr = p_I->prev_ptr;
@ -480,20 +495,23 @@ public:
void move_to_front(Element *p_I) { void move_to_front(Element *p_I) {
ERR_FAIL_COND(p_I->data != _data); ERR_FAIL_COND(p_I->data != _data);
if (!p_I->prev_ptr) if (!p_I->prev_ptr) {
return; return;
}
if (_data->first == p_I) { if (_data->first == p_I) {
_data->first = p_I->next_ptr; _data->first = p_I->next_ptr;
}; };
if (_data->last == p_I) if (_data->last == p_I) {
_data->last = p_I->prev_ptr; _data->last = p_I->prev_ptr;
}
p_I->prev_ptr->next_ptr = p_I->next_ptr; p_I->prev_ptr->next_ptr = p_I->next_ptr;
if (p_I->next_ptr) if (p_I->next_ptr) {
p_I->next_ptr->prev_ptr = p_I->prev_ptr; p_I->next_ptr->prev_ptr = p_I->prev_ptr;
}
_data->first->prev_ptr = p_I; _data->first->prev_ptr = p_I;
p_I->next_ptr = _data->first; p_I->next_ptr = _data->first;
@ -541,8 +559,9 @@ public:
template <class C> template <class C>
void sort_custom_inplace() { void sort_custom_inplace() {
if (size() < 2) if (size() < 2) {
return; return;
}
Element *from = front(); Element *from = front();
Element *current = from; Element *current = from;
@ -563,15 +582,17 @@ public:
find = find->next_ptr; find = find->next_ptr;
} }
if (current->prev_ptr) if (current->prev_ptr) {
current->prev_ptr->next_ptr = current; current->prev_ptr->next_ptr = current;
else } else {
from = current; from = current;
}
if (current->next_ptr) if (current->next_ptr) {
current->next_ptr->prev_ptr = current; current->next_ptr->prev_ptr = current;
else } else {
to = current; to = current;
}
} else { } else {
current->prev_ptr = nullptr; current->prev_ptr = nullptr;
current->next_ptr = nullptr; current->next_ptr = nullptr;
@ -597,8 +618,9 @@ public:
//if you don't want to use auxiliary memory, use the in_place version //if you don't want to use auxiliary memory, use the in_place version
int s = size(); int s = size();
if (s < 2) if (s < 2) {
return; return;
}
Element **aux_buffer = memnew_arr(Element *, s); Element **aux_buffer = memnew_arr(Element *, s);

View File

@ -76,8 +76,9 @@ public:
void erase(const T &p_val) { void erase(const T &p_val) {
U idx = find(p_val); U idx = find(p_val);
if (idx >= 0) if (idx >= 0) {
remove(idx); remove(idx);
}
} }
void invert() { void invert() {
@ -167,8 +168,9 @@ public:
template <class C> template <class C>
void sort_custom() { void sort_custom() {
U len = count; U len = count;
if (len == 0) if (len == 0) {
return; return;
}
SortArray<T, C> sorter; SortArray<T, C> sorter;
sorter.sort(data, len); sorter.sort(data, len);

View File

@ -138,13 +138,15 @@ private:
inline void _rotate_left(Element *p_node) { inline void _rotate_left(Element *p_node) {
Element *r = p_node->right; Element *r = p_node->right;
p_node->right = r->left; p_node->right = r->left;
if (r->left != _data._nil) if (r->left != _data._nil) {
r->left->parent = p_node; r->left->parent = p_node;
}
r->parent = p_node->parent; r->parent = p_node->parent;
if (p_node == p_node->parent->left) if (p_node == p_node->parent->left) {
p_node->parent->left = r; p_node->parent->left = r;
else } else {
p_node->parent->right = r; p_node->parent->right = r;
}
r->left = p_node; r->left = p_node;
p_node->parent = r; p_node->parent = r;
@ -153,13 +155,15 @@ private:
inline void _rotate_right(Element *p_node) { inline void _rotate_right(Element *p_node) {
Element *l = p_node->left; Element *l = p_node->left;
p_node->left = l->right; p_node->left = l->right;
if (l->right != _data._nil) if (l->right != _data._nil) {
l->right->parent = p_node; l->right->parent = p_node;
}
l->parent = p_node->parent; l->parent = p_node->parent;
if (p_node == p_node->parent->right) if (p_node == p_node->parent->right) {
p_node->parent->right = l; p_node->parent->right = l;
else } else {
p_node->parent->left = l; p_node->parent->left = l;
}
l->right = p_node; l->right = p_node;
p_node->parent = l; p_node->parent = l;
@ -179,8 +183,9 @@ private:
node = node->parent; node = node->parent;
} }
if (node->parent == _data._root) if (node->parent == _data._root) {
return nullptr; // No successor, as p_node = last node return nullptr; // No successor, as p_node = last node
}
return node->parent; return node->parent;
} }
} }
@ -199,8 +204,9 @@ private:
node = node->parent; node = node->parent;
} }
if (node == _data._root) if (node == _data._root) {
return nullptr; // No predecessor, as p_node = first node return nullptr; // No predecessor, as p_node = first node
}
return node->parent; return node->parent;
} }
} }
@ -210,12 +216,13 @@ private:
C less; C less;
while (node != _data._nil) { while (node != _data._nil) {
if (less(p_key, node->_key)) if (less(p_key, node->_key)) {
node = node->left; node = node->left;
else if (less(node->_key, p_key)) } else if (less(node->_key, p_key)) {
node = node->right; node = node->right;
else } else {
return node; // found return node; // found
}
} }
return nullptr; return nullptr;
@ -229,19 +236,22 @@ private:
while (node != _data._nil) { while (node != _data._nil) {
prev = node; prev = node;
if (less(p_key, node->_key)) if (less(p_key, node->_key)) {
node = node->left; node = node->left;
else if (less(node->_key, p_key)) } else if (less(node->_key, p_key)) {
node = node->right; node = node->right;
else } else {
return node; // found return node; // found
}
} }
if (prev == nullptr) if (prev == nullptr) {
return nullptr; // tree empty return nullptr; // tree empty
}
if (less(p_key, prev->_key)) if (less(p_key, prev->_key)) {
prev = prev->_prev; prev = prev->_prev;
}
return prev; return prev;
} }
@ -302,11 +312,11 @@ private:
while (node != _data._nil) { while (node != _data._nil) {
new_parent = node; new_parent = node;
if (less(p_key, node->_key)) if (less(p_key, node->_key)) {
node = node->left; node = node->left;
else if (less(node->_key, p_key)) } else if (less(node->_key, p_key)) {
node = node->right; node = node->right;
else { } else {
node->_value = p_value; node->_value = p_value;
return node; // Return existing node with new value return node; // Return existing node with new value
} }
@ -328,10 +338,12 @@ private:
new_node->_next = _successor(new_node); new_node->_next = _successor(new_node);
new_node->_prev = _predecessor(new_node); new_node->_prev = _predecessor(new_node);
if (new_node->_next) if (new_node->_next) {
new_node->_next->_prev = new_node; new_node->_next->_prev = new_node;
if (new_node->_prev) }
if (new_node->_prev) {
new_node->_prev->_next = new_node; new_node->_prev->_next = new_node;
}
_data.size_cache++; _data.size_cache++;
_insert_rb_fix(new_node); _insert_rb_fix(new_node);
@ -426,10 +438,12 @@ private:
rp->right = p_node->right; rp->right = p_node->right;
rp->parent = p_node->parent; rp->parent = p_node->parent;
rp->color = p_node->color; rp->color = p_node->color;
if (p_node->left != _data._nil) if (p_node->left != _data._nil) {
p_node->left->parent = rp; p_node->left->parent = rp;
if (p_node->right != _data._nil) }
if (p_node->right != _data._nil) {
p_node->right->parent = rp; p_node->right->parent = rp;
}
if (p_node == p_node->parent->left) { if (p_node == p_node->parent->left) {
p_node->parent->left = rp; p_node->parent->left = rp;
@ -438,10 +452,12 @@ private:
} }
} }
if (p_node->_next) if (p_node->_next) {
p_node->_next->_prev = p_node->_prev; p_node->_next->_prev = p_node->_prev;
if (p_node->_prev) }
if (p_node->_prev) {
p_node->_prev->_next = p_node->_next; p_node->_prev->_next = p_node->_next;
}
memdelete_allocator<Element, A>(p_node); memdelete_allocator<Element, A>(p_node);
_data.size_cache--; _data.size_cache--;
@ -449,19 +465,22 @@ private:
} }
void _calculate_depth(Element *p_element, int &max_d, int d) const { void _calculate_depth(Element *p_element, int &max_d, int d) const {
if (p_element == _data._nil) if (p_element == _data._nil) {
return; return;
}
_calculate_depth(p_element->left, max_d, d + 1); _calculate_depth(p_element->left, max_d, d + 1);
_calculate_depth(p_element->right, max_d, d + 1); _calculate_depth(p_element->right, max_d, d + 1);
if (d > max_d) if (d > max_d) {
max_d = d; max_d = d;
}
} }
void _cleanup_tree(Element *p_element) { void _cleanup_tree(Element *p_element) {
if (p_element == _data._nil) if (p_element == _data._nil) {
return; return;
}
_cleanup_tree(p_element->left); _cleanup_tree(p_element->left);
_cleanup_tree(p_element->right); _cleanup_tree(p_element->right);
@ -478,32 +497,36 @@ private:
public: public:
const Element *find(const K &p_key) const { const Element *find(const K &p_key) const {
if (!_data._root) if (!_data._root) {
return nullptr; return nullptr;
}
const Element *res = _find(p_key); const Element *res = _find(p_key);
return res; return res;
} }
Element *find(const K &p_key) { Element *find(const K &p_key) {
if (!_data._root) if (!_data._root) {
return nullptr; return nullptr;
}
Element *res = _find(p_key); Element *res = _find(p_key);
return res; return res;
} }
const Element *find_closest(const K &p_key) const { const Element *find_closest(const K &p_key) const {
if (!_data._root) if (!_data._root) {
return nullptr; return nullptr;
}
const Element *res = _find_closest(p_key); const Element *res = _find_closest(p_key);
return res; return res;
} }
Element *find_closest(const K &p_key) { Element *find_closest(const K &p_key) {
if (!_data._root) if (!_data._root) {
return nullptr; return nullptr;
}
Element *res = _find_closest(p_key); Element *res = _find_closest(p_key);
return res; return res;
@ -514,31 +537,37 @@ public:
} }
Element *insert(const K &p_key, const V &p_value) { Element *insert(const K &p_key, const V &p_value) {
if (!_data._root) if (!_data._root) {
_data._create_root(); _data._create_root();
}
return _insert(p_key, p_value); return _insert(p_key, p_value);
} }
void erase(Element *p_element) { void erase(Element *p_element) {
if (!_data._root || !p_element) if (!_data._root || !p_element) {
return; return;
}
_erase(p_element); _erase(p_element);
if (_data.size_cache == 0 && _data._root) if (_data.size_cache == 0 && _data._root) {
_data._free_root(); _data._free_root();
}
} }
bool erase(const K &p_key) { bool erase(const K &p_key) {
if (!_data._root) if (!_data._root) {
return false; return false;
}
Element *e = find(p_key); Element *e = find(p_key);
if (!e) if (!e) {
return false; return false;
}
_erase(e); _erase(e);
if (_data.size_cache == 0 && _data._root) if (_data.size_cache == 0 && _data._root) {
_data._free_root(); _data._free_root();
}
return true; return true;
} }
@ -550,40 +579,48 @@ public:
} }
V &operator[](const K &p_key) { V &operator[](const K &p_key) {
if (!_data._root) if (!_data._root) {
_data._create_root(); _data._create_root();
}
Element *e = find(p_key); Element *e = find(p_key);
if (!e) if (!e) {
e = insert(p_key, V()); e = insert(p_key, V());
}
return e->_value; return e->_value;
} }
Element *front() const { Element *front() const {
if (!_data._root) if (!_data._root) {
return nullptr; return nullptr;
}
Element *e = _data._root->left; Element *e = _data._root->left;
if (e == _data._nil) if (e == _data._nil) {
return nullptr; return nullptr;
}
while (e->left != _data._nil) while (e->left != _data._nil) {
e = e->left; e = e->left;
}
return e; return e;
} }
Element *back() const { Element *back() const {
if (!_data._root) if (!_data._root) {
return nullptr; return nullptr;
}
Element *e = _data._root->left; Element *e = _data._root->left;
if (e == _data._nil) if (e == _data._nil) {
return nullptr; return nullptr;
}
while (e->right != _data._nil) while (e->right != _data._nil) {
e = e->right; e = e->right;
}
return e; return e;
} }
@ -593,8 +630,9 @@ public:
int calculate_depth() const { int calculate_depth() const {
// used for debug mostly // used for debug mostly
if (!_data._root) if (!_data._root) {
return 0; return 0;
}
int max_d = 0; int max_d = 0;
_calculate_depth(_data._root->left, max_d, 0); _calculate_depth(_data._root->left, max_d, 0);
@ -602,8 +640,9 @@ public:
} }
void clear() { void clear() {
if (!_data._root) if (!_data._root) {
return; return;
}
_cleanup_tree(_data._root->left); _cleanup_tree(_data._root->left);
_data._root->left = _data._nil; _data._root->left = _data._nil;

View File

@ -154,8 +154,9 @@ void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) {
} }
Segment s(p_id, p_with_id); Segment s(p_id, p_with_id);
if (bidirectional) if (bidirectional) {
s.direction = Segment::BIDIRECTIONAL; s.direction = Segment::BIDIRECTIONAL;
}
Set<Segment>::Element *element = segments.find(s); Set<Segment>::Element *element = segments.find(s);
if (element != nullptr) { if (element != nullptr) {
@ -197,15 +198,17 @@ void AStar::disconnect_points(int p_id, int p_with_id, bool bidirectional) {
b->unlinked_neighbours.remove(a->id); b->unlinked_neighbours.remove(a->id);
} }
} else { } else {
if (s.direction == Segment::NONE) if (s.direction == Segment::NONE) {
b->unlinked_neighbours.remove(a->id); b->unlinked_neighbours.remove(a->id);
else } else {
a->unlinked_neighbours.set(b->id, b); a->unlinked_neighbours.set(b->id, b);
}
} }
segments.erase(element); segments.erase(element);
if (s.direction != Segment::NONE) if (s.direction != Segment::NONE) {
segments.insert(s); segments.insert(s);
}
} }
} }
@ -273,8 +276,9 @@ int AStar::get_closest_point(const Vector3 &p_point, bool p_include_disabled) co
real_t closest_dist = 1e20; real_t closest_dist = 1e20;
for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) { for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
if (!p_include_disabled && !(*it.value)->enabled) if (!p_include_disabled && !(*it.value)->enabled) {
continue; // Disabled points should not be considered. continue; // Disabled points should not be considered.
}
real_t d = p_point.distance_squared_to((*it.value)->pos); real_t d = p_point.distance_squared_to((*it.value)->pos);
if (closest_id < 0 || d < closest_dist) { if (closest_id < 0 || d < closest_dist) {
@ -320,8 +324,9 @@ Vector3 AStar::get_closest_position_in_segment(const Vector3 &p_point) const {
bool AStar::_solve(Point *begin_point, Point *end_point) { bool AStar::_solve(Point *begin_point, Point *end_point) {
pass++; pass++;
if (!end_point->enabled) if (!end_point->enabled) {
return false; return false;
}
bool found_route = false; bool found_route = false;
@ -379,8 +384,9 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
} }
real_t AStar::_estimate_cost(int p_from_id, int p_to_id) { real_t AStar::_estimate_cost(int p_from_id, int p_to_id) {
if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost)) if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost)) {
return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id); return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id);
}
Point *from_point; Point *from_point;
bool from_exists = points.lookup(p_from_id, from_point); bool from_exists = points.lookup(p_from_id, from_point);
@ -394,8 +400,9 @@ real_t AStar::_estimate_cost(int p_from_id, int p_to_id) {
} }
real_t AStar::_compute_cost(int p_from_id, int p_to_id) { real_t AStar::_compute_cost(int p_from_id, int p_to_id) {
if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost)) if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost)) {
return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id); return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id);
}
Point *from_point; Point *from_point;
bool from_exists = points.lookup(p_from_id, from_point); bool from_exists = points.lookup(p_from_id, from_point);
@ -427,8 +434,9 @@ Vector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
Point *end_point = b; Point *end_point = b;
bool found_route = _solve(begin_point, end_point); bool found_route = _solve(begin_point, end_point);
if (!found_route) if (!found_route) {
return Vector<Vector3>(); return Vector<Vector3>();
}
Point *p = end_point; Point *p = end_point;
int pc = 1; // Begin point int pc = 1; // Begin point
@ -475,8 +483,9 @@ Vector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
Point *end_point = b; Point *end_point = b;
bool found_route = _solve(begin_point, end_point); bool found_route = _solve(begin_point, end_point);
if (!found_route) if (!found_route) {
return Vector<int>(); return Vector<int>();
}
Point *p = end_point; Point *p = end_point;
int pc = 1; // Begin point int pc = 1; // Begin point
@ -647,8 +656,9 @@ Vector2 AStar2D::get_closest_position_in_segment(const Vector2 &p_point) const {
} }
real_t AStar2D::_estimate_cost(int p_from_id, int p_to_id) { real_t AStar2D::_estimate_cost(int p_from_id, int p_to_id) {
if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost)) if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost)) {
return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id); return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id);
}
AStar::Point *from_point; AStar::Point *from_point;
bool from_exists = astar.points.lookup(p_from_id, from_point); bool from_exists = astar.points.lookup(p_from_id, from_point);
@ -662,8 +672,9 @@ real_t AStar2D::_estimate_cost(int p_from_id, int p_to_id) {
} }
real_t AStar2D::_compute_cost(int p_from_id, int p_to_id) { real_t AStar2D::_compute_cost(int p_from_id, int p_to_id) {
if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost)) if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost)) {
return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id); return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id);
}
AStar::Point *from_point; AStar::Point *from_point;
bool from_exists = astar.points.lookup(p_from_id, from_point); bool from_exists = astar.points.lookup(p_from_id, from_point);
@ -695,8 +706,9 @@ Vector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) {
AStar::Point *end_point = b; AStar::Point *end_point = b;
bool found_route = _solve(begin_point, end_point); bool found_route = _solve(begin_point, end_point);
if (!found_route) if (!found_route) {
return Vector<Vector2>(); return Vector<Vector2>();
}
AStar::Point *p = end_point; AStar::Point *p = end_point;
int pc = 1; // Begin point int pc = 1; // Begin point
@ -743,8 +755,9 @@ Vector<int> AStar2D::get_id_path(int p_from_id, int p_to_id) {
AStar::Point *end_point = b; AStar::Point *end_point = b;
bool found_route = _solve(begin_point, end_point); bool found_route = _solve(begin_point, end_point);
if (!found_route) if (!found_route) {
return Vector<int>(); return Vector<int>();
}
AStar::Point *p = end_point; AStar::Point *p = end_point;
int pc = 1; // Begin point int pc = 1; // Begin point
@ -775,8 +788,9 @@ Vector<int> AStar2D::get_id_path(int p_from_id, int p_to_id) {
bool AStar2D::_solve(AStar::Point *begin_point, AStar::Point *end_point) { bool AStar2D::_solve(AStar::Point *begin_point, AStar::Point *end_point) {
astar.pass++; astar.pass++;
if (!end_point->enabled) if (!end_point->enabled) {
return false; return false;
}
bool found_route = false; bool found_route = false;

View File

@ -78,23 +78,23 @@ AABB AABB::intersection(const AABB &p_aabb) const {
Vector3 min, max; Vector3 min, max;
if (src_min.x > dst_max.x || src_max.x < dst_min.x) if (src_min.x > dst_max.x || src_max.x < dst_min.x) {
return AABB(); return AABB();
else { } else {
min.x = (src_min.x > dst_min.x) ? src_min.x : dst_min.x; min.x = (src_min.x > dst_min.x) ? src_min.x : dst_min.x;
max.x = (src_max.x < dst_max.x) ? src_max.x : dst_max.x; max.x = (src_max.x < dst_max.x) ? src_max.x : dst_max.x;
} }
if (src_min.y > dst_max.y || src_max.y < dst_min.y) if (src_min.y > dst_max.y || src_max.y < dst_min.y) {
return AABB(); return AABB();
else { } else {
min.y = (src_min.y > dst_min.y) ? src_min.y : dst_min.y; min.y = (src_min.y > dst_min.y) ? src_min.y : dst_min.y;
max.y = (src_max.y < dst_max.y) ? src_max.y : dst_max.y; max.y = (src_max.y < dst_max.y) ? src_max.y : dst_max.y;
} }
if (src_min.z > dst_max.z || src_max.z < dst_min.z) if (src_min.z > dst_max.z || src_max.z < dst_min.z) {
return AABB(); return AABB();
else { } else {
min.z = (src_min.z > dst_min.z) ? src_min.z : dst_min.z; min.z = (src_min.z > dst_min.z) ? src_min.z : dst_min.z;
max.z = (src_max.z < dst_max.z) ? src_max.z : dst_max.z; max.z = (src_max.z < dst_max.z) ? src_max.z : dst_max.z;
} }
@ -134,8 +134,9 @@ bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *
} }
} }
if (r_clip) if (r_clip) {
*r_clip = c1; *r_clip = c1;
}
if (r_normal) { if (r_normal) {
*r_normal = Vector3(); *r_normal = Vector3();
(*r_normal)[axis] = p_dir[axis] ? -1 : 1; (*r_normal)[axis] = p_dir[axis] ? -1 : 1;
@ -158,16 +159,18 @@ bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector
real_t csign; real_t csign;
if (seg_from < seg_to) { if (seg_from < seg_to) {
if (seg_from > box_end || seg_to < box_begin) if (seg_from > box_end || seg_to < box_begin) {
return false; return false;
}
real_t length = seg_to - seg_from; real_t length = seg_to - seg_from;
cmin = (seg_from < box_begin) ? ((box_begin - seg_from) / length) : 0; cmin = (seg_from < box_begin) ? ((box_begin - seg_from) / length) : 0;
cmax = (seg_to > box_end) ? ((box_end - seg_from) / length) : 1; cmax = (seg_to > box_end) ? ((box_end - seg_from) / length) : 1;
csign = -1.0; csign = -1.0;
} else { } else {
if (seg_to > box_end || seg_from < box_begin) if (seg_to > box_end || seg_from < box_begin) {
return false; return false;
}
real_t length = seg_to - seg_from; real_t length = seg_to - seg_from;
cmin = (seg_from > box_end) ? (box_end - seg_from) / length : 0; cmin = (seg_from > box_end) ? (box_end - seg_from) / length : 0;
cmax = (seg_to < box_begin) ? (box_begin - seg_from) / length : 1; cmax = (seg_to < box_begin) ? (box_begin - seg_from) / length : 1;
@ -179,10 +182,12 @@ bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector
axis = i; axis = i;
sign = csign; sign = csign;
} }
if (cmax < max) if (cmax < max) {
max = cmax; max = cmax;
if (max < min) }
if (max < min) {
return false; return false;
}
} }
Vector3 rel = p_to - p_from; Vector3 rel = p_to - p_from;
@ -193,8 +198,9 @@ bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector
*r_normal = normal; *r_normal = normal;
} }
if (r_clip) if (r_clip) {
*r_clip = p_from + rel * min; *r_clip = p_from + rel * min;
}
return true; return true;
} }
@ -215,10 +221,11 @@ bool AABB::intersects_plane(const Plane &p_plane) const {
bool under = false; bool under = false;
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
if (p_plane.distance_to(points[i]) > 0) if (p_plane.distance_to(points[i]) > 0) {
over = true; over = true;
else } else {
under = true; under = true;
}
} }
return under && over; return under && over;

View File

@ -109,35 +109,47 @@ public:
}; };
inline bool AABB::intersects(const AABB &p_aabb) const { inline bool AABB::intersects(const AABB &p_aabb) const {
if (position.x >= (p_aabb.position.x + p_aabb.size.x)) if (position.x >= (p_aabb.position.x + p_aabb.size.x)) {
return false; return false;
if ((position.x + size.x) <= p_aabb.position.x) }
if ((position.x + size.x) <= p_aabb.position.x) {
return false; return false;
if (position.y >= (p_aabb.position.y + p_aabb.size.y)) }
if (position.y >= (p_aabb.position.y + p_aabb.size.y)) {
return false; return false;
if ((position.y + size.y) <= p_aabb.position.y) }
if ((position.y + size.y) <= p_aabb.position.y) {
return false; return false;
if (position.z >= (p_aabb.position.z + p_aabb.size.z)) }
if (position.z >= (p_aabb.position.z + p_aabb.size.z)) {
return false; return false;
if ((position.z + size.z) <= p_aabb.position.z) }
if ((position.z + size.z) <= p_aabb.position.z) {
return false; return false;
}
return true; return true;
} }
inline bool AABB::intersects_inclusive(const AABB &p_aabb) const { inline bool AABB::intersects_inclusive(const AABB &p_aabb) const {
if (position.x > (p_aabb.position.x + p_aabb.size.x)) if (position.x > (p_aabb.position.x + p_aabb.size.x)) {
return false; return false;
if ((position.x + size.x) < p_aabb.position.x) }
if ((position.x + size.x) < p_aabb.position.x) {
return false; return false;
if (position.y > (p_aabb.position.y + p_aabb.size.y)) }
if (position.y > (p_aabb.position.y + p_aabb.size.y)) {
return false; return false;
if ((position.y + size.y) < p_aabb.position.y) }
if ((position.y + size.y) < p_aabb.position.y) {
return false; return false;
if (position.z > (p_aabb.position.z + p_aabb.size.z)) }
if (position.z > (p_aabb.position.z + p_aabb.size.z)) {
return false; return false;
if ((position.z + size.z) < p_aabb.position.z) }
if ((position.z + size.z) < p_aabb.position.z) {
return false; return false;
}
return true; return true;
} }
@ -202,8 +214,9 @@ bool AABB::intersects_convex_shape(const Plane *p_planes, int p_plane_count, con
(p.normal.y > 0) ? -half_extents.y : half_extents.y, (p.normal.y > 0) ? -half_extents.y : half_extents.y,
(p.normal.z > 0) ? -half_extents.z : half_extents.z); (p.normal.z > 0) ? -half_extents.z : half_extents.z);
point += ofs; point += ofs;
if (p.is_point_over(point)) if (p.is_point_over(point)) {
return false; return false;
}
} }
// Make sure all points in the shape aren't fully separated from the AABB on // Make sure all points in the shape aren't fully separated from the AABB on
@ -243,26 +256,33 @@ bool AABB::inside_convex_shape(const Plane *p_planes, int p_plane_count) const {
(p.normal.y < 0) ? -half_extents.y : half_extents.y, (p.normal.y < 0) ? -half_extents.y : half_extents.y,
(p.normal.z < 0) ? -half_extents.z : half_extents.z); (p.normal.z < 0) ? -half_extents.z : half_extents.z);
point += ofs; point += ofs;
if (p.is_point_over(point)) if (p.is_point_over(point)) {
return false; return false;
}
} }
return true; return true;
} }
bool AABB::has_point(const Vector3 &p_point) const { bool AABB::has_point(const Vector3 &p_point) const {
if (p_point.x < position.x) if (p_point.x < position.x) {
return false; return false;
if (p_point.y < position.y) }
if (p_point.y < position.y) {
return false; return false;
if (p_point.z < position.z) }
if (p_point.z < position.z) {
return false; return false;
if (p_point.x > position.x + size.x) }
if (p_point.x > position.x + size.x) {
return false; return false;
if (p_point.y > position.y + size.y) }
if (p_point.y > position.y + size.y) {
return false; return false;
if (p_point.z > position.z + size.z) }
if (p_point.z > position.z + size.z) {
return false; return false;
}
return true; return true;
} }
@ -271,19 +291,25 @@ inline void AABB::expand_to(const Vector3 &p_vector) {
Vector3 begin = position; Vector3 begin = position;
Vector3 end = position + size; Vector3 end = position + size;
if (p_vector.x < begin.x) if (p_vector.x < begin.x) {
begin.x = p_vector.x; begin.x = p_vector.x;
if (p_vector.y < begin.y) }
if (p_vector.y < begin.y) {
begin.y = p_vector.y; begin.y = p_vector.y;
if (p_vector.z < begin.z) }
if (p_vector.z < begin.z) {
begin.z = p_vector.z; begin.z = p_vector.z;
}
if (p_vector.x > end.x) if (p_vector.x > end.x) {
end.x = p_vector.x; end.x = p_vector.x;
if (p_vector.y > end.y) }
if (p_vector.y > end.y) {
end.y = p_vector.y; end.y = p_vector.y;
if (p_vector.z > end.z) }
if (p_vector.z > end.z) {
end.z = p_vector.z; end.z = p_vector.z;
}
position = begin; position = begin;
size = end - begin; size = end - begin;
@ -348,12 +374,15 @@ bool AABB::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real
tymin = (upbound.y - p_from.y) * divy; tymin = (upbound.y - p_from.y) * divy;
tymax = (position.y - p_from.y) * divy; tymax = (position.y - p_from.y) * divy;
} }
if ((tmin > tymax) || (tymin > tmax)) if ((tmin > tymax) || (tymin > tmax)) {
return false; return false;
if (tymin > tmin) }
if (tymin > tmin) {
tmin = tymin; tmin = tymin;
if (tymax < tmax) }
if (tymax < tmax) {
tmax = tymax; tmax = tymax;
}
if (p_dir.z >= 0) { if (p_dir.z >= 0) {
tzmin = (position.z - p_from.z) * divz; tzmin = (position.z - p_from.z) * divz;
tzmax = (upbound.z - p_from.z) * divz; tzmax = (upbound.z - p_from.z) * divz;
@ -361,12 +390,15 @@ bool AABB::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real
tzmin = (upbound.z - p_from.z) * divz; tzmin = (upbound.z - p_from.z) * divz;
tzmax = (position.z - p_from.z) * divz; tzmax = (position.z - p_from.z) * divz;
} }
if ((tmin > tzmax) || (tzmin > tmax)) if ((tmin > tzmax) || (tzmin > tmax)) {
return false; return false;
if (tzmin > tmin) }
if (tzmin > tmin) {
tmin = tzmin; tmin = tzmin;
if (tzmax < tmax) }
if (tzmax < tmax) {
tmax = tzmax; tmax = tzmax;
}
return ((tmin < t1) && (tmax > t0)); return ((tmin < t1) && (tmax > t0));
} }

View File

@ -114,12 +114,15 @@ bool Basis::is_rotation() const {
} }
bool Basis::is_symmetric() const { bool Basis::is_symmetric() const {
if (!Math::is_equal_approx_ratio(elements[0][1], elements[1][0], UNIT_EPSILON)) if (!Math::is_equal_approx_ratio(elements[0][1], elements[1][0], UNIT_EPSILON)) {
return false; return false;
if (!Math::is_equal_approx_ratio(elements[0][2], elements[2][0], UNIT_EPSILON)) }
if (!Math::is_equal_approx_ratio(elements[0][2], elements[2][0], UNIT_EPSILON)) {
return false; return false;
if (!Math::is_equal_approx_ratio(elements[1][2], elements[2][1], UNIT_EPSILON)) }
if (!Math::is_equal_approx_ratio(elements[1][2], elements[2][1], UNIT_EPSILON)) {
return false; return false;
}
return true; return true;
} }
@ -555,8 +558,9 @@ bool Basis::is_equal_approx(const Basis &p_basis) const {
bool Basis::is_equal_approx_ratio(const Basis &a, const Basis &b, real_t p_epsilon) const { bool Basis::is_equal_approx_ratio(const Basis &a, const Basis &b, real_t p_epsilon) const {
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
if (!Math::is_equal_approx_ratio(a.elements[i][j], b.elements[i][j], p_epsilon)) if (!Math::is_equal_approx_ratio(a.elements[i][j], b.elements[i][j], p_epsilon)) {
return false; return false;
}
} }
} }
@ -566,8 +570,9 @@ bool Basis::is_equal_approx_ratio(const Basis &a, const Basis &b, real_t p_epsil
bool Basis::operator==(const Basis &p_matrix) const { bool Basis::operator==(const Basis &p_matrix) const {
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
if (elements[i][j] != p_matrix.elements[i][j]) if (elements[i][j] != p_matrix.elements[i][j]) {
return false; return false;
}
} }
} }
@ -582,8 +587,9 @@ Basis::operator String() const {
String mtx; String mtx;
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
if (i != 0 || j != 0) if (i != 0 || j != 0) {
mtx += ", "; mtx += ", ";
}
mtx += rtos(elements[i][j]); mtx += rtos(elements[i][j]);
} }
@ -661,20 +667,22 @@ int Basis::get_orthogonal_index() const {
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
real_t v = orth[i][j]; real_t v = orth[i][j];
if (v > 0.5) if (v > 0.5) {
v = 1.0; v = 1.0;
else if (v < -0.5) } else if (v < -0.5) {
v = -1.0; v = -1.0;
else } else {
v = 0; v = 0;
}
orth[i][j] = v; orth[i][j] = v;
} }
} }
for (int i = 0; i < 24; i++) { for (int i = 0; i < 24; i++) {
if (_ortho_bases[i] == orth) if (_ortho_bases[i] == orth) {
return i; return i;
}
} }
return 0; return 0;
@ -754,8 +762,9 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
real_t s = Math::sqrt((elements[1][2] - elements[2][1]) * (elements[1][2] - elements[2][1]) + (elements[2][0] - elements[0][2]) * (elements[2][0] - elements[0][2]) + (elements[0][1] - elements[1][0]) * (elements[0][1] - elements[1][0])); // s=|axis||sin(angle)|, used to normalise real_t s = Math::sqrt((elements[1][2] - elements[2][1]) * (elements[1][2] - elements[2][1]) + (elements[2][0] - elements[0][2]) * (elements[2][0] - elements[0][2]) + (elements[0][1] - elements[1][0]) * (elements[0][1] - elements[1][0])); // s=|axis||sin(angle)|, used to normalise
angle = Math::acos((elements[0][0] + elements[1][1] + elements[2][2] - 1) / 2); angle = Math::acos((elements[0][0] + elements[1][1] + elements[2][2] - 1) / 2);
if (angle < 0) if (angle < 0) {
s = -s; s = -s;
}
x = (elements[2][1] - elements[1][2]) / s; x = (elements[2][1] - elements[1][2]) / s;
y = (elements[0][2] - elements[2][0]) / s; y = (elements[0][2] - elements[2][0]) / s;
z = (elements[1][0] - elements[0][1]) / s; z = (elements[1][0] - elements[0][1]) / s;

View File

@ -469,23 +469,26 @@ void CameraMatrix::invert() {
/** Divide column by minus pivot value **/ /** Divide column by minus pivot value **/
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (i != k) if (i != k) {
matrix[i][k] /= (-pvt_val); matrix[i][k] /= (-pvt_val);
}
} }
/** Reduce the matrix **/ /** Reduce the matrix **/
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
hold = matrix[i][k]; hold = matrix[i][k];
for (j = 0; j < 4; j++) { for (j = 0; j < 4; j++) {
if (i != k && j != k) if (i != k && j != k) {
matrix[i][j] += hold * matrix[k][j]; matrix[i][j] += hold * matrix[k][j];
}
} }
} }
/** Divide row by pivot **/ /** Divide row by pivot **/
for (j = 0; j < 4; j++) { for (j = 0; j < 4; j++) {
if (j != k) if (j != k) {
matrix[k][j] /= pvt_val; matrix[k][j] /= pvt_val;
}
} }
/** Replace pivot by reciprocal (at last we can touch it). **/ /** Replace pivot by reciprocal (at last we can touch it). **/
@ -505,12 +508,13 @@ void CameraMatrix::invert() {
} }
j = pvt_i[k]; /* Columns to swap correspond to pivot ROW */ j = pvt_i[k]; /* Columns to swap correspond to pivot ROW */
if (j != k) /* If columns are different */ if (j != k) { /* If columns are different */
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
hold = matrix[i][k]; hold = matrix[i][k];
matrix[i][k] = -matrix[i][j]; matrix[i][k] = -matrix[i][j];
matrix[i][j] = hold; matrix[i][j] = hold;
} }
}
} }
} }
@ -530,8 +534,9 @@ CameraMatrix CameraMatrix::operator*(const CameraMatrix &p_matrix) const {
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
real_t ab = 0; real_t ab = 0;
for (int k = 0; k < 4; k++) for (int k = 0; k < 4; k++) {
ab += matrix[k][i] * p_matrix.matrix[j][k]; ab += matrix[k][i] * p_matrix.matrix[j][k];
}
new_matrix.matrix[j][i] = ab; new_matrix.matrix[j][i] = ab;
} }
} }
@ -604,9 +609,11 @@ void CameraMatrix::set_light_atlas_rect(const Rect2 &p_rect) {
CameraMatrix::operator String() const { CameraMatrix::operator String() const {
String str; String str;
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) for (int j = 0; j < 4; j++) {
str += String((j > 0) ? ", " : "\n") + rtos(matrix[i][j]); str += String((j > 0) ? ", " : "\n") + rtos(matrix[i][j]);
}
}
return str; return str;
} }

View File

@ -81,12 +81,15 @@ class Delaunay3D {
_FORCE_INLINE_ Triangle() {} _FORCE_INLINE_ Triangle() {}
_FORCE_INLINE_ Triangle(uint32_t p_a, uint32_t p_b, uint32_t p_c) { _FORCE_INLINE_ Triangle(uint32_t p_a, uint32_t p_b, uint32_t p_c) {
if (p_a > p_b) if (p_a > p_b) {
SWAP(p_a, p_b); SWAP(p_a, p_b);
if (p_b > p_c) }
if (p_b > p_c) {
SWAP(p_b, p_c); SWAP(p_b, p_c);
if (p_a > p_b) }
if (p_a > p_b) {
SWAP(p_a, p_b); SWAP(p_a, p_b);
}
triangle[0] = p_a; triangle[0] = p_a;
triangle[1] = p_b; triangle[1] = p_b;

View File

@ -109,8 +109,9 @@ void DisjointSet<T, C, AL>::create_union(T a, T b) {
Element *y_root = get_parent(y); Element *y_root = get_parent(y);
// Already in the same set // Already in the same set
if (x_root == y_root) if (x_root == y_root) {
return; return;
}
// Not in the same set, merge // Not in the same set, merge
if (x_root->rank < y_root->rank) { if (x_root->rank < y_root->rank) {

View File

@ -111,8 +111,9 @@ const char *Expression::func_name[Expression::FUNC_MAX] = {
Expression::BuiltinFunc Expression::find_function(const String &p_string) { Expression::BuiltinFunc Expression::find_function(const String &p_string) {
for (int i = 0; i < FUNC_MAX; i++) { for (int i = 0; i < FUNC_MAX; i++) {
if (p_string == func_name[i]) if (p_string == func_name[i]) {
return BuiltinFunc(i); return BuiltinFunc(i);
}
} }
return FUNC_MAX; return FUNC_MAX;
@ -1036,8 +1037,9 @@ Error Expression::_get_token(Token &r_token) {
exp_beg = true; exp_beg = true;
} else if ((c == '-' || c == '+') && !exp_sign && !exp_beg) { } else if ((c == '-' || c == '+') && !exp_sign && !exp_beg) {
if (c == '-') if (c == '-') {
is_float = true; is_float = true;
}
exp_sign = true; exp_sign = true;
} else { } else {
@ -1046,8 +1048,9 @@ Error Expression::_get_token(Token &r_token) {
} break; } break;
} }
if (reading == READING_DONE) if (reading == READING_DONE) {
break; break;
}
num += String::chr(c); num += String::chr(c);
c = GET_CHAR(); c = GET_CHAR();
} }
@ -1056,10 +1059,11 @@ Error Expression::_get_token(Token &r_token) {
r_token.type = TK_CONSTANT; r_token.type = TK_CONSTANT;
if (is_float) if (is_float) {
r_token.value = num.to_double(); r_token.value = num.to_double();
else } else {
r_token.value = num.to_int64(); r_token.value = num.to_int64();
}
return OK; return OK;
} else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') { } else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') {
@ -1196,8 +1200,9 @@ Expression::ENode *Expression::_parse_expression() {
Token tk; Token tk;
_get_token(tk); _get_token(tk);
if (error_set) if (error_set) {
return nullptr; return nullptr;
}
switch (tk.type) { switch (tk.type) {
case TK_CURLY_BRACKET_OPEN: { case TK_CURLY_BRACKET_OPEN: {
@ -1213,8 +1218,9 @@ Expression::ENode *Expression::_parse_expression() {
str_ofs = cofs; //revert str_ofs = cofs; //revert
//parse an expression //parse an expression
ENode *subexpr = _parse_expression(); ENode *subexpr = _parse_expression();
if (!subexpr) if (!subexpr) {
return nullptr; return nullptr;
}
dn->dict.push_back(subexpr); dn->dict.push_back(subexpr);
_get_token(tk); _get_token(tk);
@ -1224,8 +1230,9 @@ Expression::ENode *Expression::_parse_expression() {
} }
subexpr = _parse_expression(); subexpr = _parse_expression();
if (!subexpr) if (!subexpr) {
return nullptr; return nullptr;
}
dn->dict.push_back(subexpr); dn->dict.push_back(subexpr);
@ -1256,8 +1263,9 @@ Expression::ENode *Expression::_parse_expression() {
str_ofs = cofs; //revert str_ofs = cofs; //revert
//parse an expression //parse an expression
ENode *subexpr = _parse_expression(); ENode *subexpr = _parse_expression();
if (!subexpr) if (!subexpr) {
return nullptr; return nullptr;
}
an->array.push_back(subexpr); an->array.push_back(subexpr);
cofs = str_ofs; cofs = str_ofs;
@ -1276,8 +1284,9 @@ Expression::ENode *Expression::_parse_expression() {
case TK_PARENTHESIS_OPEN: { case TK_PARENTHESIS_OPEN: {
//a suexpression //a suexpression
ENode *e = _parse_expression(); ENode *e = _parse_expression();
if (error_set) if (error_set) {
return nullptr; return nullptr;
}
_get_token(tk); _get_token(tk);
if (tk.type != TK_PARENTHESIS_CLOSE) { if (tk.type != TK_PARENTHESIS_CLOSE) {
_set_error("Expected ')'"); _set_error("Expected ')'");
@ -1308,8 +1317,9 @@ Expression::ENode *Expression::_parse_expression() {
str_ofs = cofs2; //revert str_ofs = cofs2; //revert
//parse an expression //parse an expression
ENode *subexpr = _parse_expression(); ENode *subexpr = _parse_expression();
if (!subexpr) if (!subexpr) {
return nullptr; return nullptr;
}
func_call->arguments.push_back(subexpr); func_call->arguments.push_back(subexpr);
@ -1386,8 +1396,9 @@ Expression::ENode *Expression::_parse_expression() {
str_ofs = cofs; //revert str_ofs = cofs; //revert
//parse an expression //parse an expression
ENode *subexpr = _parse_expression(); ENode *subexpr = _parse_expression();
if (!subexpr) if (!subexpr) {
return nullptr; return nullptr;
}
constructor->arguments.push_back(subexpr); constructor->arguments.push_back(subexpr);
@ -1426,8 +1437,9 @@ Expression::ENode *Expression::_parse_expression() {
str_ofs = cofs; //revert str_ofs = cofs; //revert
//parse an expression //parse an expression
ENode *subexpr = _parse_expression(); ENode *subexpr = _parse_expression();
if (!subexpr) if (!subexpr) {
return nullptr; return nullptr;
}
bifunc->arguments.push_back(subexpr); bifunc->arguments.push_back(subexpr);
@ -1476,8 +1488,9 @@ Expression::ENode *Expression::_parse_expression() {
while (true) { while (true) {
int cofs2 = str_ofs; int cofs2 = str_ofs;
_get_token(tk); _get_token(tk);
if (error_set) if (error_set) {
return nullptr; return nullptr;
}
bool done = false; bool done = false;
@ -1489,8 +1502,9 @@ Expression::ENode *Expression::_parse_expression() {
index->base = expr; index->base = expr;
ENode *what = _parse_expression(); ENode *what = _parse_expression();
if (!what) if (!what) {
return nullptr; return nullptr;
}
index->index = what; index->index = what;
@ -1529,8 +1543,9 @@ Expression::ENode *Expression::_parse_expression() {
str_ofs = cofs3; //revert str_ofs = cofs3; //revert
//parse an expression //parse an expression
ENode *subexpr = _parse_expression(); ENode *subexpr = _parse_expression();
if (!subexpr) if (!subexpr) {
return nullptr; return nullptr;
}
func_call->arguments.push_back(subexpr); func_call->arguments.push_back(subexpr);
@ -1563,8 +1578,9 @@ Expression::ENode *Expression::_parse_expression() {
} break; } break;
} }
if (done) if (done) {
break; break;
}
} }
//push expression //push expression
@ -1579,8 +1595,9 @@ Expression::ENode *Expression::_parse_expression() {
int cofs = str_ofs; int cofs = str_ofs;
_get_token(tk); _get_token(tk);
if (error_set) if (error_set) {
return nullptr; return nullptr;
}
Variant::Operator op = Variant::OP_MAX; Variant::Operator op = Variant::OP_MAX;
@ -1843,8 +1860,9 @@ Expression::ENode *Expression::_parse_expression() {
} }
bool Expression::_compile_expression() { bool Expression::_compile_expression() {
if (!expression_dirty) if (!expression_dirty) {
return error_set; return error_set;
}
if (nodes) { if (nodes) {
memdelete(nodes); memdelete(nodes);
@ -1898,15 +1916,17 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
Variant a; Variant a;
bool ret = _execute(p_inputs, p_instance, op->nodes[0], a, r_error_str); bool ret = _execute(p_inputs, p_instance, op->nodes[0], a, r_error_str);
if (ret) if (ret) {
return true; return true;
}
Variant b; Variant b;
if (op->nodes[1]) { if (op->nodes[1]) {
ret = _execute(p_inputs, p_instance, op->nodes[1], b, r_error_str); ret = _execute(p_inputs, p_instance, op->nodes[1], b, r_error_str);
if (ret) if (ret) {
return true; return true;
}
} }
bool valid = true; bool valid = true;
@ -1922,14 +1942,16 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
Variant base; Variant base;
bool ret = _execute(p_inputs, p_instance, index->base, base, r_error_str); bool ret = _execute(p_inputs, p_instance, index->base, base, r_error_str);
if (ret) if (ret) {
return true; return true;
}
Variant idx; Variant idx;
ret = _execute(p_inputs, p_instance, index->index, idx, r_error_str); ret = _execute(p_inputs, p_instance, index->index, idx, r_error_str);
if (ret) if (ret) {
return true; return true;
}
bool valid; bool valid;
r_ret = base.get(idx, &valid); r_ret = base.get(idx, &valid);
@ -1944,8 +1966,9 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
Variant base; Variant base;
bool ret = _execute(p_inputs, p_instance, index->base, base, r_error_str); bool ret = _execute(p_inputs, p_instance, index->base, base, r_error_str);
if (ret) if (ret) {
return true; return true;
}
bool valid; bool valid;
r_ret = base.get_named(index->name, &valid); r_ret = base.get_named(index->name, &valid);
@ -1964,8 +1987,9 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
Variant value; Variant value;
bool ret = _execute(p_inputs, p_instance, array->array[i], value, r_error_str); bool ret = _execute(p_inputs, p_instance, array->array[i], value, r_error_str);
if (ret) if (ret) {
return true; return true;
}
arr[i] = value; arr[i] = value;
} }
@ -1980,13 +2004,15 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
Variant key; Variant key;
bool ret = _execute(p_inputs, p_instance, dictionary->dict[i + 0], key, r_error_str); bool ret = _execute(p_inputs, p_instance, dictionary->dict[i + 0], key, r_error_str);
if (ret) if (ret) {
return true; return true;
}
Variant value; Variant value;
ret = _execute(p_inputs, p_instance, dictionary->dict[i + 1], value, r_error_str); ret = _execute(p_inputs, p_instance, dictionary->dict[i + 1], value, r_error_str);
if (ret) if (ret) {
return true; return true;
}
d[key] = value; d[key] = value;
} }
@ -2005,8 +2031,9 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
Variant value; Variant value;
bool ret = _execute(p_inputs, p_instance, constructor->arguments[i], value, r_error_str); bool ret = _execute(p_inputs, p_instance, constructor->arguments[i], value, r_error_str);
if (ret) if (ret) {
return true; return true;
}
arr.write[i] = value; arr.write[i] = value;
argp.write[i] = &arr[i]; argp.write[i] = &arr[i];
} }
@ -2031,8 +2058,9 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
for (int i = 0; i < bifunc->arguments.size(); i++) { for (int i = 0; i < bifunc->arguments.size(); i++) {
Variant value; Variant value;
bool ret = _execute(p_inputs, p_instance, bifunc->arguments[i], value, r_error_str); bool ret = _execute(p_inputs, p_instance, bifunc->arguments[i], value, r_error_str);
if (ret) if (ret) {
return true; return true;
}
arr.write[i] = value; arr.write[i] = value;
argp.write[i] = &arr[i]; argp.write[i] = &arr[i];
} }
@ -2052,8 +2080,9 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
Variant base; Variant base;
bool ret = _execute(p_inputs, p_instance, call->base, base, r_error_str); bool ret = _execute(p_inputs, p_instance, call->base, base, r_error_str);
if (ret) if (ret) {
return true; return true;
}
Vector<Variant> arr; Vector<Variant> arr;
Vector<const Variant *> argp; Vector<const Variant *> argp;
@ -2064,8 +2093,9 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
Variant value; Variant value;
ret = _execute(p_inputs, p_instance, call->arguments[i], value, r_error_str); ret = _execute(p_inputs, p_instance, call->arguments[i], value, r_error_str);
if (ret) if (ret) {
return true; return true;
}
arr.write[i] = value; arr.write[i] = value;
argp.write[i] = &arr[i]; argp.write[i] = &arr[i];
} }

View File

@ -184,8 +184,9 @@ private:
}; };
void _set_error(const String &p_err) { void _set_error(const String &p_err) {
if (error_set) if (error_set) {
return; return;
}
error_str = p_err; error_str = p_err;
error_set = true; error_set = true;
} }

View File

@ -64,8 +64,9 @@ int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_
/* Check for Intersection between this and the next vertex*/ /* Check for Intersection between this and the next vertex*/
Vector3 inters; Vector3 inters;
if (!p_plane.intersects_segment(vertex[i], vertex[(i + 1) % 3], &inters)) if (!p_plane.intersects_segment(vertex[i], vertex[(i + 1) % 3], &inters)) {
continue; continue;
}
/* Intersection goes to both */ /* Intersection goes to both */
ERR_FAIL_COND_V(above_count >= 4, 0); ERR_FAIL_COND_V(above_count >= 4, 0);
@ -127,23 +128,26 @@ Face3::Side Face3::get_side_of(const Face3 &p_face, ClockDirection p_clock_dir)
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
const Vector3 &v = p_face.vertex[i]; const Vector3 &v = p_face.vertex[i];
if (plane.has_point(v)) //coplanar, don't bother if (plane.has_point(v)) { //coplanar, don't bother
continue; continue;
}
if (plane.is_point_over(v)) if (plane.is_point_over(v)) {
over++; over++;
else } else {
under++; under++;
}
} }
if (over > 0 && under == 0) if (over > 0 && under == 0) {
return SIDE_OVER; return SIDE_OVER;
else if (under > 0 && over == 0) } else if (under > 0 && over == 0) {
return SIDE_UNDER; return SIDE_UNDER;
else if (under == 0 && over == 0) } else if (under == 0 && over == 0) {
return SIDE_COPLANAR; return SIDE_COPLANAR;
else } else {
return SIDE_SPANNING; return SIDE_SPANNING;
}
} }
Vector3 Face3::get_random_point_inside() const { Vector3 Face3::get_random_point_inside() const {
@ -176,8 +180,9 @@ ClockDirection Face3::get_clock_dir() const {
bool Face3::intersects_aabb(const AABB &p_aabb) const { bool Face3::intersects_aabb(const AABB &p_aabb) const {
/** TEST PLANE **/ /** TEST PLANE **/
if (!p_aabb.intersects_plane(get_plane())) if (!p_aabb.intersects_plane(get_plane())) {
return false; return false;
}
#define TEST_AXIS(m_ax) \ #define TEST_AXIS(m_ax) \
/** TEST FACE AXIS */ \ /** TEST FACE AXIS */ \
@ -218,16 +223,18 @@ bool Face3::intersects_aabb(const AABB &p_aabb) const {
Vector3 axis = vec3_cross(e1, e2); Vector3 axis = vec3_cross(e1, e2);
if (axis.length_squared() < 0.0001) if (axis.length_squared() < 0.0001) {
continue; // coplanar continue; // coplanar
}
axis.normalize(); axis.normalize();
real_t minA, maxA, minB, maxB; real_t minA, maxA, minB, maxB;
p_aabb.project_range_in_plane(Plane(axis, 0), minA, maxA); p_aabb.project_range_in_plane(Plane(axis, 0), minA, maxA);
project_range(axis, Transform(), minB, maxB); project_range(axis, Transform(), minB, maxB);
if (maxA < minB || maxB < minA) if (maxA < minB || maxB < minA) {
return false; return false;
}
} }
} }
return true; return true;
@ -242,11 +249,13 @@ void Face3::project_range(const Vector3 &p_normal, const Transform &p_transform,
Vector3 v = p_transform.xform(vertex[i]); Vector3 v = p_transform.xform(vertex[i]);
real_t d = p_normal.dot(v); real_t d = p_normal.dot(v);
if (i == 0 || d > r_max) if (i == 0 || d > r_max) {
r_max = d; r_max = d;
}
if (i == 0 || d < r_min) if (i == 0 || d < r_min) {
r_min = d; r_min = d;
}
} }
} }
@ -254,8 +263,9 @@ void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, V
#define _FACE_IS_VALID_SUPPORT_THRESHOLD 0.98 #define _FACE_IS_VALID_SUPPORT_THRESHOLD 0.98
#define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.05 #define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.05
if (p_max <= 0) if (p_max <= 0) {
return; return;
}
Vector3 n = p_transform.basis.xform_inv(p_normal); Vector3 n = p_transform.basis.xform_inv(p_normal);
@ -287,8 +297,9 @@ void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, V
/** TEST EDGES AS SUPPORT **/ /** TEST EDGES AS SUPPORT **/
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
if (i != vert_support_idx && i + 1 != vert_support_idx) if (i != vert_support_idx && i + 1 != vert_support_idx) {
continue; continue;
}
// check if edge is valid as a support // check if edge is valid as a support
real_t dot = (vertex[i] - vertex[(i + 1) % 3]).normalized().dot(n); real_t dot = (vertex[i] - vertex[(i + 1) % 3]).normalized().dot(n);
@ -296,8 +307,9 @@ void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, V
if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD) {
*p_count = MIN(2, p_max); *p_count = MIN(2, p_max);
for (int j = 0; j < *p_count; j++) for (int j = 0; j < *p_count; j++) {
p_vertices[j] = p_transform.xform(vertex[(j + i) % 3]); p_vertices[j] = p_transform.xform(vertex[(j + i) % 3]);
}
return; return;
} }

View File

@ -111,8 +111,9 @@ bool Face3::intersects_aabb2(const AABB &p_aabb) const {
real_t dist_a = perp.dot(ofs + sup) - d; real_t dist_a = perp.dot(ofs + sup) - d;
real_t dist_b = perp.dot(ofs - sup) - d; real_t dist_b = perp.dot(ofs - sup) - d;
if (dist_a * dist_b > 0) if (dist_a * dist_b > 0) {
return false; //does not intersect the plane return false; //does not intersect the plane
}
#define TEST_AXIS(m_ax) \ #define TEST_AXIS(m_ax) \
{ \ { \
@ -209,8 +210,9 @@ bool Face3::intersects_aabb2(const AABB &p_aabb) const {
Vector3 axis = vec3_cross(e1, e2); Vector3 axis = vec3_cross(e1, e2);
if (axis.length_squared() < 0.0001) if (axis.length_squared() < 0.0001) {
continue; // coplanar continue; // coplanar
}
//axis.normalize(); //axis.normalize();
Vector3 sup2 = Vector3( Vector3 sup2 = Vector3(
@ -228,15 +230,18 @@ bool Face3::intersects_aabb2(const AABB &p_aabb) const {
for (int k = 0; k < 3; k++) { for (int k = 0; k < 3; k++) {
real_t vert_d = axis.dot(vertex[k]); real_t vert_d = axis.dot(vertex[k]);
if (vert_d > maxT) if (vert_d > maxT) {
maxT = vert_d; maxT = vert_d;
}
if (vert_d < minT) if (vert_d < minT) {
minT = vert_d; minT = vert_d;
}
} }
if (maxB < minT || maxT < minB) if (maxB < minT || maxT < minB) {
return false; return false;
}
} }
} }
return true; return true;

View File

@ -90,8 +90,9 @@ void Geometry::MeshData::optimize_vertices() {
new_vertices.resize(vtx_remap.size()); new_vertices.resize(vtx_remap.size());
for (int i = 0; i < vertices.size(); i++) { for (int i = 0; i < vertices.size(); i++) {
if (vtx_remap.has(i)) if (vtx_remap.has(i)) {
new_vertices.write[vtx_remap[i]] = vertices[i]; new_vertices.write[vtx_remap[i]] = vertices[i];
}
} }
vertices = new_vertices; vertices = new_vertices;
} }
@ -126,11 +127,13 @@ static bool _connect_faces(_FaceClassify *p_faces, int len, int p_group) {
} }
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (p_faces[i].group != p_group) if (p_faces[i].group != p_group) {
continue; continue;
}
for (int j = i + 1; j < len; j++) { for (int j = i + 1; j < len; j++) {
if (p_faces[j].group != p_group) if (p_faces[j].group != p_group) {
continue; continue;
}
for (int k = 0; k < 3; k++) { for (int k = 0; k < 3; k++) {
Vector3 vi1 = p_faces[i].face.vertex[k]; Vector3 vi1 = p_faces[i].face.vertex[k];
@ -159,29 +162,34 @@ static bool _connect_faces(_FaceClassify *p_faces, int len, int p_group) {
p_faces[j].links[l].edge = k; p_faces[j].links[l].edge = k;
} }
} }
if (error) if (error) {
break; break;
}
} }
if (error) if (error) {
break; break;
}
} }
if (error) if (error) {
break; break;
}
} }
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
p_faces[i].valid = true; p_faces[i].valid = true;
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
if (p_faces[i].links[j].face == -1) if (p_faces[i].links[j].face == -1) {
p_faces[i].valid = false; p_faces[i].valid = false;
}
} }
} }
return error; return error;
} }
static bool _group_face(_FaceClassify *p_faces, int len, int p_index, int p_group) { static bool _group_face(_FaceClassify *p_faces, int len, int p_index, int p_group) {
if (p_faces[p_index].group >= 0) if (p_faces[p_index].group >= 0) {
return false; return false;
}
p_faces[p_index].group = p_group; p_faces[p_index].group = p_group;
@ -218,8 +226,9 @@ Vector<Vector<Face3>> Geometry::separate_objects(Vector<Face3> p_array) {
int group = 0; int group = 0;
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (!_fcptr[i].valid) if (!_fcptr[i].valid) {
continue; continue;
}
if (_group_face(_fcptr, len, i, group)) { if (_group_face(_fcptr, len, i, group)) {
group++; group++;
} }
@ -236,8 +245,9 @@ Vector<Vector<Face3>> Geometry::separate_objects(Vector<Face3> p_array) {
Vector<Face3> *group_faces = objects.ptrw(); Vector<Face3> *group_faces = objects.ptrw();
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (!_fcptr[i].valid) if (!_fcptr[i].valid) {
continue; continue;
}
if (_fcptr[i].group >= 0 && _fcptr[i].group < group) { if (_fcptr[i].group >= 0 && _fcptr[i].group < group) {
group_faces[_fcptr[i].group].push_back(_fcptr[i].face); group_faces[_fcptr[i].group].push_back(_fcptr[i].face);
} }
@ -279,8 +289,9 @@ static inline void _plot_face(uint8_t ***p_cell_status, int x, int y, int z, int
aabb.position = aabb.position * voxelsize; aabb.position = aabb.position * voxelsize;
aabb.size = aabb.size * voxelsize; aabb.size = aabb.size * voxelsize;
if (!p_face.intersects_aabb(aabb)) if (!p_face.intersects_aabb(aabb)) {
return; return;
}
if (len_x == 1 && len_y == 1 && len_z == 1) { if (len_x == 1 && len_y == 1 && len_z == 1) {
p_cell_status[x][y][z] = _CELL_SOLID; p_cell_status[x][y][z] = _CELL_SOLID;
@ -326,8 +337,9 @@ static inline void _plot_face(uint8_t ***p_cell_status, int x, int y, int z, int
} }
static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z) { static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z) {
if (p_cell_status[x][y][z] & 3) if (p_cell_status[x][y][z] & 3) {
return; // Nothing to do, already used and/or visited. return; // Nothing to do, already used and/or visited.
}
p_cell_status[x][y][z] = _CELL_PREV_FIRST; p_cell_status[x][y][z] = _CELL_PREV_FIRST;
@ -413,15 +425,19 @@ static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z,
ERR_FAIL(); ERR_FAIL();
} }
if (next_x < 0 || next_x >= len_x) if (next_x < 0 || next_x >= len_x) {
continue; continue;
if (next_y < 0 || next_y >= len_y) }
if (next_y < 0 || next_y >= len_y) {
continue; continue;
if (next_z < 0 || next_z >= len_z) }
if (next_z < 0 || next_z >= len_z) {
continue; continue;
}
if (p_cell_status[next_x][next_y][next_z] & 3) if (p_cell_status[next_x][next_y][next_z] & 3) {
continue; continue;
}
x = next_x; x = next_x;
y = next_y; y = next_y;
@ -435,8 +451,9 @@ static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, i
ERR_FAIL_INDEX(y, len_y); ERR_FAIL_INDEX(y, len_y);
ERR_FAIL_INDEX(z, len_z); ERR_FAIL_INDEX(z, len_z);
if (p_cell_status[x][y][z] & _CELL_EXTERIOR) if (p_cell_status[x][y][z] & _CELL_EXTERIOR) {
return; return;
}
#define vert(m_idx) Vector3(((m_idx)&4) >> 2, ((m_idx)&2) >> 1, (m_idx)&1) #define vert(m_idx) Vector3(((m_idx)&4) >> 2, ((m_idx)&2) >> 1, (m_idx)&1)
@ -458,21 +475,27 @@ static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, i
bool plot = false; bool plot = false;
if (disp_x < 0 || disp_x >= len_x) if (disp_x < 0 || disp_x >= len_x) {
plot = true; plot = true;
if (disp_y < 0 || disp_y >= len_y) }
if (disp_y < 0 || disp_y >= len_y) {
plot = true; plot = true;
if (disp_z < 0 || disp_z >= len_z) }
if (disp_z < 0 || disp_z >= len_z) {
plot = true; plot = true;
}
if (!plot && (p_cell_status[disp_x][disp_y][disp_z] & _CELL_EXTERIOR)) if (!plot && (p_cell_status[disp_x][disp_y][disp_z] & _CELL_EXTERIOR)) {
plot = true; plot = true;
}
if (!plot) if (!plot) {
continue; continue;
}
for (int j = 0; j < 4; j++) for (int j = 0; j < 4; j++) {
face_points[j] = vert(indices[i][j]) + Vector3(x, y, z); face_points[j] = vert(indices[i][j]) + Vector3(x, y, z);
}
p_faces.push_back( p_faces.push_back(
Face3( Face3(
@ -510,20 +533,23 @@ Vector<Face3> Geometry::wrap_geometry(Vector<Face3> p_array, real_t *p_error) {
// Determine amount of cells in grid axis. // Determine amount of cells in grid axis.
int div_x, div_y, div_z; int div_x, div_y, div_z;
if (global_aabb.size.x / _MIN_SIZE < _MAX_LENGTH) if (global_aabb.size.x / _MIN_SIZE < _MAX_LENGTH) {
div_x = (int)(global_aabb.size.x / _MIN_SIZE) + 1; div_x = (int)(global_aabb.size.x / _MIN_SIZE) + 1;
else } else {
div_x = _MAX_LENGTH; div_x = _MAX_LENGTH;
}
if (global_aabb.size.y / _MIN_SIZE < _MAX_LENGTH) if (global_aabb.size.y / _MIN_SIZE < _MAX_LENGTH) {
div_y = (int)(global_aabb.size.y / _MIN_SIZE) + 1; div_y = (int)(global_aabb.size.y / _MIN_SIZE) + 1;
else } else {
div_y = _MAX_LENGTH; div_y = _MAX_LENGTH;
}
if (global_aabb.size.z / _MIN_SIZE < _MAX_LENGTH) if (global_aabb.size.z / _MIN_SIZE < _MAX_LENGTH) {
div_z = (int)(global_aabb.size.z / _MIN_SIZE) + 1; div_z = (int)(global_aabb.size.z / _MIN_SIZE) + 1;
else } else {
div_z = _MAX_LENGTH; div_z = _MAX_LENGTH;
}
Vector3 voxelsize = global_aabb.size; Vector3 voxelsize = global_aabb.size;
voxelsize.x /= div_x; voxelsize.x /= div_x;
@ -614,8 +640,9 @@ Vector<Face3> Geometry::wrap_geometry(Vector<Face3> p_array, real_t *p_error) {
} }
memdelete_arr(cell_status); memdelete_arr(cell_status);
if (p_error) if (p_error) {
*p_error = voxelsize.length(); *p_error = voxelsize.length();
}
return wrapped_faces; return wrapped_faces;
} }
@ -665,8 +692,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const Vector<Plane> &p_planes) {
Vector3 ref = Vector3(0.0, 1.0, 0.0); Vector3 ref = Vector3(0.0, 1.0, 0.0);
if (ABS(p.normal.dot(ref)) > 0.95) if (ABS(p.normal.dot(ref)) > 0.95) {
ref = Vector3(0.0, 0.0, 1.0); // Change axis. ref = Vector3(0.0, 0.0, 1.0); // Change axis.
}
Vector3 right = p.normal.cross(ref).normalized(); Vector3 right = p.normal.cross(ref).normalized();
Vector3 up = p.normal.cross(right).normalized(); Vector3 up = p.normal.cross(right).normalized();
@ -681,17 +709,20 @@ Geometry::MeshData Geometry::build_convex_mesh(const Vector<Plane> &p_planes) {
vertices.push_back(center + up * subplane_size + right * subplane_size); vertices.push_back(center + up * subplane_size + right * subplane_size);
for (int j = 0; j < p_planes.size(); j++) { for (int j = 0; j < p_planes.size(); j++) {
if (j == i) if (j == i) {
continue; continue;
}
Vector<Vector3> new_vertices; Vector<Vector3> new_vertices;
Plane clip = p_planes[j]; Plane clip = p_planes[j];
if (clip.normal.dot(p.normal) > 0.95) if (clip.normal.dot(p.normal) > 0.95) {
continue; continue;
}
if (vertices.size() < 3) if (vertices.size() < 3) {
break; break;
}
for (int k = 0; k < vertices.size(); k++) { for (int k = 0; k < vertices.size(); k++) {
int k_n = (k + 1) % vertices.size(); int k_n = (k + 1) % vertices.size();
@ -713,8 +744,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const Vector<Plane> &p_planes) {
Vector3 rel = edge1_A - edge0_A; Vector3 rel = edge1_A - edge0_A;
real_t den = clip.normal.dot(rel); real_t den = clip.normal.dot(rel);
if (Math::is_zero_approx(den)) if (Math::is_zero_approx(den)) {
continue; // Point too short. continue; // Point too short.
}
real_t dist = -(clip.normal.dot(edge0_A) - clip.d) / den; real_t dist = -(clip.normal.dot(edge0_A) - clip.d) / den;
Vector3 inters = edge0_A + rel * dist; Vector3 inters = edge0_A + rel * dist;
@ -725,8 +757,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const Vector<Plane> &p_planes) {
vertices = new_vertices; vertices = new_vertices;
} }
if (vertices.size() < 3) if (vertices.size() < 3) {
continue; continue;
}
// Result is a clockwise face. // Result is a clockwise face.
@ -770,8 +803,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const Vector<Plane> &p_planes) {
} }
} }
if (found) if (found) {
continue; continue;
}
MeshData::Edge edge; MeshData::Edge edge;
edge.a = a; edge.a = a;
edge.b = b; edge.b = b;
@ -913,13 +947,15 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
int w = 1 << i; int w = 1 << i;
int max_h = 0; int max_h = 0;
int max_w = 0; int max_w = 0;
if (w < widest) if (w < widest) {
continue; continue;
}
Vector<int> hmax; Vector<int> hmax;
hmax.resize(w); hmax.resize(w);
for (int j = 0; j < w; j++) for (int j = 0; j < w; j++) {
hmax.write[j] = 0; hmax.write[j] = 0;
}
// Place them. // Place them.
int ofs = 0; int ofs = 0;
@ -931,29 +967,34 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
int from_y = 0; int from_y = 0;
for (int k = 0; k < wrects[j].s.width; k++) { for (int k = 0; k < wrects[j].s.width; k++) {
if (hmax[ofs + k] > from_y) if (hmax[ofs + k] > from_y) {
from_y = hmax[ofs + k]; from_y = hmax[ofs + k];
}
} }
wrects.write[j].p.x = ofs; wrects.write[j].p.x = ofs;
wrects.write[j].p.y = from_y; wrects.write[j].p.y = from_y;
int end_h = from_y + wrects[j].s.height; int end_h = from_y + wrects[j].s.height;
int end_w = ofs + wrects[j].s.width; int end_w = ofs + wrects[j].s.width;
if (ofs == 0) if (ofs == 0) {
limit_h = end_h; limit_h = end_h;
}
for (int k = 0; k < wrects[j].s.width; k++) { for (int k = 0; k < wrects[j].s.width; k++) {
hmax.write[ofs + k] = end_h; hmax.write[ofs + k] = end_h;
} }
if (end_h > max_h) if (end_h > max_h) {
max_h = end_h; max_h = end_h;
}
if (end_w > max_w) if (end_w > max_w) {
max_w = end_w; max_w = end_w;
}
if (ofs == 0 || end_h > limit_h) // While h limit not reached, keep stacking. if (ofs == 0 || end_h > limit_h) { // While h limit not reached, keep stacking.
ofs += wrects[j].s.width; ofs += wrects[j].s.width;
}
} }
_AtlasWorkRectResult result; _AtlasWorkRectResult result;
@ -1243,8 +1284,9 @@ static void edt(float *f, int stride, int n) {
k = 0; k = 0;
for (int q = 0; q <= n - 1; q++) { for (int q = 0; q <= n - 1; q++) {
while (z[k + 1] < q) while (z[k + 1] < q) {
k++; k++;
}
d[q] = square(q - v[k]) + f[v[k] * stride]; d[q] = square(q - v[k]) + f[v[k] * stride];
} }

View File

@ -78,8 +78,9 @@ public:
// clamp to segment S1. Else pick arbitrary s (here 0). // clamp to segment S1. Else pick arbitrary s (here 0).
if (denom != 0.0) { if (denom != 0.0) {
s = CLAMP((b * f - c * e) / denom, 0.0, 1.0); s = CLAMP((b * f - c * e) / denom, 0.0, 1.0);
} else } else {
s = 0.0; s = 0.0;
}
// Compute point on L2 closest to S1(s) using // Compute point on L2 closest to S1(s) using
// t = Dot((P1 + D1*s) - P2,D2) / Dot(D2,D2) = (b*s + f) / e // t = Dot((P1 + D1*s) - P2,D2) / Dot(D2,D2) = (b*s + f) / e
t = (b * s + f) / e; t = (b * s + f) / e;
@ -110,14 +111,18 @@ public:
real_t mub = (d_of(p1, q1, q2, q1) + mua * d_of(q2, q1, p2, p1)) / d_of(q2, q1, q2, q1); real_t mub = (d_of(p1, q1, q2, q1) + mua * d_of(q2, q1, p2, p1)) / d_of(q2, q1, q2, q1);
// Clip the value between [0..1] constraining the solution to lie on the original curves. // Clip the value between [0..1] constraining the solution to lie on the original curves.
if (mua < 0) if (mua < 0) {
mua = 0; mua = 0;
if (mub < 0) }
if (mub < 0) {
mub = 0; mub = 0;
if (mua > 1) }
if (mua > 1) {
mua = 1; mua = 1;
if (mub > 1) }
if (mub > 1) {
mub = 1; mub = 1;
}
c1 = p1.lerp(p2, mua); c1 = p1.lerp(p2, mua);
c2 = q1.lerp(q2, mub); c2 = q1.lerp(q2, mub);
} }
@ -158,22 +163,22 @@ public:
if (tN < 0.0) { // tc < 0 => the t=0 edge is visible. if (tN < 0.0) { // tc < 0 => the t=0 edge is visible.
tN = 0.0; tN = 0.0;
// Recompute sc for this edge. // Recompute sc for this edge.
if (-d < 0.0) if (-d < 0.0) {
sN = 0.0; sN = 0.0;
else if (-d > a) } else if (-d > a) {
sN = sD; sN = sD;
else { } else {
sN = -d; sN = -d;
sD = a; sD = a;
} }
} else if (tN > tD) { // tc > 1 => the t=1 edge is visible. } else if (tN > tD) { // tc > 1 => the t=1 edge is visible.
tN = tD; tN = tD;
// Recompute sc for this edge. // Recompute sc for this edge.
if ((-d + b) < 0.0) if ((-d + b) < 0.0) {
sN = 0; sN = 0;
else if ((-d + b) > a) } else if ((-d + b) > a) {
sN = sD; sN = sD;
else { } else {
sN = (-d + b); sN = (-d + b);
sD = a; sD = a;
} }
@ -193,34 +198,39 @@ public:
Vector3 e2 = p_v2 - p_v0; Vector3 e2 = p_v2 - p_v0;
Vector3 h = p_dir.cross(e2); Vector3 h = p_dir.cross(e2);
real_t a = e1.dot(h); real_t a = e1.dot(h);
if (Math::is_zero_approx(a)) // Parallel test. if (Math::is_zero_approx(a)) { // Parallel test.
return false; return false;
}
real_t f = 1.0 / a; real_t f = 1.0 / a;
Vector3 s = p_from - p_v0; Vector3 s = p_from - p_v0;
real_t u = f * s.dot(h); real_t u = f * s.dot(h);
if (u < 0.0 || u > 1.0) if (u < 0.0 || u > 1.0) {
return false; return false;
}
Vector3 q = s.cross(e1); Vector3 q = s.cross(e1);
real_t v = f * p_dir.dot(q); real_t v = f * p_dir.dot(q);
if (v < 0.0 || u + v > 1.0) if (v < 0.0 || u + v > 1.0) {
return false; return false;
}
// At this stage we can compute t to find out where // At this stage we can compute t to find out where
// the intersection point is on the line. // the intersection point is on the line.
real_t t = f * e2.dot(q); real_t t = f * e2.dot(q);
if (t > 0.00001) { // ray intersection if (t > 0.00001) { // ray intersection
if (r_res) if (r_res) {
*r_res = p_from + p_dir * t; *r_res = p_from + p_dir * t;
}
return true; return true;
} else // This means that there is a line intersection but not a ray intersection. } else { // This means that there is a line intersection but not a ray intersection.
return false; return false;
}
} }
static inline bool segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2, Vector3 *r_res = nullptr) { static inline bool segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2, Vector3 *r_res = nullptr) {
@ -229,67 +239,78 @@ public:
Vector3 e2 = p_v2 - p_v0; Vector3 e2 = p_v2 - p_v0;
Vector3 h = rel.cross(e2); Vector3 h = rel.cross(e2);
real_t a = e1.dot(h); real_t a = e1.dot(h);
if (Math::is_zero_approx(a)) // Parallel test. if (Math::is_zero_approx(a)) { // Parallel test.
return false; return false;
}
real_t f = 1.0 / a; real_t f = 1.0 / a;
Vector3 s = p_from - p_v0; Vector3 s = p_from - p_v0;
real_t u = f * s.dot(h); real_t u = f * s.dot(h);
if (u < 0.0 || u > 1.0) if (u < 0.0 || u > 1.0) {
return false; return false;
}
Vector3 q = s.cross(e1); Vector3 q = s.cross(e1);
real_t v = f * rel.dot(q); real_t v = f * rel.dot(q);
if (v < 0.0 || u + v > 1.0) if (v < 0.0 || u + v > 1.0) {
return false; return false;
}
// At this stage we can compute t to find out where // At this stage we can compute t to find out where
// the intersection point is on the line. // the intersection point is on the line.
real_t t = f * e2.dot(q); real_t t = f * e2.dot(q);
if (t > CMP_EPSILON && t <= 1.0) { // Ray intersection. if (t > CMP_EPSILON && t <= 1.0) { // Ray intersection.
if (r_res) if (r_res) {
*r_res = p_from + rel * t; *r_res = p_from + rel * t;
}
return true; return true;
} else // This means that there is a line intersection but not a ray intersection. } else { // This means that there is a line intersection but not a ray intersection.
return false; return false;
}
} }
static inline bool segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius, Vector3 *r_res = nullptr, Vector3 *r_norm = nullptr) { static inline bool segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius, Vector3 *r_res = nullptr, Vector3 *r_norm = nullptr) {
Vector3 sphere_pos = p_sphere_pos - p_from; Vector3 sphere_pos = p_sphere_pos - p_from;
Vector3 rel = (p_to - p_from); Vector3 rel = (p_to - p_from);
real_t rel_l = rel.length(); real_t rel_l = rel.length();
if (rel_l < CMP_EPSILON) if (rel_l < CMP_EPSILON) {
return false; // Both points are the same. return false; // Both points are the same.
}
Vector3 normal = rel / rel_l; Vector3 normal = rel / rel_l;
real_t sphere_d = normal.dot(sphere_pos); real_t sphere_d = normal.dot(sphere_pos);
real_t ray_distance = sphere_pos.distance_to(normal * sphere_d); real_t ray_distance = sphere_pos.distance_to(normal * sphere_d);
if (ray_distance >= p_sphere_radius) if (ray_distance >= p_sphere_radius) {
return false; return false;
}
real_t inters_d2 = p_sphere_radius * p_sphere_radius - ray_distance * ray_distance; real_t inters_d2 = p_sphere_radius * p_sphere_radius - ray_distance * ray_distance;
real_t inters_d = sphere_d; real_t inters_d = sphere_d;
if (inters_d2 >= CMP_EPSILON) if (inters_d2 >= CMP_EPSILON) {
inters_d -= Math::sqrt(inters_d2); inters_d -= Math::sqrt(inters_d2);
}
// Check in segment. // Check in segment.
if (inters_d < 0 || inters_d > rel_l) if (inters_d < 0 || inters_d > rel_l) {
return false; return false;
}
Vector3 result = p_from + normal * inters_d; Vector3 result = p_from + normal * inters_d;
if (r_res) if (r_res) {
*r_res = result; *r_res = result;
if (r_norm) }
if (r_norm) {
*r_norm = (result - p_sphere_pos).normalized(); *r_norm = (result - p_sphere_pos).normalized();
}
return true; return true;
} }
@ -297,8 +318,9 @@ public:
static inline bool segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, real_t p_height, real_t p_radius, Vector3 *r_res = nullptr, Vector3 *r_norm = nullptr) { static inline bool segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, real_t p_height, real_t p_radius, Vector3 *r_res = nullptr, Vector3 *r_norm = nullptr) {
Vector3 rel = (p_to - p_from); Vector3 rel = (p_to - p_from);
real_t rel_l = rel.length(); real_t rel_l = rel.length();
if (rel_l < CMP_EPSILON) if (rel_l < CMP_EPSILON) {
return false; // Both points are the same. return false; // Both points are the same.
}
// First check if they are parallel. // First check if they are parallel.
Vector3 normal = (rel / rel_l); Vector3 normal = (rel / rel_l);
@ -315,13 +337,15 @@ public:
real_t dist = z_dir.dot(p_from); real_t dist = z_dir.dot(p_from);
if (dist >= p_radius) if (dist >= p_radius) {
return false; // Too far away. return false; // Too far away.
}
// Convert to 2D. // Convert to 2D.
real_t w2 = p_radius * p_radius - dist * dist; real_t w2 = p_radius * p_radius - dist * dist;
if (w2 < CMP_EPSILON) if (w2 < CMP_EPSILON) {
return false; // Avoid numerical error. return false; // Avoid numerical error.
}
Size2 size(Math::sqrt(w2), p_height * 0.5); Size2 size(Math::sqrt(w2), p_height * 0.5);
Vector3 x_dir = z_dir.cross(Vector3(0, 0, 1)).normalized(); Vector3 x_dir = z_dir.cross(Vector3(0, 0, 1)).normalized();
@ -341,15 +365,17 @@ public:
real_t cmin, cmax; real_t cmin, cmax;
if (seg_from < seg_to) { if (seg_from < seg_to) {
if (seg_from > box_end || seg_to < box_begin) if (seg_from > box_end || seg_to < box_begin) {
return false; return false;
}
real_t length = seg_to - seg_from; real_t length = seg_to - seg_from;
cmin = (seg_from < box_begin) ? ((box_begin - seg_from) / length) : 0; cmin = (seg_from < box_begin) ? ((box_begin - seg_from) / length) : 0;
cmax = (seg_to > box_end) ? ((box_end - seg_from) / length) : 1; cmax = (seg_to > box_end) ? ((box_end - seg_from) / length) : 1;
} else { } else {
if (seg_to > box_end || seg_from < box_begin) if (seg_to > box_end || seg_from < box_begin) {
return false; return false;
}
real_t length = seg_to - seg_from; real_t length = seg_to - seg_from;
cmin = (seg_from > box_end) ? (box_end - seg_from) / length : 0; cmin = (seg_from > box_end) ? (box_end - seg_from) / length : 0;
cmax = (seg_to < box_begin) ? (box_begin - seg_from) / length : 1; cmax = (seg_to < box_begin) ? (box_begin - seg_from) / length : 1;
@ -359,10 +385,12 @@ public:
min = cmin; min = cmin;
axis = i; axis = i;
} }
if (cmax < max) if (cmax < max) {
max = cmax; max = cmax;
if (max < min) }
if (max < min) {
return false; return false;
}
} }
// Convert to 3D again. // Convert to 3D again.
@ -378,10 +406,12 @@ public:
res_normal.normalize(); res_normal.normalize();
if (r_res) if (r_res) {
*r_res = result; *r_res = result;
if (r_norm) }
if (r_norm) {
*r_norm = res_normal; *r_norm = res_normal;
}
return true; return true;
} }
@ -392,8 +422,9 @@ public:
Vector3 rel = p_to - p_from; Vector3 rel = p_to - p_from;
real_t rel_l = rel.length(); real_t rel_l = rel.length();
if (rel_l < CMP_EPSILON) if (rel_l < CMP_EPSILON) {
return false; return false;
}
Vector3 dir = rel / rel_l; Vector3 dir = rel / rel_l;
@ -404,15 +435,17 @@ public:
real_t den = p.normal.dot(dir); real_t den = p.normal.dot(dir);
if (Math::abs(den) <= CMP_EPSILON) if (Math::abs(den) <= CMP_EPSILON) {
continue; // Ignore parallel plane. continue; // Ignore parallel plane.
}
real_t dist = -p.distance_to(p_from) / den; real_t dist = -p.distance_to(p_from) / den;
if (den > 0) { if (den > 0) {
// Backwards facing plane. // Backwards facing plane.
if (dist < max) if (dist < max) {
max = dist; max = dist;
}
} else { } else {
// Front facing plane. // Front facing plane.
if (dist > min) { if (dist > min) {
@ -422,13 +455,16 @@ public:
} }
} }
if (max <= min || min < 0 || min > rel_l || min_index == -1) // Exit conditions. if (max <= min || min < 0 || min > rel_l || min_index == -1) { // Exit conditions.
return false; // No intersection. return false; // No intersection.
}
if (p_res) if (p_res) {
*p_res = p_from + dir * min; *p_res = p_from + dir * min;
if (p_norm) }
if (p_norm) {
*p_norm = p_planes[min_index].normal; *p_norm = p_planes[min_index].normal;
}
return true; return true;
} }
@ -437,25 +473,28 @@ public:
Vector3 p = p_point - p_segment[0]; Vector3 p = p_point - p_segment[0];
Vector3 n = p_segment[1] - p_segment[0]; Vector3 n = p_segment[1] - p_segment[0];
real_t l2 = n.length_squared(); real_t l2 = n.length_squared();
if (l2 < 1e-20) if (l2 < 1e-20) {
return p_segment[0]; // Both points are the same, just give any. return p_segment[0]; // Both points are the same, just give any.
}
real_t d = n.dot(p) / l2; real_t d = n.dot(p) / l2;
if (d <= 0.0) if (d <= 0.0) {
return p_segment[0]; // Before first point. return p_segment[0]; // Before first point.
else if (d >= 1.0) } else if (d >= 1.0) {
return p_segment[1]; // After first point. return p_segment[1]; // After first point.
else } else {
return p_segment[0] + n * d; // Inside. return p_segment[0] + n * d; // Inside.
}
} }
static Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 *p_segment) { static Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 *p_segment) {
Vector3 p = p_point - p_segment[0]; Vector3 p = p_point - p_segment[0];
Vector3 n = p_segment[1] - p_segment[0]; Vector3 n = p_segment[1] - p_segment[0];
real_t l2 = n.length_squared(); real_t l2 = n.length_squared();
if (l2 < 1e-20) if (l2 < 1e-20) {
return p_segment[0]; // Both points are the same, just give any. return p_segment[0]; // Both points are the same, just give any.
}
real_t d = n.dot(p) / l2; real_t d = n.dot(p) / l2;
@ -466,17 +505,19 @@ public:
Vector2 p = p_point - p_segment[0]; Vector2 p = p_point - p_segment[0];
Vector2 n = p_segment[1] - p_segment[0]; Vector2 n = p_segment[1] - p_segment[0];
real_t l2 = n.length_squared(); real_t l2 = n.length_squared();
if (l2 < 1e-20) if (l2 < 1e-20) {
return p_segment[0]; // Both points are the same, just give any. return p_segment[0]; // Both points are the same, just give any.
}
real_t d = n.dot(p) / l2; real_t d = n.dot(p) / l2;
if (d <= 0.0) if (d <= 0.0) {
return p_segment[0]; // Before first point. return p_segment[0]; // Before first point.
else if (d >= 1.0) } else if (d >= 1.0) {
return p_segment[1]; // After first point. return p_segment[1]; // After first point.
else } else {
return p_segment[0] + n * d; // Inside. return p_segment[0] + n * d; // Inside.
}
} }
static bool is_point_in_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) { static bool is_point_in_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) {
@ -486,8 +527,9 @@ public:
bool orientation = an.cross(bn) > 0; bool orientation = an.cross(bn) > 0;
if ((bn.cross(cn) > 0) != orientation) if ((bn.cross(cn) > 0) != orientation) {
return false; return false;
}
return (cn.cross(an) > 0) == orientation; return (cn.cross(an) > 0) == orientation;
} }
@ -496,8 +538,9 @@ public:
Vector2 p = p_point - p_segment[0]; Vector2 p = p_point - p_segment[0];
Vector2 n = p_segment[1] - p_segment[0]; Vector2 n = p_segment[1] - p_segment[0];
real_t l2 = n.length_squared(); real_t l2 = n.length_squared();
if (l2 < 1e-20) if (l2 < 1e-20) {
return p_segment[0]; // Both points are the same, just give any. return p_segment[0]; // Both points are the same, just give any.
}
real_t d = n.dot(p) / l2; real_t d = n.dot(p) / l2;
@ -524,24 +567,28 @@ public:
Vector2 D = p_to_b - p_from_a; Vector2 D = p_to_b - p_from_a;
real_t ABlen = B.dot(B); real_t ABlen = B.dot(B);
if (ABlen <= 0) if (ABlen <= 0) {
return false; return false;
}
Vector2 Bn = B / ABlen; Vector2 Bn = B / ABlen;
C = Vector2(C.x * Bn.x + C.y * Bn.y, C.y * Bn.x - C.x * Bn.y); C = Vector2(C.x * Bn.x + C.y * Bn.y, C.y * Bn.x - C.x * Bn.y);
D = Vector2(D.x * Bn.x + D.y * Bn.y, D.y * Bn.x - D.x * Bn.y); D = Vector2(D.x * Bn.x + D.y * Bn.y, D.y * Bn.x - D.x * Bn.y);
if ((C.y < 0 && D.y < 0) || (C.y >= 0 && D.y >= 0)) if ((C.y < 0 && D.y < 0) || (C.y >= 0 && D.y >= 0)) {
return false; return false;
}
real_t ABpos = D.x + (C.x - D.x) * D.y / (D.y - C.y); real_t ABpos = D.x + (C.x - D.x) * D.y / (D.y - C.y);
// Fail if segment C-D crosses line A-B outside of segment A-B. // Fail if segment C-D crosses line A-B outside of segment A-B.
if (ABpos < 0 || ABpos > 1.0) if (ABpos < 0 || ABpos > 1.0) {
return false; return false;
}
// (4) Apply the discovered position to line A-B in the original coordinate system. // (4) Apply the discovered position to line A-B in the original coordinate system.
if (r_result) if (r_result) {
*r_result = p_from_a + B * ABpos; *r_result = p_from_a + B * ABpos;
}
return true; return true;
} }
@ -551,18 +598,21 @@ public:
Vector3 n1 = (p_point - p_v3).cross(p_point - p_v2); Vector3 n1 = (p_point - p_v3).cross(p_point - p_v2);
if (face_n.dot(n1) < 0) if (face_n.dot(n1) < 0) {
return false; return false;
}
Vector3 n2 = (p_v1 - p_v3).cross(p_v1 - p_point); Vector3 n2 = (p_v1 - p_v3).cross(p_v1 - p_point);
if (face_n.dot(n2) < 0) if (face_n.dot(n2) < 0) {
return false; return false;
}
Vector3 n3 = (p_v1 - p_point).cross(p_v1 - p_v2); Vector3 n3 = (p_v1 - p_point).cross(p_v1 - p_v2);
if (face_n.dot(n3) < 0) if (face_n.dot(n3) < 0) {
return false; return false;
}
return true; return true;
} }
@ -570,8 +620,10 @@ public:
static inline bool triangle_sphere_intersection_test(const Vector3 *p_triangle, const Vector3 &p_normal, const Vector3 &p_sphere_pos, real_t p_sphere_radius, Vector3 &r_triangle_contact, Vector3 &r_sphere_contact) { static inline bool triangle_sphere_intersection_test(const Vector3 *p_triangle, const Vector3 &p_normal, const Vector3 &p_sphere_pos, real_t p_sphere_radius, Vector3 &r_triangle_contact, Vector3 &r_sphere_contact) {
real_t d = p_normal.dot(p_sphere_pos) - p_normal.dot(p_triangle[0]); real_t d = p_normal.dot(p_sphere_pos) - p_normal.dot(p_triangle[0]);
if (d > p_sphere_radius || d < -p_sphere_radius) // Not touching the plane of the face, return. if (d > p_sphere_radius || d < -p_sphere_radius) {
// Not touching the plane of the face, return.
return false; return false;
}
Vector3 contact = p_sphere_pos - (p_normal * d); Vector3 contact = p_sphere_pos - (p_normal * d);
@ -663,8 +715,9 @@ public:
// If the term we intend to square root is less than 0 then the answer won't be real, // If the term we intend to square root is less than 0 then the answer won't be real,
// so it definitely won't be t in the range 0 to 1. // so it definitely won't be t in the range 0 to 1.
if (sqrtterm < 0) if (sqrtterm < 0) {
return -1; return -1;
}
// If we can assume that the line segment starts outside the circle (e.g. for continuous time collision detection) // If we can assume that the line segment starts outside the circle (e.g. for continuous time collision detection)
// then the following can be skipped and we can just return the equivalent of res1. // then the following can be skipped and we can just return the equivalent of res1.
@ -672,10 +725,12 @@ public:
real_t res1 = (-b - sqrtterm) / (2 * a); real_t res1 = (-b - sqrtterm) / (2 * a);
real_t res2 = (-b + sqrtterm) / (2 * a); real_t res2 = (-b + sqrtterm) / (2 * a);
if (res1 >= 0 && res1 <= 1) if (res1 >= 0 && res1 <= 1) {
return res1; return res1;
if (res2 >= 0 && res2 <= 1) }
if (res2 >= 0 && res2 <= 1) {
return res2; return res2;
}
return -1; return -1;
} }
@ -686,8 +741,9 @@ public:
LOC_OUTSIDE = -1 LOC_OUTSIDE = -1
}; };
if (polygon.size() == 0) if (polygon.size() == 0) {
return polygon; return polygon;
}
int *location_cache = (int *)alloca(sizeof(int) * polygon.size()); int *location_cache = (int *)alloca(sizeof(int) * polygon.size());
int inside_count = 0; int inside_count = 0;
@ -710,7 +766,6 @@ public:
if (outside_count == 0) { if (outside_count == 0) {
return polygon; // No changes. return polygon; // No changes.
} else if (inside_count == 0) { } else if (inside_count == 0) {
return Vector<Vector3>(); // Empty. return Vector<Vector3>(); // Empty.
} }
@ -818,15 +873,17 @@ public:
static Vector<int> triangulate_polygon(const Vector<Vector2> &p_polygon) { static Vector<int> triangulate_polygon(const Vector<Vector2> &p_polygon) {
Vector<int> triangles; Vector<int> triangles;
if (!Triangulate::triangulate(p_polygon, triangles)) if (!Triangulate::triangulate(p_polygon, triangles)) {
return Vector<int>(); //fail return Vector<int>(); //fail
}
return triangles; return triangles;
} }
static bool is_polygon_clockwise(const Vector<Vector2> &p_polygon) { static bool is_polygon_clockwise(const Vector<Vector2> &p_polygon) {
int c = p_polygon.size(); int c = p_polygon.size();
if (c < 3) if (c < 3) {
return false; return false;
}
const Vector2 *p = p_polygon.ptr(); const Vector2 *p = p_polygon.ptr();
real_t sum = 0; real_t sum = 0;
for (int i = 0; i < c; i++) { for (int i = 0; i < c; i++) {
@ -841,8 +898,9 @@ public:
// Alternate implementation that should be faster. // Alternate implementation that should be faster.
static bool is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2> &p_polygon) { static bool is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2> &p_polygon) {
int c = p_polygon.size(); int c = p_polygon.size();
if (c < 3) if (c < 3) {
return false; return false;
}
const Vector2 *p = p_polygon.ptr(); const Vector2 *p = p_polygon.ptr();
Vector2 further_away(-1e20, -1e20); Vector2 further_away(-1e20, -1e20);
Vector2 further_away_opposite(1e20, 1e20); Vector2 further_away_opposite(1e20, 1e20);
@ -914,25 +972,29 @@ public:
return (1 << 23) | (1 << 22) | (1 << 21) | (1 << 20); return (1 << 23) | (1 << 22) | (1 << 21) | (1 << 20);
} else { } else {
int ret = 0; int ret = 0;
if ((p_idx % 8) == 0) if ((p_idx % 8) == 0) {
ret |= (1 << (p_idx + 7)); ret |= (1 << (p_idx + 7));
else } else {
ret |= (1 << (p_idx - 1)); ret |= (1 << (p_idx - 1));
if ((p_idx % 8) == 7) }
if ((p_idx % 8) == 7) {
ret |= (1 << (p_idx - 7)); ret |= (1 << (p_idx - 7));
else } else {
ret |= (1 << (p_idx + 1)); ret |= (1 << (p_idx + 1));
}
int mask = ret | (1 << p_idx); int mask = ret | (1 << p_idx);
if (p_idx < 8) if (p_idx < 8) {
ret |= 24; ret |= 24;
else } else {
ret |= mask >> 8; ret |= mask >> 8;
}
if (p_idx >= 16) if (p_idx >= 16) {
ret |= 25; ret |= 25;
else } else {
ret |= mask << 8; ret |= mask << 8;
}
return ret; return ret;
} }
@ -954,15 +1016,17 @@ public:
// Build lower hull. // Build lower hull.
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
while (k >= 2 && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0) while (k >= 2 && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0) {
k--; k--;
}
H.write[k++] = P[i]; H.write[k++] = P[i];
} }
// Build upper hull. // Build upper hull.
for (int i = n - 2, t = k + 1; i >= 0; i--) { for (int i = n - 2, t = k + 1; i >= 0; i--) {
while (k >= t && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0) while (k >= t && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0) {
k--; k--;
}
H.write[k++] = P[i]; H.write[k++] = P[i];
} }
@ -983,14 +1047,18 @@ public:
#define FINDMINMAX(x0, x1, x2, min, max) \ #define FINDMINMAX(x0, x1, x2, min, max) \
min = max = x0; \ min = max = x0; \
if (x1 < min) \ if (x1 < min) { \
min = x1; \ min = x1; \
if (x1 > max) \ } \
if (x1 > max) { \
max = x1; \ max = x1; \
if (x2 < min) \ } \
if (x2 < min) { \
min = x2; \ min = x2; \
if (x2 > max) \ } \
max = x2; if (x2 > max) { \
max = x2; \
}
_FORCE_INLINE_ static bool planeBoxOverlap(Vector3 normal, float d, Vector3 maxbox) { _FORCE_INLINE_ static bool planeBoxOverlap(Vector3 normal, float d, Vector3 maxbox) {
int q; int q;
@ -1004,10 +1072,12 @@ public:
vmax[q] = -maxbox[q]; vmax[q] = -maxbox[q];
} }
} }
if (normal.dot(vmin) + d > 0.0f) if (normal.dot(vmin) + d > 0.0f) {
return false; return false;
if (normal.dot(vmax) + d >= 0.0f) }
if (normal.dot(vmax) + d >= 0.0f) {
return true; return true;
}
return false; return false;
} }
@ -1024,8 +1094,9 @@ public:
max = p0; \ max = p0; \
} \ } \
rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \ rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
if (min > rad || max < -rad) \ if (min > rad || max < -rad) { \
return false; return false; \
}
#define AXISTEST_X2(a, b, fa, fb) \ #define AXISTEST_X2(a, b, fa, fb) \
p0 = a * v0.y - b * v0.z; \ p0 = a * v0.y - b * v0.z; \
@ -1038,8 +1109,9 @@ public:
max = p0; \ max = p0; \
} \ } \
rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \ rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
if (min > rad || max < -rad) \ if (min > rad || max < -rad) { \
return false; return false; \
}
/*======================== Y-tests ========================*/ /*======================== Y-tests ========================*/
#define AXISTEST_Y02(a, b, fa, fb) \ #define AXISTEST_Y02(a, b, fa, fb) \
@ -1053,8 +1125,9 @@ public:
max = p0; \ max = p0; \
} \ } \
rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \ rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
if (min > rad || max < -rad) \ if (min > rad || max < -rad) { \
return false; return false; \
}
#define AXISTEST_Y1(a, b, fa, fb) \ #define AXISTEST_Y1(a, b, fa, fb) \
p0 = -a * v0.x + b * v0.z; \ p0 = -a * v0.x + b * v0.z; \
@ -1067,8 +1140,9 @@ public:
max = p0; \ max = p0; \
} \ } \
rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \ rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
if (min > rad || max < -rad) \ if (min > rad || max < -rad) { \
return false; return false; \
}
/*======================== Z-tests ========================*/ /*======================== Z-tests ========================*/
@ -1083,8 +1157,9 @@ public:
max = p2; \ max = p2; \
} \ } \
rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \ rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
if (min > rad || max < -rad) \ if (min > rad || max < -rad) { \
return false; return false; \
}
#define AXISTEST_Z0(a, b, fa, fb) \ #define AXISTEST_Z0(a, b, fa, fb) \
p0 = a * v0.x - b * v0.y; \ p0 = a * v0.x - b * v0.y; \
@ -1097,8 +1172,9 @@ public:
max = p0; \ max = p0; \
} \ } \
rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \ rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
if (min > rad || max < -rad) \ if (min > rad || max < -rad) { \
return false; return false; \
}
_FORCE_INLINE_ static bool triangle_box_overlap(const Vector3 &boxcenter, const Vector3 boxhalfsize, const Vector3 *triverts) { _FORCE_INLINE_ static bool triangle_box_overlap(const Vector3 &boxcenter, const Vector3 boxhalfsize, const Vector3 *triverts) {
/* use separating axis theorem to test overlap between triangle and box */ /* use separating axis theorem to test overlap between triangle and box */
@ -1155,18 +1231,21 @@ public:
/* test in X-direction */ /* test in X-direction */
FINDMINMAX(v0.x, v1.x, v2.x, min, max); FINDMINMAX(v0.x, v1.x, v2.x, min, max);
if (min > boxhalfsize.x || max < -boxhalfsize.x) if (min > boxhalfsize.x || max < -boxhalfsize.x) {
return false; return false;
}
/* test in Y-direction */ /* test in Y-direction */
FINDMINMAX(v0.y, v1.y, v2.y, min, max); FINDMINMAX(v0.y, v1.y, v2.y, min, max);
if (min > boxhalfsize.y || max < -boxhalfsize.y) if (min > boxhalfsize.y || max < -boxhalfsize.y) {
return false; return false;
}
/* test in Z-direction */ /* test in Z-direction */
FINDMINMAX(v0.z, v1.z, v2.z, min, max); FINDMINMAX(v0.z, v1.z, v2.z, min, max);
if (min > boxhalfsize.z || max < -boxhalfsize.z) if (min > boxhalfsize.z || max < -boxhalfsize.z) {
return false; return false;
}
/* Bullet 2: */ /* Bullet 2: */
/* test if the box intersects the plane of the triangle */ /* test if the box intersects the plane of the triangle */

View File

@ -94,16 +94,18 @@ double Math::dectime(double p_value, double p_amount, double p_step) {
double sgn = p_value < 0 ? -1.0 : 1.0; double sgn = p_value < 0 ? -1.0 : 1.0;
double val = Math::abs(p_value); double val = Math::abs(p_value);
val -= p_amount * p_step; val -= p_amount * p_step;
if (val < 0.0) if (val < 0.0) {
val = 0.0; val = 0.0;
}
return val * sgn; return val * sgn;
} }
double Math::ease(double p_x, double p_c) { double Math::ease(double p_x, double p_c) {
if (p_x < 0) if (p_x < 0) {
p_x = 0; p_x = 0;
else if (p_x > 1.0) } else if (p_x > 1.0) {
p_x = 1.0; p_x = 1.0;
}
if (p_c > 0) { if (p_c > 0) {
if (p_c < 1.0) { if (p_c < 1.0) {
return 1.0 - Math::pow(1.0 - p_x, 1.0 / p_c); return 1.0 - Math::pow(1.0 - p_x, 1.0 / p_c);
@ -118,8 +120,9 @@ double Math::ease(double p_x, double p_c) {
} else { } else {
return (1.0 - Math::pow(1.0 - (p_x - 0.5) * 2.0, -p_c)) * 0.5 + 0.5; return (1.0 - Math::pow(1.0 - (p_x - 0.5) * 2.0, -p_c)) * 0.5 + 0.5;
} }
} else } else {
return 0; // no ease (raw) return 0; // no ease (raw)
}
} }
double Math::stepify(double p_value, double p_step) { double Math::stepify(double p_value, double p_step) {
@ -166,8 +169,9 @@ uint32_t Math::larger_prime(uint32_t p_val) {
int idx = 0; int idx = 0;
while (true) { while (true) {
ERR_FAIL_COND_V(primes[idx] == 0, 0); ERR_FAIL_COND_V(primes[idx] == 0, 0);
if (primes[idx] > p_val) if (primes[idx] > p_val) {
return primes[idx]; return primes[idx];
}
idx++; idx++;
} }
} }

View File

@ -232,14 +232,16 @@ public:
static _ALWAYS_INLINE_ float range_lerp(float p_value, float p_istart, float p_istop, float p_ostart, float p_ostop) { return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); } static _ALWAYS_INLINE_ float range_lerp(float p_value, float p_istart, float p_istop, float p_ostart, float p_ostop) { return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); }
static _ALWAYS_INLINE_ double smoothstep(double p_from, double p_to, double p_weight) { static _ALWAYS_INLINE_ double smoothstep(double p_from, double p_to, double p_weight) {
if (is_equal_approx(p_from, p_to)) if (is_equal_approx(p_from, p_to)) {
return p_from; return p_from;
}
double x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0, 1.0); double x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0, 1.0);
return x * x * (3.0 - 2.0 * x); return x * x * (3.0 - 2.0 * x);
} }
static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_weight) { static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_weight) {
if (is_equal_approx(p_from, p_to)) if (is_equal_approx(p_from, p_to)) {
return p_from; return p_from;
}
float x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0f, 1.0f); float x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0f, 1.0f);
return x * x * (3.0f - 2.0f * x); return x * x * (3.0f - 2.0f * x);
} }
@ -471,10 +473,11 @@ public:
if (p_step != 0) { if (p_step != 0) {
float a = Math::stepify(p_target - p_offset, p_step + p_separation) + p_offset; float a = Math::stepify(p_target - p_offset, p_step + p_separation) + p_offset;
float b = a; float b = a;
if (p_target >= 0) if (p_target >= 0) {
b -= p_separation; b -= p_separation;
else } else {
b += p_step; b += p_step;
}
return (Math::abs(p_target - a) < Math::abs(p_target - b)) ? a : b; return (Math::abs(p_target - a) < Math::abs(p_target - b)) ? a : b;
} }
return p_target; return p_target;

View File

@ -190,12 +190,14 @@ private:
} }
_FORCE_INLINE_ void _pair_reference(Element *p_A, Element *p_B) { _FORCE_INLINE_ void _pair_reference(Element *p_A, Element *p_B) {
if (p_A == p_B || (p_A->userdata == p_B->userdata && p_A->userdata)) if (p_A == p_B || (p_A->userdata == p_B->userdata && p_A->userdata)) {
return; return;
}
if (!(p_A->pairable_type & p_B->pairable_mask) && if (!(p_A->pairable_type & p_B->pairable_mask) &&
!(p_B->pairable_type & p_A->pairable_mask)) !(p_B->pairable_type & p_A->pairable_mask)) {
return; // none can pair with none return; // none can pair with none
}
PairKey key(p_A->_id, p_B->_id); PairKey key(p_A->_id, p_B->_id);
typename PairMap::Element *E = pair_map.find(key); typename PairMap::Element *E = pair_map.find(key);
@ -220,8 +222,9 @@ private:
} }
_FORCE_INLINE_ void _pair_unreference(Element *p_A, Element *p_B) { _FORCE_INLINE_ void _pair_unreference(Element *p_A, Element *p_B) {
if (p_A == p_B) if (p_A == p_B) {
return; return;
}
PairKey key(p_A->_id, p_B->_id); PairKey key(p_A->_id, p_B->_id);
typename PairMap::Element *E = pair_map.find(key); typename PairMap::Element *E = pair_map.find(key);
@ -307,12 +310,14 @@ private:
void _cull_point(Octant *p_octant, const Vector3 &p_point, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask); void _cull_point(Octant *p_octant, const Vector3 &p_point, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask);
void _remove_tree(Octant *p_octant) { void _remove_tree(Octant *p_octant) {
if (!p_octant) if (!p_octant) {
return; return;
}
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
if (p_octant->children[i]) if (p_octant->children[i]) {
_remove_tree(p_octant->children[i]); _remove_tree(p_octant->children[i]);
}
} }
memdelete_allocator<Octant, AL>(p_octant); memdelete_allocator<Octant, AL>(p_octant);
@ -423,12 +428,15 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct
AABB aabb = p_octant->aabb; AABB aabb = p_octant->aabb;
aabb.size *= 0.5; aabb.size *= 0.5;
if (i & 1) if (i & 1) {
aabb.position.x += aabb.size.x; aabb.position.x += aabb.size.x;
if (i & 2) }
if (i & 2) {
aabb.position.y += aabb.size.y; aabb.position.y += aabb.size.y;
if (i & 4) }
if (i & 4) {
aabb.position.z += aabb.size.z; aabb.position.z += aabb.size.z;
}
if (aabb.intersects_inclusive(p_element->aabb)) { if (aabb.intersects_inclusive(p_element->aabb)) {
/* if actually intersects, create the child */ /* if actually intersects, create the child */
@ -535,8 +543,9 @@ bool Octree<T, use_pairs, AL>::_remove_element_from_octant(Element *p_element, O
while (true) { while (true) {
// check all exit conditions // check all exit conditions
if (p_octant == p_limit) // reached limit, nothing to erase, exit if (p_octant == p_limit) { // reached limit, nothing to erase, exit
return octant_removed; return octant_removed;
}
bool unpaired = false; bool unpaired = false;
@ -583,8 +592,9 @@ bool Octree<T, use_pairs, AL>::_remove_element_from_octant(Element *p_element, O
octant_removed = true; octant_removed = true;
} }
if (!removed && !unpaired) if (!removed && !unpaired) {
return octant_removed; // no reason to keep going up anymore! was already visited and was not removed return octant_removed; // no reason to keep going up anymore! was already visited and was not removed
}
p_octant = parent; p_octant = parent;
} }
@ -618,12 +628,14 @@ void Octree<T, use_pairs, AL>::_unpair_element(Element *p_element, Octant *p_oct
p_octant->last_pass = pass; p_octant->last_pass = pass;
if (p_octant->children_count == 0) if (p_octant->children_count == 0) {
return; // small optimization for leafs return; // small optimization for leafs
}
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
if (p_octant->children[i]) if (p_octant->children[i]) {
_unpair_element(p_element, p_octant->children[i]); _unpair_element(p_element, p_octant->children[i]);
}
} }
} }
@ -654,12 +666,14 @@ void Octree<T, use_pairs, AL>::_pair_element(Element *p_element, Octant *p_octan
} }
p_octant->last_pass = pass; p_octant->last_pass = pass;
if (p_octant->children_count == 0) if (p_octant->children_count == 0) {
return; // small optimization for leafs return; // small optimization for leafs
}
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
if (p_octant->children[i]) if (p_octant->children[i]) {
_pair_element(p_element, p_octant->children[i]); _pair_element(p_element, p_octant->children[i]);
}
} }
} }
@ -673,8 +687,9 @@ void Octree<T, use_pairs, AL>::_remove_element(Element *p_element) {
for (; I; I = I->next()) { for (; I; I = I->next()) {
Octant *o = I->get().octant; Octant *o = I->get().octant;
if (!use_pairs) // small speedup if (!use_pairs) { // small speedup
o->elements.erase(I->get().E); o->elements.erase(I->get().E);
}
_remove_element_from_octant(p_element, o); _remove_element_from_octant(p_element, o);
} }
@ -690,14 +705,16 @@ void Octree<T, use_pairs, AL>::_remove_element(Element *p_element) {
// erase children pairs, they are erased ONCE even if repeated // erase children pairs, they are erased ONCE even if repeated
pass++; pass++;
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
if (o->children[i]) if (o->children[i]) {
_unpair_element(p_element, o->children[i]); _unpair_element(p_element, o->children[i]);
}
} }
if (p_element->pairable) if (p_element->pairable) {
o->pairable_elements.erase(I->get().E); o->pairable_elements.erase(I->get().E);
else } else {
o->elements.erase(I->get().E); o->elements.erase(I->get().E);
}
} }
} }
@ -742,8 +759,9 @@ OctreeElementID Octree<T, use_pairs, AL>::create(T *p_userdata, const AABB &p_aa
if (!e.aabb.has_no_surface()) { if (!e.aabb.has_no_surface()) {
_ensure_valid_root(p_aabb); _ensure_valid_root(p_aabb);
_insert_element(&e, root); _insert_element(&e, root);
if (use_pairs) if (use_pairs) {
_element_check_pairs(&e); _element_check_pairs(&e);
}
} }
return last_element_id - 1; return last_element_id - 1;
@ -781,21 +799,24 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
e.common_parent = nullptr; e.common_parent = nullptr;
e.aabb = p_aabb; e.aabb = p_aabb;
_insert_element(&e, root); _insert_element(&e, root);
if (use_pairs) if (use_pairs) {
_element_check_pairs(&e); _element_check_pairs(&e);
}
} }
return; return;
} }
if (!old_has_surf) // doing nothing if (!old_has_surf) { // doing nothing
return; return;
}
// it still is enclosed in the same AABB it was assigned to // it still is enclosed in the same AABB it was assigned to
if (e.container_aabb.encloses(p_aabb)) { if (e.container_aabb.encloses(p_aabb)) {
e.aabb = p_aabb; e.aabb = p_aabb;
if (use_pairs) if (use_pairs) {
_element_check_pairs(&e); // must check pairs anyway _element_check_pairs(&e); // must check pairs anyway
}
return; return;
} }
@ -815,8 +836,9 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
//src is now the place towards where insertion is going to happen //src is now the place towards where insertion is going to happen
pass++; pass++;
while (common_parent && !common_parent->aabb.encloses(p_aabb)) while (common_parent && !common_parent->aabb.encloses(p_aabb)) {
common_parent = common_parent->parent; common_parent = common_parent->parent;
}
ERR_FAIL_COND(!common_parent); ERR_FAIL_COND(!common_parent);
@ -838,10 +860,11 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
o->elements.erase( F->get().E ); o->elements.erase( F->get().E );
*/ */
if (use_pairs && e.pairable) if (use_pairs && e.pairable) {
o->pairable_elements.erase(F->get().E); o->pairable_elements.erase(F->get().E);
else } else {
o->elements.erase(F->get().E); o->elements.erase(F->get().E);
}
if (_remove_element_from_octant(&e, o, common_parent->parent)) { if (_remove_element_from_octant(&e, o, common_parent->parent)) {
owners.erase(F); owners.erase(F);
@ -858,8 +881,9 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
// erase children pairs, unref ONCE // erase children pairs, unref ONCE
pass++; pass++;
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
if (o->children[i]) if (o->children[i]) {
_unpair_element(&e, o->children[i]); _unpair_element(&e, o->children[i]);
}
} }
} }
@ -876,8 +900,9 @@ void Octree<T, use_pairs, AL>::set_pairable(OctreeElementID p_id, bool p_pairabl
Element &e = E->get(); Element &e = E->get();
if (p_pairable == e.pairable && e.pairable_type == p_pairable_type && e.pairable_mask == p_pairable_mask) if (p_pairable == e.pairable && e.pairable_type == p_pairable_type && e.pairable_mask == p_pairable_mask) {
return; // no changes, return return; // no changes, return
}
if (!e.aabb.has_no_surface()) { if (!e.aabb.has_no_surface()) {
_remove_element(&e); _remove_element(&e);
@ -891,8 +916,9 @@ void Octree<T, use_pairs, AL>::set_pairable(OctreeElementID p_id, bool p_pairabl
if (!e.aabb.has_no_surface()) { if (!e.aabb.has_no_surface()) {
_ensure_valid_root(e.aabb); _ensure_valid_root(e.aabb);
_insert_element(&e, root); _insert_element(&e, root);
if (use_pairs) if (use_pairs) {
_element_check_pairs(&e); _element_check_pairs(&e);
}
} }
} }
@ -913,8 +939,9 @@ void Octree<T, use_pairs, AL>::erase(OctreeElementID p_id) {
template <class T, bool use_pairs, class AL> template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::_cull_convex(Octant *p_octant, _CullConvexData *p_cull) { void Octree<T, use_pairs, AL>::_cull_convex(Octant *p_octant, _CullConvexData *p_cull) {
if (*p_cull->result_idx == p_cull->result_max) if (*p_cull->result_idx == p_cull->result_max) {
return; //pointless return; //pointless
}
if (!p_octant->elements.empty()) { if (!p_octant->elements.empty()) {
typename List<Element *, AL>::Element *I; typename List<Element *, AL>::Element *I;
@ -923,8 +950,9 @@ void Octree<T, use_pairs, AL>::_cull_convex(Octant *p_octant, _CullConvexData *p
for (; I; I = I->next()) { for (; I; I = I->next()) {
Element *e = I->get(); Element *e = I->get();
if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_cull->mask))) if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_cull->mask))) {
continue; continue;
}
e->last_pass = pass; e->last_pass = pass;
if (e->aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) { if (e->aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) {
@ -945,8 +973,9 @@ void Octree<T, use_pairs, AL>::_cull_convex(Octant *p_octant, _CullConvexData *p
for (; I; I = I->next()) { for (; I; I = I->next()) {
Element *e = I->get(); Element *e = I->get();
if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_cull->mask))) if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_cull->mask))) {
continue; continue;
}
e->last_pass = pass; e->last_pass = pass;
if (e->aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) { if (e->aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) {
@ -969,8 +998,9 @@ void Octree<T, use_pairs, AL>::_cull_convex(Octant *p_octant, _CullConvexData *p
template <class T, bool use_pairs, class AL> template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const AABB &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) { void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const AABB &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
if (*p_result_idx == p_result_max) if (*p_result_idx == p_result_max) {
return; //pointless return; //pointless
}
if (!p_octant->elements.empty()) { if (!p_octant->elements.empty()) {
typename List<Element *, AL>::Element *I; typename List<Element *, AL>::Element *I;
@ -978,15 +1008,17 @@ void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const AABB &p_aabb,
for (; I; I = I->next()) { for (; I; I = I->next()) {
Element *e = I->get(); Element *e = I->get();
if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
continue; continue;
}
e->last_pass = pass; e->last_pass = pass;
if (p_aabb.intersects_inclusive(e->aabb)) { if (p_aabb.intersects_inclusive(e->aabb)) {
if (*p_result_idx < p_result_max) { if (*p_result_idx < p_result_max) {
p_result_array[*p_result_idx] = e->userdata; p_result_array[*p_result_idx] = e->userdata;
if (p_subindex_array) if (p_subindex_array) {
p_subindex_array[*p_result_idx] = e->subindex; p_subindex_array[*p_result_idx] = e->subindex;
}
(*p_result_idx)++; (*p_result_idx)++;
} else { } else {
@ -1002,15 +1034,17 @@ void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const AABB &p_aabb,
for (; I; I = I->next()) { for (; I; I = I->next()) {
Element *e = I->get(); Element *e = I->get();
if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
continue; continue;
}
e->last_pass = pass; e->last_pass = pass;
if (p_aabb.intersects_inclusive(e->aabb)) { if (p_aabb.intersects_inclusive(e->aabb)) {
if (*p_result_idx < p_result_max) { if (*p_result_idx < p_result_max) {
p_result_array[*p_result_idx] = e->userdata; p_result_array[*p_result_idx] = e->userdata;
if (p_subindex_array) if (p_subindex_array) {
p_subindex_array[*p_result_idx] = e->subindex; p_subindex_array[*p_result_idx] = e->subindex;
}
(*p_result_idx)++; (*p_result_idx)++;
} else { } else {
return; // pointless to continue return; // pointless to continue
@ -1028,8 +1062,9 @@ void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const AABB &p_aabb,
template <class T, bool use_pairs, class AL> template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::_cull_segment(Octant *p_octant, const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) { void Octree<T, use_pairs, AL>::_cull_segment(Octant *p_octant, const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
if (*p_result_idx == p_result_max) if (*p_result_idx == p_result_max) {
return; //pointless return; //pointless
}
if (!p_octant->elements.empty()) { if (!p_octant->elements.empty()) {
typename List<Element *, AL>::Element *I; typename List<Element *, AL>::Element *I;
@ -1037,15 +1072,17 @@ void Octree<T, use_pairs, AL>::_cull_segment(Octant *p_octant, const Vector3 &p_
for (; I; I = I->next()) { for (; I; I = I->next()) {
Element *e = I->get(); Element *e = I->get();
if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
continue; continue;
}
e->last_pass = pass; e->last_pass = pass;
if (e->aabb.intersects_segment(p_from, p_to)) { if (e->aabb.intersects_segment(p_from, p_to)) {
if (*p_result_idx < p_result_max) { if (*p_result_idx < p_result_max) {
p_result_array[*p_result_idx] = e->userdata; p_result_array[*p_result_idx] = e->userdata;
if (p_subindex_array) if (p_subindex_array) {
p_subindex_array[*p_result_idx] = e->subindex; p_subindex_array[*p_result_idx] = e->subindex;
}
(*p_result_idx)++; (*p_result_idx)++;
} else { } else {
@ -1061,16 +1098,18 @@ void Octree<T, use_pairs, AL>::_cull_segment(Octant *p_octant, const Vector3 &p_
for (; I; I = I->next()) { for (; I; I = I->next()) {
Element *e = I->get(); Element *e = I->get();
if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
continue; continue;
}
e->last_pass = pass; e->last_pass = pass;
if (e->aabb.intersects_segment(p_from, p_to)) { if (e->aabb.intersects_segment(p_from, p_to)) {
if (*p_result_idx < p_result_max) { if (*p_result_idx < p_result_max) {
p_result_array[*p_result_idx] = e->userdata; p_result_array[*p_result_idx] = e->userdata;
if (p_subindex_array) if (p_subindex_array) {
p_subindex_array[*p_result_idx] = e->subindex; p_subindex_array[*p_result_idx] = e->subindex;
}
(*p_result_idx)++; (*p_result_idx)++;
@ -1090,8 +1129,9 @@ void Octree<T, use_pairs, AL>::_cull_segment(Octant *p_octant, const Vector3 &p_
template <class T, bool use_pairs, class AL> template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::_cull_point(Octant *p_octant, const Vector3 &p_point, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) { void Octree<T, use_pairs, AL>::_cull_point(Octant *p_octant, const Vector3 &p_point, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
if (*p_result_idx == p_result_max) if (*p_result_idx == p_result_max) {
return; //pointless return; //pointless
}
if (!p_octant->elements.empty()) { if (!p_octant->elements.empty()) {
typename List<Element *, AL>::Element *I; typename List<Element *, AL>::Element *I;
@ -1099,15 +1139,17 @@ void Octree<T, use_pairs, AL>::_cull_point(Octant *p_octant, const Vector3 &p_po
for (; I; I = I->next()) { for (; I; I = I->next()) {
Element *e = I->get(); Element *e = I->get();
if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
continue; continue;
}
e->last_pass = pass; e->last_pass = pass;
if (e->aabb.has_point(p_point)) { if (e->aabb.has_point(p_point)) {
if (*p_result_idx < p_result_max) { if (*p_result_idx < p_result_max) {
p_result_array[*p_result_idx] = e->userdata; p_result_array[*p_result_idx] = e->userdata;
if (p_subindex_array) if (p_subindex_array) {
p_subindex_array[*p_result_idx] = e->subindex; p_subindex_array[*p_result_idx] = e->subindex;
}
(*p_result_idx)++; (*p_result_idx)++;
} else { } else {
@ -1123,16 +1165,18 @@ void Octree<T, use_pairs, AL>::_cull_point(Octant *p_octant, const Vector3 &p_po
for (; I; I = I->next()) { for (; I; I = I->next()) {
Element *e = I->get(); Element *e = I->get();
if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
continue; continue;
}
e->last_pass = pass; e->last_pass = pass;
if (e->aabb.has_point(p_point)) { if (e->aabb.has_point(p_point)) {
if (*p_result_idx < p_result_max) { if (*p_result_idx < p_result_max) {
p_result_array[*p_result_idx] = e->userdata; p_result_array[*p_result_idx] = e->userdata;
if (p_subindex_array) if (p_subindex_array) {
p_subindex_array[*p_result_idx] = e->subindex; p_subindex_array[*p_result_idx] = e->subindex;
}
(*p_result_idx)++; (*p_result_idx)++;
@ -1153,12 +1197,14 @@ void Octree<T, use_pairs, AL>::_cull_point(Octant *p_octant, const Vector3 &p_po
template <class T, bool use_pairs, class AL> template <class T, bool use_pairs, class AL>
int Octree<T, use_pairs, AL>::cull_convex(const Vector<Plane> &p_convex, T **p_result_array, int p_result_max, uint32_t p_mask) { int Octree<T, use_pairs, AL>::cull_convex(const Vector<Plane> &p_convex, T **p_result_array, int p_result_max, uint32_t p_mask) {
if (!root || p_convex.size() == 0) if (!root || p_convex.size() == 0) {
return 0; return 0;
}
Vector<Vector3> convex_points = Geometry::compute_convex_mesh_points(&p_convex[0], p_convex.size()); Vector<Vector3> convex_points = Geometry::compute_convex_mesh_points(&p_convex[0], p_convex.size());
if (convex_points.size() == 0) if (convex_points.size() == 0) {
return 0; return 0;
}
int result_count = 0; int result_count = 0;
pass++; pass++;
@ -1179,8 +1225,9 @@ int Octree<T, use_pairs, AL>::cull_convex(const Vector<Plane> &p_convex, T **p_r
template <class T, bool use_pairs, class AL> template <class T, bool use_pairs, class AL>
int Octree<T, use_pairs, AL>::cull_aabb(const AABB &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) { int Octree<T, use_pairs, AL>::cull_aabb(const AABB &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
if (!root) if (!root) {
return 0; return 0;
}
int result_count = 0; int result_count = 0;
pass++; pass++;
@ -1191,8 +1238,9 @@ int Octree<T, use_pairs, AL>::cull_aabb(const AABB &p_aabb, T **p_result_array,
template <class T, bool use_pairs, class AL> template <class T, bool use_pairs, class AL>
int Octree<T, use_pairs, AL>::cull_segment(const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) { int Octree<T, use_pairs, AL>::cull_segment(const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
if (!root) if (!root) {
return 0; return 0;
}
int result_count = 0; int result_count = 0;
pass++; pass++;
@ -1203,8 +1251,9 @@ int Octree<T, use_pairs, AL>::cull_segment(const Vector3 &p_from, const Vector3
template <class T, bool use_pairs, class AL> template <class T, bool use_pairs, class AL>
int Octree<T, use_pairs, AL>::cull_point(const Vector3 &p_point, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) { int Octree<T, use_pairs, AL>::cull_point(const Vector3 &p_point, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
if (!root) if (!root) {
return 0; return 0;
}
int result_count = 0; int result_count = 0;
pass++; pass++;

View File

@ -61,10 +61,11 @@ Vector3 Plane::get_any_perpendicular_normal() const {
static const Vector3 p2 = Vector3(0, 1, 0); static const Vector3 p2 = Vector3(0, 1, 0);
Vector3 p; Vector3 p;
if (ABS(normal.dot(p1)) > 0.99) // if too similar to p1 if (ABS(normal.dot(p1)) > 0.99) { // if too similar to p1
p = p2; // use p2 p = p2; // use p2
else } else {
p = p1; // use p1 p = p1; // use p1
}
p -= normal * normal.dot(p); p -= normal * normal.dot(p);
p.normalize(); p.normalize();
@ -82,8 +83,9 @@ bool Plane::intersect_3(const Plane &p_plane1, const Plane &p_plane2, Vector3 *r
real_t denom = vec3_cross(normal0, normal1).dot(normal2); real_t denom = vec3_cross(normal0, normal1).dot(normal2);
if (Math::is_zero_approx(denom)) if (Math::is_zero_approx(denom)) {
return false; return false;
}
if (r_result) { if (r_result) {
*r_result = ((vec3_cross(normal1, normal2) * p_plane0.d) + *r_result = ((vec3_cross(normal1, normal2) * p_plane0.d) +

View File

@ -109,10 +109,11 @@ Plane::Plane(const Vector3 &p_point, const Vector3 &p_normal) :
} }
Plane::Plane(const Vector3 &p_point1, const Vector3 &p_point2, const Vector3 &p_point3, ClockDirection p_dir) { Plane::Plane(const Vector3 &p_point1, const Vector3 &p_point2, const Vector3 &p_point3, ClockDirection p_dir) {
if (p_dir == CLOCKWISE) if (p_dir == CLOCKWISE) {
normal = (p_point1 - p_point3).cross(p_point1 - p_point2); normal = (p_point1 - p_point3).cross(p_point1 - p_point2);
else } else {
normal = (p_point1 - p_point2).cross(p_point1 - p_point3); normal = (p_point1 - p_point2).cross(p_point1 - p_point3);
}
normal.normalize(); normal.normalize();
d = normal.dot(p_point1); d = normal.dot(p_point1);

View File

@ -202,8 +202,9 @@ Quat Quat::slerpni(const Quat &q, const real_t &t) const {
real_t dot = from.dot(q); real_t dot = from.dot(q);
if (Math::absf(dot) > 0.9999) if (Math::absf(dot) > 0.9999) {
return from; return from;
}
real_t theta = Math::acos(dot), real_t theta = Math::acos(dot),
sinT = 1.0 / Math::sin(theta), sinT = 1.0 / Math::sin(theta),
@ -237,9 +238,9 @@ void Quat::set_axis_angle(const Vector3 &axis, const real_t &angle) {
ERR_FAIL_COND_MSG(!axis.is_normalized(), "The axis Vector3 must be normalized."); ERR_FAIL_COND_MSG(!axis.is_normalized(), "The axis Vector3 must be normalized.");
#endif #endif
real_t d = axis.length(); real_t d = axis.length();
if (d == 0) if (d == 0) {
set(0, 0, 0, 0); set(0, 0, 0, 0);
else { } else {
real_t sin_angle = Math::sin(angle * 0.5); real_t sin_angle = Math::sin(angle * 0.5);
real_t cos_angle = Math::cos(angle * 0.5); real_t cos_angle = Math::cos(angle * 0.5);
real_t s = sin_angle / d; real_t s = sin_angle / d;

View File

@ -75,8 +75,9 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
real_t max = 0, min = 0; real_t max = 0, min = 0;
for (int i = 0; i < p_points.size(); i++) { for (int i = 0; i < p_points.size(); i++) {
if (!valid_points[i]) if (!valid_points[i]) {
continue; continue;
}
real_t d = p_points[i][longest_axis]; real_t d = p_points[i][longest_axis];
if (i == 0 || d < min) { if (i == 0 || d < min) {
simplex[0] = i; simplex[0] = i;
@ -97,8 +98,9 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
Vector3 rel12 = p_points[simplex[0]] - p_points[simplex[1]]; Vector3 rel12 = p_points[simplex[0]] - p_points[simplex[1]];
for (int i = 0; i < p_points.size(); i++) { for (int i = 0; i < p_points.size(); i++) {
if (!valid_points[i]) if (!valid_points[i]) {
continue; continue;
}
Vector3 n = rel12.cross(p_points[simplex[0]] - p_points[i]).cross(rel12).normalized(); Vector3 n = rel12.cross(p_points[simplex[0]] - p_points[i]).cross(rel12).normalized();
real_t d = Math::abs(n.dot(p_points[simplex[0]]) - n.dot(p_points[i])); real_t d = Math::abs(n.dot(p_points[simplex[0]]) - n.dot(p_points[i]));
@ -117,8 +119,9 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
Plane p(p_points[simplex[0]], p_points[simplex[1]], p_points[simplex[2]]); Plane p(p_points[simplex[0]], p_points[simplex[1]], p_points[simplex[2]]);
for (int i = 0; i < p_points.size(); i++) { for (int i = 0; i < p_points.size(); i++) {
if (!valid_points[i]) if (!valid_points[i]) {
continue; continue;
}
real_t d = Math::abs(p.distance_to(p_points[i])); real_t d = Math::abs(p.distance_to(p_points[i]));
@ -173,16 +176,21 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
/* COMPUTE AVAILABLE VERTICES */ /* COMPUTE AVAILABLE VERTICES */
for (int i = 0; i < p_points.size(); i++) { for (int i = 0; i < p_points.size(); i++) {
if (i == simplex[0]) if (i == simplex[0]) {
continue; continue;
if (i == simplex[1]) }
if (i == simplex[1]) {
continue; continue;
if (i == simplex[2]) }
if (i == simplex[2]) {
continue; continue;
if (i == simplex[3]) }
if (i == simplex[3]) {
continue; continue;
if (!valid_points[i]) }
if (!valid_points[i]) {
continue; continue;
}
for (List<Face>::Element *E = faces.front(); E; E = E->next()) { for (List<Face>::Element *E = faces.front(); E; E = E->next()) {
if (E->get().plane.distance_to(p_points[i]) > over_tolerance) { if (E->get().plane.distance_to(p_points[i]) > over_tolerance) {
@ -288,8 +296,9 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
Face &lf = F->get()->get(); Face &lf = F->get()->get();
for (int i = 0; i < lf.points_over.size(); i++) { for (int i = 0; i < lf.points_over.size(); i++) {
if (lf.points_over[i] == f.points_over[next]) //do not add current one if (lf.points_over[i] == f.points_over[next]) { //do not add current one
continue; continue;
}
Vector3 p = p_points[lf.points_over[i]]; Vector3 p = p_points[lf.points_over[i]];
for (List<List<Face>::Element *>::Element *E = new_faces.front(); E; E = E->next()) { for (List<List<Face>::Element *>::Element *E = new_faces.front(); E; E = E->next()) {
@ -397,10 +406,11 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
Map<Edge, RetFaceConnect>::Element *F2 = ret_edges.find(e2); Map<Edge, RetFaceConnect>::Element *F2 = ret_edges.find(e2);
ERR_CONTINUE(!F2); ERR_CONTINUE(!F2);
//change faceconnect, point to this face instead //change faceconnect, point to this face instead
if (F2->get().left == O) if (F2->get().left == O) {
F2->get().left = E; F2->get().left = E;
else if (F2->get().right == O) } else if (F2->get().right == O) {
F2->get().right = E; F2->get().right = E;
}
} }
break; break;
@ -409,11 +419,13 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
// remove all edge connections to this face // remove all edge connections to this face
for (Map<Edge, RetFaceConnect>::Element *G = ret_edges.front(); G; G = G->next()) { for (Map<Edge, RetFaceConnect>::Element *G = ret_edges.front(); G; G = G->next()) {
if (G->get().left == O) if (G->get().left == O) {
G->get().left = nullptr; G->get().left = nullptr;
}
if (G->get().right == O) if (G->get().right == O) {
G->get().right = nullptr; G->get().right = nullptr;
}
} }
ret_edges.erase(F); //remove the edge ret_edges.erase(F); //remove the edge

View File

@ -59,10 +59,11 @@ public:
_FORCE_INLINE_ int randi_range(int from, int to) { _FORCE_INLINE_ int randi_range(int from, int to) {
unsigned int ret = randbase.rand(); unsigned int ret = randbase.rand();
if (to < from) if (to < from) {
return ret % (from - to + 1) + to; return ret % (from - to + 1) + to;
else } else {
return ret % (to - from + 1) + from; return ret % (to - from + 1) + from;
}
} }
RandomNumberGenerator() {} RandomNumberGenerator() {}

View File

@ -48,16 +48,18 @@ bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2
real_t csign; real_t csign;
if (seg_from < seg_to) { if (seg_from < seg_to) {
if (seg_from > box_end || seg_to < box_begin) if (seg_from > box_end || seg_to < box_begin) {
return false; return false;
}
real_t length = seg_to - seg_from; real_t length = seg_to - seg_from;
cmin = (seg_from < box_begin) ? ((box_begin - seg_from) / length) : 0; cmin = (seg_from < box_begin) ? ((box_begin - seg_from) / length) : 0;
cmax = (seg_to > box_end) ? ((box_end - seg_from) / length) : 1; cmax = (seg_to > box_end) ? ((box_end - seg_from) / length) : 1;
csign = -1.0; csign = -1.0;
} else { } else {
if (seg_to > box_end || seg_from < box_begin) if (seg_to > box_end || seg_from < box_begin) {
return false; return false;
}
real_t length = seg_to - seg_from; real_t length = seg_to - seg_from;
cmin = (seg_from > box_end) ? (box_end - seg_from) / length : 0; cmin = (seg_from > box_end) ? (box_end - seg_from) / length : 0;
cmax = (seg_to < box_begin) ? (box_begin - seg_from) / length : 1; cmax = (seg_to < box_begin) ? (box_begin - seg_from) / length : 1;
@ -69,10 +71,12 @@ bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2
axis = i; axis = i;
sign = csign; sign = csign;
} }
if (cmax < max) if (cmax < max) {
max = cmax; max = cmax;
if (max < min) }
if (max < min) {
return false; return false;
}
} }
Vector2 rel = p_to - p_from; Vector2 rel = p_to - p_from;
@ -83,8 +87,9 @@ bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2
*r_normal = normal; *r_normal = normal;
} }
if (r_pos) if (r_pos) {
*r_pos = p_from + rel * min; *r_pos = p_from + rel * min;
}
return true; return true;
} }
@ -103,14 +108,18 @@ bool Rect2::intersects_transformed(const Transform2D &p_xform, const Rect2 &p_re
//base rect2 first (faster) //base rect2 first (faster)
if (xf_points[0].y > position.y) if (xf_points[0].y > position.y) {
goto next1; goto next1;
if (xf_points[1].y > position.y) }
if (xf_points[1].y > position.y) {
goto next1; goto next1;
if (xf_points[2].y > position.y) }
if (xf_points[2].y > position.y) {
goto next1; goto next1;
if (xf_points[3].y > position.y) }
if (xf_points[3].y > position.y) {
goto next1; goto next1;
}
return false; return false;
@ -118,27 +127,35 @@ next1:
low_limit = position.y + size.y; low_limit = position.y + size.y;
if (xf_points[0].y < low_limit) if (xf_points[0].y < low_limit) {
goto next2; goto next2;
if (xf_points[1].y < low_limit) }
if (xf_points[1].y < low_limit) {
goto next2; goto next2;
if (xf_points[2].y < low_limit) }
if (xf_points[2].y < low_limit) {
goto next2; goto next2;
if (xf_points[3].y < low_limit) }
if (xf_points[3].y < low_limit) {
goto next2; goto next2;
}
return false; return false;
next2: next2:
if (xf_points[0].x > position.x) if (xf_points[0].x > position.x) {
goto next3; goto next3;
if (xf_points[1].x > position.x) }
if (xf_points[1].x > position.x) {
goto next3; goto next3;
if (xf_points[2].x > position.x) }
if (xf_points[2].x > position.x) {
goto next3; goto next3;
if (xf_points[3].x > position.x) }
if (xf_points[3].x > position.x) {
goto next3; goto next3;
}
return false; return false;
@ -146,14 +163,18 @@ next3:
low_limit = position.x + size.x; low_limit = position.x + size.x;
if (xf_points[0].x < low_limit) if (xf_points[0].x < low_limit) {
goto next4; goto next4;
if (xf_points[1].x < low_limit) }
if (xf_points[1].x < low_limit) {
goto next4; goto next4;
if (xf_points[2].x < low_limit) }
if (xf_points[2].x < low_limit) {
goto next4; goto next4;
if (xf_points[3].x < low_limit) }
if (xf_points[3].x < low_limit) {
goto next4; goto next4;
}
return false; return false;
@ -196,10 +217,12 @@ next4:
maxb = MAX(dp, maxb); maxb = MAX(dp, maxb);
minb = MIN(dp, minb); minb = MIN(dp, minb);
if (mina > maxb) if (mina > maxb) {
return false; return false;
if (minb > maxa) }
if (minb > maxa) {
return false; return false;
}
maxa = p_xform.elements[1].dot(xf_points2[0]); maxa = p_xform.elements[1].dot(xf_points2[0]);
mina = maxa; mina = maxa;
@ -231,10 +254,12 @@ next4:
maxb = MAX(dp, maxb); maxb = MAX(dp, maxb);
minb = MIN(dp, minb); minb = MIN(dp, minb);
if (mina > maxb) if (mina > maxb) {
return false; return false;
if (minb > maxa) }
if (minb > maxa) {
return false; return false;
}
return true; return true;
} }

View File

@ -48,23 +48,31 @@ struct Rect2 {
inline bool intersects(const Rect2 &p_rect, const bool p_include_borders = false) const { inline bool intersects(const Rect2 &p_rect, const bool p_include_borders = false) const {
if (p_include_borders) { if (p_include_borders) {
if (position.x > (p_rect.position.x + p_rect.size.width)) if (position.x > (p_rect.position.x + p_rect.size.width)) {
return false; return false;
if ((position.x + size.width) < p_rect.position.x) }
if ((position.x + size.width) < p_rect.position.x) {
return false; return false;
if (position.y > (p_rect.position.y + p_rect.size.height)) }
if (position.y > (p_rect.position.y + p_rect.size.height)) {
return false; return false;
if ((position.y + size.height) < p_rect.position.y) }
if ((position.y + size.height) < p_rect.position.y) {
return false; return false;
}
} else { } else {
if (position.x >= (p_rect.position.x + p_rect.size.width)) if (position.x >= (p_rect.position.x + p_rect.size.width)) {
return false; return false;
if ((position.x + size.width) <= p_rect.position.x) }
if ((position.x + size.width) <= p_rect.position.x) {
return false; return false;
if (position.y >= (p_rect.position.y + p_rect.size.height)) }
if (position.y >= (p_rect.position.y + p_rect.size.height)) {
return false; return false;
if ((position.y + size.height) <= p_rect.position.y) }
if ((position.y + size.height) <= p_rect.position.y) {
return false; return false;
}
} }
return true; return true;
@ -95,10 +103,11 @@ struct Rect2 {
inside = false; inside = false;
} }
if (inside) if (inside) {
return 0; return 0;
else } else {
return dist; return dist;
}
} }
bool intersects_transformed(const Transform2D &p_xform, const Rect2 &p_rect) const; bool intersects_transformed(const Transform2D &p_xform, const Rect2 &p_rect) const;
@ -118,8 +127,9 @@ struct Rect2 {
Rect2 new_rect = p_rect; Rect2 new_rect = p_rect;
if (!intersects(new_rect)) if (!intersects(new_rect)) {
return Rect2(); return Rect2();
}
new_rect.position.x = MAX(p_rect.position.x, position.x); new_rect.position.x = MAX(p_rect.position.x, position.x);
new_rect.position.y = MAX(p_rect.position.y, position.y); new_rect.position.y = MAX(p_rect.position.y, position.y);
@ -148,15 +158,19 @@ struct Rect2 {
return new_rect; return new_rect;
}; };
inline bool has_point(const Point2 &p_point) const { inline bool has_point(const Point2 &p_point) const {
if (p_point.x < position.x) if (p_point.x < position.x) {
return false; return false;
if (p_point.y < position.y) }
if (p_point.y < position.y) {
return false; return false;
}
if (p_point.x >= (position.x + size.x)) if (p_point.x >= (position.x + size.x)) {
return false; return false;
if (p_point.y >= (position.y + size.y)) }
if (p_point.y >= (position.y + size.y)) {
return false; return false;
}
return true; return true;
} }
@ -204,15 +218,19 @@ struct Rect2 {
Vector2 begin = position; Vector2 begin = position;
Vector2 end = position + size; Vector2 end = position + size;
if (p_vector.x < begin.x) if (p_vector.x < begin.x) {
begin.x = p_vector.x; begin.x = p_vector.x;
if (p_vector.y < begin.y) }
if (p_vector.y < begin.y) {
begin.y = p_vector.y; begin.y = p_vector.y;
}
if (p_vector.x > end.x) if (p_vector.x > end.x) {
end.x = p_vector.x; end.x = p_vector.x;
if (p_vector.y > end.y) }
if (p_vector.y > end.y) {
end.y = p_vector.y; end.y = p_vector.y;
}
position = begin; position = begin;
size = end - begin; size = end - begin;
@ -247,14 +265,18 @@ struct Rect2i {
int get_area() const { return size.width * size.height; } int get_area() const { return size.width * size.height; }
inline bool intersects(const Rect2i &p_rect) const { inline bool intersects(const Rect2i &p_rect) const {
if (position.x > (p_rect.position.x + p_rect.size.width)) if (position.x > (p_rect.position.x + p_rect.size.width)) {
return false; return false;
if ((position.x + size.width) < p_rect.position.x) }
if ((position.x + size.width) < p_rect.position.x) {
return false; return false;
if (position.y > (p_rect.position.y + p_rect.size.height)) }
if (position.y > (p_rect.position.y + p_rect.size.height)) {
return false; return false;
if ((position.y + size.height) < p_rect.position.y) }
if ((position.y + size.height) < p_rect.position.y) {
return false; return false;
}
return true; return true;
} }
@ -272,8 +294,9 @@ struct Rect2i {
Rect2i new_rect = p_rect; Rect2i new_rect = p_rect;
if (!intersects(new_rect)) if (!intersects(new_rect)) {
return Rect2i(); return Rect2i();
}
new_rect.position.x = MAX(p_rect.position.x, position.x); new_rect.position.x = MAX(p_rect.position.x, position.x);
new_rect.position.y = MAX(p_rect.position.y, position.y); new_rect.position.y = MAX(p_rect.position.y, position.y);
@ -302,15 +325,19 @@ struct Rect2i {
return new_rect; return new_rect;
}; };
bool has_point(const Point2 &p_point) const { bool has_point(const Point2 &p_point) const {
if (p_point.x < position.x) if (p_point.x < position.x) {
return false; return false;
if (p_point.y < position.y) }
if (p_point.y < position.y) {
return false; return false;
}
if (p_point.x >= (position.x + size.x)) if (p_point.x >= (position.x + size.x)) {
return false; return false;
if (p_point.y >= (position.y + size.y)) }
if (p_point.y >= (position.y + size.y)) {
return false; return false;
}
return true; return true;
} }
@ -356,15 +383,19 @@ struct Rect2i {
Point2i begin = position; Point2i begin = position;
Point2i end = position + size; Point2i end = position + size;
if (p_vector.x < begin.x) if (p_vector.x < begin.x) {
begin.x = p_vector.x; begin.x = p_vector.x;
if (p_vector.y < begin.y) }
if (p_vector.y < begin.y) {
begin.y = p_vector.y; begin.y = p_vector.y;
}
if (p_vector.x > end.x) if (p_vector.x > end.x) {
end.x = p_vector.x; end.x = p_vector.x;
if (p_vector.y > end.y) }
if (p_vector.y > end.y) {
end.y = p_vector.y; end.y = p_vector.y;
}
position = begin; position = begin;
size = end - begin; size = end - begin;

View File

@ -165,8 +165,9 @@ bool Transform2D::is_equal_approx(const Transform2D &p_transform) const {
bool Transform2D::operator==(const Transform2D &p_transform) const { bool Transform2D::operator==(const Transform2D &p_transform) const {
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
if (elements[i] != p_transform.elements[i]) if (elements[i] != p_transform.elements[i]) {
return false; return false;
}
} }
return true; return true;
@ -174,8 +175,9 @@ bool Transform2D::operator==(const Transform2D &p_transform) const {
bool Transform2D::operator!=(const Transform2D &p_transform) const { bool Transform2D::operator!=(const Transform2D &p_transform) const {
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
if (elements[i] != p_transform.elements[i]) if (elements[i] != p_transform.elements[i]) {
return true; return true;
}
} }
return false; return false;

View File

@ -85,8 +85,9 @@ int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, in
} }
void TriangleMesh::get_indices(Vector<int> *r_triangles_indices) const { void TriangleMesh::get_indices(Vector<int> *r_triangles_indices) const {
if (!valid) if (!valid) {
return; return;
}
const int triangles_num = triangles.size(); const int triangles_num = triangles.size();
@ -139,10 +140,11 @@ void TriangleMesh::create(const Vector<Vector3> &p_faces) {
} }
f.indices[j] = vidx; f.indices[j] = vidx;
if (j == 0) if (j == 0) {
bw[i].aabb.position = vs; bw[i].aabb.position = vs;
else } else {
bw[i].aabb.expand_to(vs); bw[i].aabb.expand_to(vs);
}
} }
f.normal = Face3(r[i * 3 + 0], r[i * 3 + 1], r[i * 3 + 2]).get_plane().get_normal(); f.normal = Face3(r[i * 3 + 0], r[i * 3 + 1], r[i * 3 + 2]).get_plane().get_normal();
@ -243,18 +245,21 @@ Vector3 TriangleMesh::get_area_normal(const AABB &p_aabb) const {
if (level == 0) { if (level == 0) {
done = true; done = true;
break; break;
} else } else {
level--; level--;
}
continue; continue;
} }
} }
if (done) if (done) {
break; break;
}
} }
if (n_count > 0) if (n_count > 0) {
n /= n_count; n /= n_count;
}
return n; return n;
} }
@ -340,19 +345,22 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en
if (level == 0) { if (level == 0) {
done = true; done = true;
break; break;
} else } else {
level--; level--;
}
continue; continue;
} }
} }
if (done) if (done) {
break; break;
}
} }
if (inters) { if (inters) {
if (n.dot(r_normal) > 0) if (n.dot(r_normal) > 0) {
r_normal = -r_normal; r_normal = -r_normal;
}
} }
return inters; return inters;
@ -437,19 +445,22 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V
if (level == 0) { if (level == 0) {
done = true; done = true;
break; break;
} else } else {
level--; level--;
}
continue; continue;
} }
} }
if (done) if (done) {
break; break;
}
} }
if (inters) { if (inters) {
if (n.dot(r_normal) > 0) if (n.dot(r_normal) > 0) {
r_normal = -r_normal; r_normal = -r_normal;
}
} }
return inters; return inters;
@ -506,16 +517,18 @@ bool TriangleMesh::intersect_convex_shape(const Plane *p_planes, int p_plane_cou
if (p.intersects_segment(point, next_point, &res)) { if (p.intersects_segment(point, next_point, &res)) {
bool inisde = true; bool inisde = true;
for (int k = 0; k < p_plane_count; k++) { for (int k = 0; k < p_plane_count; k++) {
if (k == i) if (k == i) {
continue; continue;
}
const Plane &pp = p_planes[k]; const Plane &pp = p_planes[k];
if (pp.is_point_over(res)) { if (pp.is_point_over(res)) {
inisde = false; inisde = false;
break; break;
} }
} }
if (inisde) if (inisde) {
return true; return true;
}
} }
if (p.is_point_over(point)) { if (p.is_point_over(point)) {
@ -523,8 +536,9 @@ bool TriangleMesh::intersect_convex_shape(const Plane *p_planes, int p_plane_cou
break; break;
} }
} }
if (over) if (over) {
return true; return true;
}
} }
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
@ -551,14 +565,16 @@ bool TriangleMesh::intersect_convex_shape(const Plane *p_planes, int p_plane_cou
if (level == 0) { if (level == 0) {
done = true; done = true;
break; break;
} else } else {
level--; level--;
}
continue; continue;
} }
} }
if (done) if (done) {
break; break;
}
} }
return false; return false;
@ -597,8 +613,9 @@ bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count,
switch (stack[level] >> VISITED_BIT_SHIFT) { switch (stack[level] >> VISITED_BIT_SHIFT) {
case TEST_AABB_BIT: { case TEST_AABB_BIT: {
bool intersects = scale.xform(b.aabb).intersects_convex_shape(p_planes, p_plane_count, p_points, p_point_count); bool intersects = scale.xform(b.aabb).intersects_convex_shape(p_planes, p_plane_count, p_points, p_point_count);
if (!intersects) if (!intersects) {
return false; return false;
}
bool inside = scale.xform(b.aabb).inside_convex_shape(p_planes, p_plane_count); bool inside = scale.xform(b.aabb).inside_convex_shape(p_planes, p_plane_count);
if (inside) { if (inside) {
@ -611,8 +628,9 @@ bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count,
Vector3 point = scale.xform(vertexptr[s.indices[j]]); Vector3 point = scale.xform(vertexptr[s.indices[j]]);
for (int i = 0; i < p_plane_count; i++) { for (int i = 0; i < p_plane_count; i++) {
const Plane &p = p_planes[i]; const Plane &p = p_planes[i];
if (p.is_point_over(point)) if (p.is_point_over(point)) {
return false; return false;
}
} }
} }
@ -640,14 +658,16 @@ bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count,
if (level == 0) { if (level == 0) {
done = true; done = true;
break; break;
} else } else {
level--; level--;
}
continue; continue;
} }
} }
if (done) if (done) {
break; break;
}
} }
return true; return true;
@ -658,8 +678,9 @@ bool TriangleMesh::is_valid() const {
} }
Vector<Face3> TriangleMesh::get_faces() const { Vector<Face3> TriangleMesh::get_faces() const {
if (!valid) if (!valid) {
return Vector<Face3>(); return Vector<Face3>();
}
Vector<Face3> faces; Vector<Face3> faces;
int ts = triangles.size(); int ts = triangles.size();

View File

@ -102,16 +102,19 @@ bool Triangulate::snip(const Vector<Vector2> &p_contour, int u, int v, int w, in
// To avoid that we allow zero-area triangles if all else failed. // To avoid that we allow zero-area triangles if all else failed.
float threshold = relaxed ? -CMP_EPSILON : CMP_EPSILON; float threshold = relaxed ? -CMP_EPSILON : CMP_EPSILON;
if (threshold > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax)))) if (threshold > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax)))) {
return false; return false;
}
for (p = 0; p < n; p++) { for (p = 0; p < n; p++) {
if ((p == u) || (p == v) || (p == w)) if ((p == u) || (p == v) || (p == w)) {
continue; continue;
}
Px = contour[V[p]].x; Px = contour[V[p]].x;
Py = contour[V[p]].y; Py = contour[V[p]].y;
if (is_inside_triangle(Ax, Ay, Bx, By, Cx, Cy, Px, Py, relaxed)) if (is_inside_triangle(Ax, Ay, Bx, By, Cx, Cy, Px, Py, relaxed)) {
return false; return false;
}
} }
return true; return true;
@ -121,20 +124,24 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul
/* allocate and initialize list of Vertices in polygon */ /* allocate and initialize list of Vertices in polygon */
int n = contour.size(); int n = contour.size();
if (n < 3) if (n < 3) {
return false; return false;
}
Vector<int> V; Vector<int> V;
V.resize(n); V.resize(n);
/* we want a counter-clockwise polygon in V */ /* we want a counter-clockwise polygon in V */
if (0.0 < get_area(contour)) if (0.0 < get_area(contour)) {
for (int v = 0; v < n; v++) for (int v = 0; v < n; v++) {
V.write[v] = v; V.write[v] = v;
else }
for (int v = 0; v < n; v++) } else {
for (int v = 0; v < n; v++) {
V.write[v] = (n - 1) - v; V.write[v] = (n - 1) - v;
}
}
bool relaxed = false; bool relaxed = false;
@ -164,14 +171,17 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul
/* three consecutive vertices in current polygon, <u,v,w> */ /* three consecutive vertices in current polygon, <u,v,w> */
int u = v; int u = v;
if (nv <= u) if (nv <= u) {
u = 0; /* previous */ u = 0; /* previous */
}
v = u + 1; v = u + 1;
if (nv <= v) if (nv <= v) {
v = 0; /* new v */ v = 0; /* new v */
}
int w = v + 1; int w = v + 1;
if (nv <= w) if (nv <= w) {
w = 0; /* next */ w = 0; /* next */
}
if (snip(contour, u, v, w, nv, V, relaxed)) { if (snip(contour, u, v, w, nv, V, relaxed)) {
int a, b, c, s, t; int a, b, c, s, t;
@ -187,8 +197,9 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul
result.push_back(c); result.push_back(c);
/* remove v from remaining polygon */ /* remove v from remaining polygon */
for (s = v, t = v + 1; t < nv; s++, t++) for (s = v, t = v + 1; t < nv; s++, t++) {
V.write[s] = V[t]; V.write[s] = V[t];
}
nv--; nv--;

View File

@ -85,10 +85,12 @@ Vector3 Vector3::cubic_interpolaten(const Vector3 &p_b, const Vector3 &p_pre_a,
real_t bc = p1.distance_to(p2); real_t bc = p1.distance_to(p2);
real_t cd = p2.distance_to(p3); real_t cd = p2.distance_to(p3);
if (ab > 0) if (ab > 0) {
p0 = p1 + (p0 - p1) * (bc / ab); p0 = p1 + (p0 - p1) * (bc / ab);
if (cd > 0) }
if (cd > 0) {
p3 = p2 + (p3 - p2) * (bc / cd); p3 = p2 + (p3 - p2) * (bc / cd);
}
} }
real_t t = p_t; real_t t = p_t;

View File

@ -323,10 +323,11 @@ bool Vector3::operator!=(const Vector3 &p_v) const {
bool Vector3::operator<(const Vector3 &p_v) const { bool Vector3::operator<(const Vector3 &p_v) const {
if (Math::is_equal_approx(x, p_v.x)) { if (Math::is_equal_approx(x, p_v.x)) {
if (Math::is_equal_approx(y, p_v.y)) if (Math::is_equal_approx(y, p_v.y)) {
return z < p_v.z; return z < p_v.z;
else } else {
return y < p_v.y; return y < p_v.y;
}
} else { } else {
return x < p_v.x; return x < p_v.x;
} }
@ -334,10 +335,11 @@ bool Vector3::operator<(const Vector3 &p_v) const {
bool Vector3::operator>(const Vector3 &p_v) const { bool Vector3::operator>(const Vector3 &p_v) const {
if (Math::is_equal_approx(x, p_v.x)) { if (Math::is_equal_approx(x, p_v.x)) {
if (Math::is_equal_approx(y, p_v.y)) if (Math::is_equal_approx(y, p_v.y)) {
return z > p_v.z; return z > p_v.z;
else } else {
return y > p_v.y; return y > p_v.y;
}
} else { } else {
return x > p_v.x; return x > p_v.x;
} }
@ -345,10 +347,11 @@ bool Vector3::operator>(const Vector3 &p_v) const {
bool Vector3::operator<=(const Vector3 &p_v) const { bool Vector3::operator<=(const Vector3 &p_v) const {
if (Math::is_equal_approx(x, p_v.x)) { if (Math::is_equal_approx(x, p_v.x)) {
if (Math::is_equal_approx(y, p_v.y)) if (Math::is_equal_approx(y, p_v.y)) {
return z <= p_v.z; return z <= p_v.z;
else } else {
return y < p_v.y; return y < p_v.y;
}
} else { } else {
return x < p_v.x; return x < p_v.x;
} }
@ -356,10 +359,11 @@ bool Vector3::operator<=(const Vector3 &p_v) const {
bool Vector3::operator>=(const Vector3 &p_v) const { bool Vector3::operator>=(const Vector3 &p_v) const {
if (Math::is_equal_approx(x, p_v.x)) { if (Math::is_equal_approx(x, p_v.x)) {
if (Math::is_equal_approx(y, p_v.y)) if (Math::is_equal_approx(y, p_v.y)) {
return z >= p_v.z; return z >= p_v.z;
else } else {
return y > p_v.y; return y > p_v.y;
}
} else { } else {
return x > p_v.x; return x > p_v.x;
} }

View File

@ -199,10 +199,11 @@ bool Vector3i::operator!=(const Vector3i &p_v) const {
bool Vector3i::operator<(const Vector3i &p_v) const { bool Vector3i::operator<(const Vector3i &p_v) const {
if (x == p_v.x) { if (x == p_v.x) {
if (y == p_v.y) if (y == p_v.y) {
return z < p_v.z; return z < p_v.z;
else } else {
return y < p_v.y; return y < p_v.y;
}
} else { } else {
return x < p_v.x; return x < p_v.x;
} }
@ -210,10 +211,11 @@ bool Vector3i::operator<(const Vector3i &p_v) const {
bool Vector3i::operator>(const Vector3i &p_v) const { bool Vector3i::operator>(const Vector3i &p_v) const {
if (x == p_v.x) { if (x == p_v.x) {
if (y == p_v.y) if (y == p_v.y) {
return z > p_v.z; return z > p_v.z;
else } else {
return y > p_v.y; return y > p_v.y;
}
} else { } else {
return x > p_v.x; return x > p_v.x;
} }
@ -221,10 +223,11 @@ bool Vector3i::operator>(const Vector3i &p_v) const {
bool Vector3i::operator<=(const Vector3i &p_v) const { bool Vector3i::operator<=(const Vector3i &p_v) const {
if (x == p_v.x) { if (x == p_v.x) {
if (y == p_v.y) if (y == p_v.y) {
return z <= p_v.z; return z <= p_v.z;
else } else {
return y < p_v.y; return y < p_v.y;
}
} else { } else {
return x < p_v.x; return x < p_v.x;
} }
@ -232,10 +235,11 @@ bool Vector3i::operator<=(const Vector3i &p_v) const {
bool Vector3i::operator>=(const Vector3i &p_v) const { bool Vector3i::operator>=(const Vector3i &p_v) const {
if (x == p_v.x) { if (x == p_v.x) {
if (y == p_v.y) if (y == p_v.y) {
return z >= p_v.z; return z >= p_v.z;
else } else {
return y > p_v.y; return y > p_v.y;
}
} else { } else {
return x > p_v.x; return x > p_v.x;
} }

View File

@ -50,8 +50,9 @@ Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, VARIANT
int argc = 0; int argc = 0;
for (int i = 0; i < VARIANT_ARG_MAX; i++) { for (int i = 0; i < VARIANT_ARG_MAX; i++) {
if (argptr[i]->get_type() == Variant::NIL) if (argptr[i]->get_type() == Variant::NIL) {
break; break;
}
argc++; argc++;
} }
@ -65,8 +66,9 @@ Error MessageQueue::push_set(ObjectID p_id, const StringName &p_prop, const Vari
if ((buffer_end + room_needed) >= buffer_size) { if ((buffer_end + room_needed) >= buffer_size) {
String type; String type;
if (ObjectDB::get_instance(p_id)) if (ObjectDB::get_instance(p_id)) {
type = ObjectDB::get_instance(p_id)->get_class(); type = ObjectDB::get_instance(p_id)->get_class();
}
print_line("Failed set: " + type + ":" + p_prop + " target ID: " + itos(p_id)); print_line("Failed set: " + type + ":" + p_prop + " target ID: " + itos(p_id));
statistics(); statistics();
ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings."); ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings.");
@ -138,8 +140,9 @@ Error MessageQueue::push_callable(const Callable &p_callable, const Variant **p_
msg->args = p_argcount; msg->args = p_argcount;
msg->callable = p_callable; msg->callable = p_callable;
msg->type = TYPE_CALL; msg->type = TYPE_CALL;
if (p_show_error) if (p_show_error) {
msg->type |= FLAG_SHOW_ERROR; msg->type |= FLAG_SHOW_ERROR;
}
buffer_end += sizeof(Message); buffer_end += sizeof(Message);
@ -167,23 +170,26 @@ void MessageQueue::statistics() {
if (target != nullptr) { if (target != nullptr) {
switch (message->type & FLAG_MASK) { switch (message->type & FLAG_MASK) {
case TYPE_CALL: { case TYPE_CALL: {
if (!call_count.has(message->callable)) if (!call_count.has(message->callable)) {
call_count[message->callable] = 0; call_count[message->callable] = 0;
}
call_count[message->callable]++; call_count[message->callable]++;
} break; } break;
case TYPE_NOTIFICATION: { case TYPE_NOTIFICATION: {
if (!notify_count.has(message->notification)) if (!notify_count.has(message->notification)) {
notify_count[message->notification] = 0; notify_count[message->notification] = 0;
}
notify_count[message->notification]++; notify_count[message->notification]++;
} break; } break;
case TYPE_SET: { case TYPE_SET: {
StringName t = message->callable.get_method(); StringName t = message->callable.get_method();
if (!set_count.has(t)) if (!set_count.has(t)) {
set_count[t] = 0; set_count[t] = 0;
}
set_count[t]++; set_count[t]++;
@ -198,8 +204,9 @@ void MessageQueue::statistics() {
} }
read_pos += sizeof(Message); read_pos += sizeof(Message);
if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) {
read_pos += sizeof(Variant) * message->args; read_pos += sizeof(Variant) * message->args;
}
} }
print_line("TOTAL BYTES: " + itos(buffer_end)); print_line("TOTAL BYTES: " + itos(buffer_end));
@ -261,8 +268,9 @@ void MessageQueue::flush() {
Message *message = (Message *)&buffer[read_pos]; Message *message = (Message *)&buffer[read_pos];
uint32_t advance = sizeof(Message); uint32_t advance = sizeof(Message);
if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) {
advance += sizeof(Variant) * message->args; advance += sizeof(Variant) * message->args;
}
//pre-advance so this function is reentrant //pre-advance so this function is reentrant
read_pos += advance; read_pos += advance;
@ -334,14 +342,16 @@ MessageQueue::~MessageQueue() {
Variant *args = (Variant *)(message + 1); Variant *args = (Variant *)(message + 1);
int argc = message->args; int argc = message->args;
if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) { if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) {
for (int i = 0; i < argc; i++) for (int i = 0; i < argc; i++) {
args[i].~Variant(); args[i].~Variant();
}
} }
message->~Message(); message->~Message();
read_pos += sizeof(Message); read_pos += sizeof(Message);
if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) {
read_pos += sizeof(Variant) * message->args; read_pos += sizeof(Variant) * message->args;
}
} }
singleton = nullptr; singleton = nullptr;

View File

@ -103,7 +103,8 @@ MethodBind::MethodBind() {
MethodBind::~MethodBind() { MethodBind::~MethodBind() {
#ifdef DEBUG_METHODS_ENABLED #ifdef DEBUG_METHODS_ENABLED
if (argument_types) if (argument_types) {
memdelete_arr(argument_types); memdelete_arr(argument_types);
}
#endif #endif
} }

Some files were not shown because too many files have changed in this diff Show More