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 2021-05-05 12:44:11 +02:00
parent b8d198eeed
commit 140350d767
No known key found for this signature in database
GPG key ID: C3336907360768E1
694 changed files with 23283 additions and 12499 deletions

View file

@ -1,5 +1,5 @@
--- ---
Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-nullptr' Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-nullptr,readability-braces-around-statements'
WarningsAsErrors: '' WarningsAsErrors: ''
HeaderFilterRegex: '.*' HeaderFilterRegex: '.*'
AnalyzeTemporaryDtors: false AnalyzeTemporaryDtors: false

View file

@ -46,8 +46,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();
@ -59,8 +60,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);
@ -136,8 +138,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;
}
if (p_from < 0) { if (p_from < 0) {
// Relative offset from the end // Relative offset from the end
@ -162,8 +165,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 {
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++) {
@ -217,14 +221,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);
@ -255,8 +262,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;
} }
}; };
@ -274,8 +282,9 @@ struct _ArrayVariantSortCustom {
const Variant *args[2] = { &p_l, &p_r }; const Variant *args[2] = { &p_l, &p_r };
Variant::CallError err; Variant::CallError err;
bool res = obj->call(func, args, 2, err); bool res = obj->call(func, args, 2, err);
if (err.error != Variant::CallError::CALL_OK) if (err.error != Variant::CallError::CALL_OK) {
res = false; res = false;
}
return res; return res;
} }
}; };
@ -291,8 +300,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

@ -475,18 +475,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) {
@ -959,8 +961,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");
@ -995,11 +998,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;
@ -1542,17 +1547,19 @@ 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 {
@ -1562,8 +1569,9 @@ bool _Geometry::point_is_inside_triangle(const Vector2 &s, const Vector2 &a, con
PoolVector<Vector3> _Geometry::segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius) { PoolVector<Vector3> _Geometry::segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius) {
PoolVector<Vector3> r; PoolVector<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);
@ -1573,8 +1581,9 @@ PoolVector<Vector3> _Geometry::segment_intersects_sphere(const Vector3 &p_from,
PoolVector<Vector3> _Geometry::segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius) { PoolVector<Vector3> _Geometry::segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius) {
PoolVector<Vector3> r; PoolVector<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);
@ -1584,8 +1593,9 @@ PoolVector<Vector3> _Geometry::segment_intersects_cylinder(const Vector3 &p_from
PoolVector<Vector3> _Geometry::segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes) { PoolVector<Vector3> _Geometry::segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes) {
PoolVector<Vector3> r; PoolVector<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);
@ -1805,8 +1815,9 @@ _Geometry::_Geometry() {
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);
@ -1821,8 +1832,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);
@ -1856,8 +1868,9 @@ 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;
} }
@ -1867,8 +1880,9 @@ void _File::flush() {
} }
void _File::close() { void _File::close() {
if (f) if (f) {
memdelete(f); memdelete(f);
}
f = nullptr; f = nullptr;
} }
bool _File::is_open() const { bool _File::is_open() const {
@ -1942,8 +1956,9 @@ PoolVector<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.");
@ -1954,8 +1969,9 @@ PoolVector<uint8_t> _File::get_buffer(int p_length) const {
w.release(); w.release();
if (len < p_length) if (len < p_length) {
data.resize(p_length); data.resize(p_length);
}
return data; return data;
} }
@ -2004,16 +2020,18 @@ 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() {
return eswap; return eswap;
} }
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();
} }
@ -2086,8 +2104,9 @@ void _File::store_buffer(const PoolVector<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;
}
PoolVector<uint8_t>::Read r = p_buffer.read(); PoolVector<uint8_t>::Read r = p_buffer.read();
@ -2207,8 +2226,9 @@ _File::_File() {
} }
_File::~_File() { _File::~_File() {
if (f) if (f) {
memdelete(f); memdelete(f);
}
} }
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
@ -2217,10 +2237,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;
@ -2380,8 +2402,9 @@ _Directory::_Directory() {
} }
_Directory::~_Directory() { _Directory::~_Directory() {
if (d) if (d) {
memdelete(d); memdelete(d);
}
} }
_Marshalls *_Marshalls::singleton = nullptr; _Marshalls *_Marshalls::singleton = nullptr;
@ -2656,8 +2679,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

@ -257,8 +257,9 @@ bool ClassDB::_is_parent_class(const StringName &p_class, const StringName &p_in
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);
} }
@ -289,8 +290,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);
}
} }
} }
@ -300,8 +302,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);
}
} }
} }
@ -309,8 +312,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;
} }
@ -354,8 +358,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);
@ -370,8 +375,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);
} }
@ -555,8 +561,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;
@ -574,8 +581,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);
@ -587,8 +595,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);
@ -607,8 +616,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;
} }
@ -621,8 +631,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;
@ -670,8 +681,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 = NULL; const StringName *K = NULL;
@ -680,8 +692,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;
} }
@ -695,16 +708,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;
} }
@ -719,12 +734,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;
} }
@ -743,8 +760,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;
} }
@ -764,8 +782,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;
} }
@ -804,8 +823,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;
} }
@ -816,8 +836,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;
} }
@ -929,8 +950,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;
} }
} }
@ -943,8 +965,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
} }
@ -969,8 +992,9 @@ bool ClassDB::set_property(Object *p_object, const StringName &p_property, const
} }
} }
if (r_valid) if (r_valid) {
*r_valid = ce.error == Variant::CallError::CALL_OK; *r_valid = ce.error == Variant::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;
@ -1026,16 +1051,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;
} }
@ -1046,16 +1073,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;
} }
@ -1094,11 +1123,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;
} }
@ -1118,10 +1149,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;
} }
@ -1192,8 +1225,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
@ -1211,8 +1245,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;
} }
@ -1258,8 +1293,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;
} }
@ -1277,8 +1313,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);
}
} }
} }
@ -1323,19 +1360,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;
} }
@ -276,10 +279,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;
@ -299,10 +303,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++) {
@ -343,10 +349,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;
@ -384,8 +392,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(" ", "");
@ -408,10 +417,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;
@ -426,8 +436,9 @@ 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;
} }

View file

@ -217,12 +217,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 #endif

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

@ -115,7 +115,8 @@ CommandQueueMT::CommandQueueMT(bool p_sync) {
} }
CommandQueueMT::~CommandQueueMT() { CommandQueueMT::~CommandQueueMT() {
if (sync) if (sync) {
memdelete(sync); memdelete(sync);
}
memfree(command_mem); memfree(command_mem);
} }

View file

@ -403,14 +403,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_and_epoch == write_ptr_and_epoch) { if (read_ptr_and_epoch == write_ptr_and_epoch) {
if (p_lock) if (p_lock) {
unlock(); unlock();
}
return false; return false;
} }
@ -433,18 +435,21 @@ class CommandQueueMT {
read_ptr_and_epoch = (read_ptr << 1) | (read_ptr_and_epoch & 1); read_ptr_and_epoch = (read_ptr << 1) | (read_ptr_and_epoch & 1);
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;
} }
@ -476,8 +481,9 @@ 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

@ -110,8 +110,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;
@ -190,22 +191,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;
} }
@ -213,8 +216,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

@ -63,22 +63,25 @@ private:
// internal helpers // internal helpers
_FORCE_INLINE_ SafeNumeric<uint32_t> *_get_refcount() const { _FORCE_INLINE_ SafeNumeric<uint32_t> *_get_refcount() const {
if (!_ptr) if (!_ptr) {
return nullptr; return nullptr;
}
return reinterpret_cast<SafeNumeric<uint32_t> *>(_ptr) - 2; return reinterpret_cast<SafeNumeric<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);
} }
@ -96,8 +99,9 @@ private:
return false; return false;
} }
*out = next_power_of_2(o); *out = next_power_of_2(o);
if (_add_overflow(o, static_cast<size_t>(32), &p)) if (_add_overflow(o, static_cast<size_t>(32), &p)) {
return false; //no longer allocated here return false; //no longer allocated here
}
return true; return true;
#else #else
// Speed is more important than correctness here, do the operations unchecked // Speed is more important than correctness here, do the operations unchecked
@ -126,10 +130,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); }
@ -169,8 +174,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;
@ -185,13 +191,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;
}
SafeNumeric<uint32_t> *refc = _get_refcount(); SafeNumeric<uint32_t> *refc = _get_refcount();
if (refc->decrement() > 0) if (refc->decrement() > 0) {
return; // still in use return; // still in use
}
// clean up // clean up
if (!__has_trivial_destructor(T)) { if (!__has_trivial_destructor(T)) {
@ -210,8 +218,9 @@ void CowData<T>::_unref(void *p_data) {
template <class T> template <class T>
uint32_t CowData<T>::_copy_on_write() { uint32_t CowData<T>::_copy_on_write() {
if (!_ptr) if (!_ptr) {
return 0; return 0;
}
SafeNumeric<uint32_t> *refc = _get_refcount(); SafeNumeric<uint32_t> *refc = _get_refcount();
@ -251,8 +260,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
@ -348,14 +358,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 (p_from._get_refcount()->conditional_increment() > 0) { // could reference if (p_from._get_refcount()->conditional_increment() > 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;
} }
@ -53,8 +54,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;
} }
@ -68,14 +70,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();
}
ERR_FAIL_V_MSG(nullptr, "Crypto is not available when the mbedtls module is disabled."); ERR_FAIL_V_MSG(nullptr, "Crypto is not available when the mbedtls module is disabled.");
} }
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() {
@ -97,18 +101,21 @@ 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, false); key->load(p_path, false);
}
return key; return key;
} else if (el == "pub") { } else if (el == "pub") {
CryptoKey *key = CryptoKey::create(); CryptoKey *key = CryptoKey::create();
if (key) if (key) {
key->load(p_path, true); key->load(p_path, true);
}
return key; return key;
} }
return nullptr; return nullptr;
@ -126,10 +133,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" || el == "pub") } else if (el == "key" || el == "pub") {
return "CryptoKey"; return "CryptoKey";
}
return ""; return "";
} }

View file

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

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());
@ -82,24 +83,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();
} }
@ -146,16 +150,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;
} }
@ -183,8 +189,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());
@ -199,8 +206,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());
@ -216,14 +224,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

@ -45,8 +45,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;
} }
@ -96,8 +97,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;
@ -194,8 +196,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

@ -69,12 +69,14 @@ StringName FuncRef::get_function() {
} }
bool FuncRef::is_valid() const { bool FuncRef::is_valid() const {
if (id == 0) if (id == 0) {
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 NULL; return NULL;
}
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 */
@ -514,8 +531,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) {
@ -527,8 +545,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

@ -52,8 +52,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;
} }
@ -61,8 +62,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;
} }
@ -89,12 +91,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

@ -236,12 +236,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) {
@ -358,10 +359,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
@ -407,11 +409,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;
}
ERR_FAIL_COND_MSG(write_lock.ptr(), "Cannot convert image when it is locked."); ERR_FAIL_COND_MSG(write_lock.ptr(), "Cannot convert image when it is locked.");
@ -552,8 +556,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 {
@ -565,10 +570,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;
} }
@ -615,20 +621,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;
@ -799,8 +809,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 };
@ -813,17 +824,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
}
} }
} }
@ -844,8 +857,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 };
@ -857,8 +871,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;
@ -866,12 +881,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];
}
} }
} }
} }
@ -904,8 +920,9 @@ void Image::resize_to_po2(bool p_square, Interpolation p_interpolation) {
} }
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, p_interpolation); resize(w, h, p_interpolation);
@ -923,8 +940,9 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, "Image width cannot be greater than " + itos(MAX_WIDTH) + "."); ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, "Image width cannot be greater than " + itos(MAX_WIDTH) + ".");
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) + ".");
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);
@ -1210,8 +1228,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);
} }
@ -1230,8 +1249,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);
@ -1247,8 +1267,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.ptr(), pdata); _get_pixelb(x, y, pixel_size, r.ptr(), pdata);
} }
@ -1258,8 +1279,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);
} }
@ -1352,15 +1374,17 @@ int Image::_get_dst_image_size(int p_width, int p_height, Format p_format, int &
size += s; size += s;
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);
} }
@ -1420,8 +1444,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);
}
PoolVector<uint8_t> dest; PoolVector<uint8_t> dest;
dest.resize(width * 2 * height * 2 * 4); dest.resize(width * 2 * height * 2 * 4);
@ -1439,8 +1464,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
@ -1604,17 +1630,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);
@ -1623,17 +1651,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:
@ -1643,24 +1673,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: {
@ -1678,11 +1711,13 @@ Error Image::generate_mipmaps(bool p_renormalize) {
} }
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);
@ -1786,15 +1821,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++;
} }
@ -1808,14 +1845,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:
@ -1859,8 +1897,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);
@ -1871,8 +1910,9 @@ void Image::create(const char **p_xpm) {
_put_pixelb(x, y, pixel_size, w.ptr(), pixel); _put_pixelb(x, y, pixel_size, w.ptr(), pixel);
} }
if (y == (size_height - 1)) if (y == (size_height - 1)) {
status = DONE; status = DONE;
}
} break; } break;
default: { default: {
} }
@ -1906,13 +1946,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);
@ -1952,8 +1994,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);
@ -1987,12 +2030,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) {
@ -2005,8 +2049,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));
} }
@ -2020,8 +2065,9 @@ PoolVector<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);
} }
@ -2050,18 +2096,19 @@ bool Image::is_compressed() const {
} }
Error Image::decompress() { Error Image::decompress() {
if (format >= FORMAT_DXT1 && format <= FORMAT_RGTC_RG && _image_decompress_bc) if (format >= FORMAT_DXT1 && format <= FORMAT_RGTC_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_RGB8A1 && _image_decompress_etc2) } else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RGB8A1 && _image_decompress_etc2) {
_image_decompress_etc2(this); _image_decompress_etc2(this);
else } else {
return ERR_UNAVAILABLE; return ERR_UNAVAILABLE;
}
return OK; return OK;
} }
@ -2124,38 +2171,46 @@ Image::Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const P
} }
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_RGBA5551) if (format != FORMAT_LA8 && format != FORMAT_RGBA8 && format != FORMAT_RGBAF && format != FORMAT_RGBAH && format != FORMAT_RGBA4444 && format != FORMAT_RGBA5551) {
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();
}
const_cast<Image *>(this)->lock(); const_cast<Image *>(this)->lock();
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;
}
} }
} }
const_cast<Image *>(this)->unlock(); const_cast<Image *>(this)->unlock();
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 {
@ -2175,13 +2230,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));
@ -2227,13 +2285,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));
@ -2281,13 +2342,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));
@ -2332,13 +2396,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));
@ -2706,14 +2773,18 @@ Image::DetectChannels Image::get_detected_channels() {
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;
@ -2723,19 +2794,24 @@ Image::DetectChannels Image::get_detected_channels() {
unlock(); unlock();
if (!c && !a) if (!c && !a) {
return DETECTED_L; return DETECTED_L;
if (!c && a) }
if (!c && a) {
return DETECTED_LA; return DETECTED_LA;
}
if (r && !g && !b && !a) if (r && !g && !b && !a) {
return DETECTED_R; return DETECTED_R;
}
if (r && g && !b && !a) if (r && g && !b && !a) {
return DETECTED_RG; return DETECTED_RG;
}
if (r && g && b && !a) if (r && g && b && !a) {
return DETECTED_RGB; return DETECTED_RGB;
}
return DETECTED_RGBA; return DETECTED_RGBA;
} }
@ -2929,8 +3005,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>());
@ -2977,13 +3054,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];
@ -3005,8 +3084,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 };
@ -3037,11 +3117,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
}
PoolVector<uint8_t>::Write wp = data.write(); PoolVector<uint8_t>::Write wp = data.write();
unsigned char *data_ptr = wp.ptr(); unsigned char *data_ptr = wp.ptr();
@ -3058,11 +3140,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
}
PoolVector<uint8_t> dcopy = data; PoolVector<uint8_t> dcopy = data;
PoolVector<uint8_t>::Read rp = dcopy.read(); PoolVector<uint8_t>::Read rp = dcopy.read();
@ -3080,8 +3164,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];
@ -3096,13 +3181,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

@ -100,8 +100,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());
@ -157,8 +158,9 @@ void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent
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), _suggest_actions(p_action)); ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(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);
} }
@ -201,8 +203,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;
} }
@ -217,10 +220,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;
} }
@ -228,10 +233,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;
@ -251,8 +258,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());
@ -263,8 +271,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

@ -61,8 +61,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);
@ -96,8 +97,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;
@ -110,8 +112,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 @@ PoolStringArray 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);
@ -91,8 +92,9 @@ bool ConfigFile::has_section(const String &p_section) const {
return values.has(p_section); return values.has(p_section);
} }
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);
} }
@ -126,8 +128,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;
} }
@ -138,8 +141,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);
@ -155,8 +159,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);
@ -171,8 +176,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()) {
@ -191,8 +197,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);
} }
@ -201,8 +208,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);
@ -218,8 +226,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);
@ -133,8 +135,9 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
return OK; return OK;
} }
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
@ -164,8 +167,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
@ -304,8 +308,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;
} }
} }
@ -335,22 +340,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;
} }
@ -381,6 +389,7 @@ FileAccessCompressed::FileAccessCompressed() :
} }
FileAccessCompressed::~FileAccessCompressed() { FileAccessCompressed::~FileAccessCompressed() {
if (f) if (f) {
close(); close();
}
} }

View file

@ -113,8 +113,9 @@ Error FileAccessEncrypted::_open(const String &p_path, int p_mode_flags) {
return OK; return OK;
} }
void FileAccessEncrypted::close() { void FileAccessEncrypted::close() {
if (!file) if (!file) {
return; return;
}
if (writing) { if (writing) {
Vector<uint8_t> compressed; Vector<uint8_t> compressed;
@ -164,22 +165,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;
@ -268,8 +272,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;
} }
@ -296,6 +301,7 @@ FileAccessEncrypted::FileAccessEncrypted() {
} }
FileAccessEncrypted::~FileAccessEncrypted() { FileAccessEncrypted::~FileAccessEncrypted() {
if (file) if (file) {
close(); close();
}
} }

View file

@ -42,18 +42,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

@ -114,8 +114,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: {
@ -139,8 +140,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;
@ -339,8 +344,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
@ -108,8 +110,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);
} }
@ -124,8 +127,9 @@ PackedData::~PackedData() {
bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset) { bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ); FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) if (!f) {
return false; return false;
}
f->seek(p_offset); f->seek(p_offset);
@ -263,8 +267,9 @@ int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); ERR_FAIL_COND_V(!p_dst && p_length > 0, -1);
ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V(p_length < 0, -1);
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) {
@ -274,8 +279,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;
@ -287,8 +293,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;
} }
@ -319,8 +326,9 @@ FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFil
} }
FileAccessPack::~FileAccessPack() { FileAccessPack::~FileAccessPack() {
if (f) if (f) {
memdelete(f); memdelete(f);
}
} }
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
@ -391,8 +399,9 @@ PackedData::PackedDir *DirAccessPack::_find_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("/", "");
@ -403,10 +412,11 @@ PackedData::PackedDir *DirAccessPack::_find_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

@ -182,10 +182,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

@ -151,14 +151,16 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, size_
// load with offset feature only supported for PCK files // load with offset feature only supported for PCK files
ERR_FAIL_COND_V_MSG(p_offset != 0, false, "Invalid PCK data. Note that loading files with a non-zero offset isn't supported with ZIP archives."); ERR_FAIL_COND_V_MSG(p_offset != 0, false, "Invalid PCK data. Note that loading files with a non-zero offset isn't supported with ZIP archives.");
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;
@ -255,8 +257,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);
@ -305,12 +308,14 @@ int FileAccessZip::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V(p_length < 0, -1);
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

@ -280,8 +280,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]);
@ -293,8 +294,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;
@ -433,8 +435,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();
@ -464,8 +467,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;
@ -541,8 +545,9 @@ PoolByteArray 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();
@ -564,8 +569,9 @@ PoolByteArray 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);
@ -580,13 +586,13 @@ PoolByteArray 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;
@ -655,8 +661,9 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
body_left -= rec; body_left -= rec;
} }
} }
if (err != OK) if (err != OK) {
break; break;
}
} }
} }
@ -784,8 +791,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_PRINTS("Error loading image: " + p_file); ERR_PRINTS("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.get() == IP::RESOLVER_STATUS_NONE) if (queue[i].status.get() == 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.get() != IP::RESOLVER_STATUS_WAITING) if (queue[i].status.get() != 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.set(IP::RESOLVER_STATUS_ERROR); queue[i].status.set(IP::RESOLVER_STATUS_ERROR);
else } else {
queue[i].status.set(IP::RESOLVER_STATUS_DONE); queue[i].status.set(IP::RESOLVER_STATUS_DONE);
}
} }
} }
@ -142,10 +145,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.set(IP::RESOLVER_STATUS_WAITING); resolver->queue[id].status.set(IP::RESOLVER_STATUS_WAITING);
if (resolver->thread.is_started()) if (resolver->thread.is_started()) {
resolver->sem.post(); resolver->sem.post();
else } else {
resolver->resolve_queues(); resolver->resolve_queues();
}
} }
resolver->mutex.unlock(); resolver->mutex.unlock();

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,31 @@ 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;
} }
@ -96,8 +97,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()) {
@ -245,8 +247,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++;
@ -298,24 +301,26 @@ 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;
} 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;
} 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;
} }
@ -337,8 +342,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;
@ -356,8 +362,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;
@ -435,8 +446,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

@ -85,10 +85,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:%i:%s() - %s\n", p_file, p_line, p_function, p_code); logf_error(" At: %s:%i:%s() - %s\n", p_file, p_line, p_function, p_code);

View file

@ -111,8 +111,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: {
@ -122,23 +123,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;
@ -147,22 +151,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;
@ -175,8 +182,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; // 5 } break; // 5
case Variant::RECT2: { case Variant::RECT2: {
@ -188,8 +196,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::VECTOR3: { case Variant::VECTOR3: {
@ -200,8 +209,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::TRANSFORM2D: { case Variant::TRANSFORM2D: {
@ -215,8 +225,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: {
@ -228,8 +239,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: {
@ -241,8 +253,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: {
@ -256,8 +269,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: {
@ -271,8 +285,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: {
@ -289,8 +304,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;
@ -304,8 +320,9 @@ 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::NODE_PATH: { case Variant::NODE_PATH: {
@ -325,24 +342,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);
@ -362,8 +383,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 = decode_uint64(buf); ObjectID val = decode_uint64(buf);
if (r_len) if (r_len) {
(*r_len) += 8; (*r_len) += 8;
}
if (val == 0) { if (val == 0) {
r_variant = (Object *)nullptr; r_variant = (Object *)nullptr;
@ -380,8 +402,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;
@ -401,14 +424,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;
@ -525,8 +550,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;
} }
@ -588,15 +614,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);
} }
@ -629,8 +657,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;
@ -663,8 +692,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;
@ -698,8 +728,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;
@ -831,8 +862,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);
@ -846,17 +878,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);
@ -1021,8 +1055,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++;
} }
@ -1034,19 +1069,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 {
@ -1095,13 +1133,15 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
encode_variant(v ? E->get() : Variant("[Deleted Object]"), buf, len, p_full_objects); encode_variant(v ? E->get() : Variant("[Deleted Object]"), 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;
}
encode_variant(v ? *v : Variant(), buf, len, p_full_objects); encode_variant(v ? *v : Variant(), 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;
@ -1120,8 +1160,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;
@ -1142,8 +1183,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;
@ -1156,8 +1198,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;
PoolVector<int>::Read r = data.read(); PoolVector<int>::Read r = data.read();
for (int i = 0; i < datalen; i++) for (int 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;
@ -1172,8 +1215,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;
PoolVector<real_t>::Read r = data.read(); PoolVector<real_t>::Read r = data.read();
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;
@ -1203,8 +1247,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

@ -46,8 +46,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:
@ -56,8 +57,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: {
@ -90,13 +92,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();
@ -136,8 +140,9 @@ Node *MultiplayerAPI::get_root_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.");
@ -408,11 +413,13 @@ bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int
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());
@ -553,11 +560,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.
@ -898,8 +907,9 @@ int MultiplayerAPI::_get_bandwidth_usage(const Vector<BandwidthFrame> &p_buffer,
} }
void MultiplayerAPI::_init_node_profile(ObjectID p_node) { void MultiplayerAPI::_init_node_profile(ObjectID p_node) {
if (profiler_frame_data.has(p_node)) if (profiler_frame_data.has(p_node)) {
return; return;
}
profiler_frame_data.insert(p_node, ProfilingInfo()); profiler_frame_data.insert(p_node, ProfilingInfo());
profiler_frame_data[p_node].node = p_node; profiler_frame_data[p_node].node = p_node;
profiler_frame_data[p_node].node_path = Object::cast_to<Node>(ObjectDB::get_instance(p_node))->get_path(); profiler_frame_data[p_node].node_path = Object::cast_to<Node>(ObjectDB::get_instance(p_node))->get_path();

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

@ -64,24 +64,28 @@ Error PacketPeer::get_packet_buffer(PoolVector<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;
}
PoolVector<uint8_t>::Write w = r_buffer.write(); PoolVector<uint8_t>::Write w = r_buffer.write();
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 PoolVector<uint8_t> &p_buffer) { Error PacketPeer::put_packet_buffer(const PoolVector<uint8_t> &p_buffer) {
int len = p_buffer.size(); int len = p_buffer.size();
if (len == 0) if (len == 0) {
return OK; return OK;
}
PoolVector<uint8_t>::Read r = p_buffer.read(); PoolVector<uint8_t>::Read r = p_buffer.read();
return put_packet(&r[0], len); return put_packet(&r[0], len);
@ -91,8 +95,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 || allow_object_decoding); return decode_variant(r_variant, buffer, buffer_size, nullptr, p_allow_objects || allow_object_decoding);
} }
@ -100,11 +105,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 || allow_object_decoding); // compute len first Error err = encode_variant(p_packet, nullptr, len, p_full_objects || allow_object_decoding); // 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'.");
@ -184,10 +191,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);
@ -209,8 +218,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++;
@ -244,19 +254,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

@ -40,8 +40,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) {
ERR_FAIL_COND(udp_server); ERR_FAIL_COND(udp_server);
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) {
@ -76,8 +77,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);
@ -87,18 +89,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];
@ -135,10 +140,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;
} }
@ -161,13 +167,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_broadcasting_enabled(broadcast); _sock->set_broadcasting_enabled(broadcast);
@ -279,8 +287,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

@ -95,8 +95,9 @@ enum {
void ResourceInteractiveLoaderBinary::_advance_padding(uint32_t p_len) { void ResourceInteractiveLoaderBinary::_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
}
} }
} }
@ -107,8 +108,9 @@ StringName ResourceInteractiveLoaderBinary::_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]);
@ -259,10 +261,12 @@ Error ResourceInteractiveLoaderBinary::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);
@ -429,8 +433,9 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
PoolVector<String> array; PoolVector<String> array;
array.resize(len); array.resize(len);
PoolVector<String>::Write w = array.write(); PoolVector<String>::Write w = array.write();
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();
}
w.release(); w.release();
r_v = array; r_v = array;
@ -585,8 +590,9 @@ Ref<Resource> ResourceInteractiveLoaderBinary::get_resource() {
return resource; return resource;
} }
Error ResourceInteractiveLoaderBinary::poll() { Error ResourceInteractiveLoaderBinary::poll() {
if (error != OK) if (error != OK) {
return error; return error;
}
int s = stage; int s = stage;
@ -641,8 +647,9 @@ Error ResourceInteractiveLoaderBinary::poll() {
return error; return error;
} }
} else { } else {
if (!ResourceCache::has(res_path)) if (!ResourceCache::has(res_path)) {
path = res_path; path = res_path;
}
} }
uint64_t offset = internal_resources[s].offset; uint64_t offset = internal_resources[s].offset;
@ -685,8 +692,9 @@ Error ResourceInteractiveLoaderBinary::poll() {
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);
} }
@ -741,8 +749,9 @@ String ResourceInteractiveLoaderBinary::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]);
@ -751,8 +760,9 @@ String ResourceInteractiveLoaderBinary::get_unicode_string() {
void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types) { void ResourceInteractiveLoaderBinary::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;
@ -820,8 +830,9 @@ void ResourceInteractiveLoaderBinary::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);
@ -912,13 +923,15 @@ ResourceInteractiveLoaderBinary::ResourceInteractiveLoaderBinary() :
} }
ResourceInteractiveLoaderBinary::~ResourceInteractiveLoaderBinary() { ResourceInteractiveLoaderBinary::~ResourceInteractiveLoaderBinary() {
if (f) if (f) {
memdelete(f); memdelete(f);
}
} }
Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) { Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) {
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);
@ -1199,8 +1212,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
}
} }
} }
@ -1359,8 +1373,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))) {
@ -1451,8 +1466,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);
PoolVector<int>::Read r = arr.read(); PoolVector<int>::Read r = arr.read();
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::POOL_REAL_ARRAY: { case Variant::POOL_REAL_ARRAY: {
@ -1527,8 +1543,9 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
case Variant::OBJECT: { case Variant::OBJECT: {
RES res = p_variant.operator RefPtr(); RES res = p_variant.operator RefPtr();
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) {
@ -1540,8 +1557,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;
@ -1594,10 +1612,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: {
@ -1617,8 +1637,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);
@ -1632,8 +1653,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);
@ -1647,8 +1669,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);
@ -1664,8 +1687,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);
@ -1680,8 +1704,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;
@ -1694,8 +1719,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);
@ -1841,8 +1867,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

@ -69,8 +69,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;
@ -94,8 +95,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) {
@ -132,8 +134,9 @@ public:
Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) { Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) {
//either this //either this
Ref<Resource> res = load(p_path, p_original_path, r_error); Ref<Resource> res = load(p_path, p_original_path, r_error);
if (res.is_null()) if (res.is_null()) {
return Ref<ResourceInteractiveLoader>(); return Ref<ResourceInteractiveLoader>();
}
Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault)); Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault));
ril->resource = res; ril->resource = res;
@ -162,33 +165,38 @@ RES ResourceFormatLoader::load(const String &p_path, const String &p_original_pa
Variant res = get_script_instance()->call("load", p_path, p_original_path); Variant res = get_script_instance()->call("load", p_path, p_original_path);
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;
} }
} }
//or this must be implemented //or this must be implemented
Ref<ResourceInteractiveLoader> ril = load_interactive(p_path, p_original_path, r_error); Ref<ResourceInteractiveLoader> ril = load_interactive(p_path, p_original_path, r_error);
if (!ril.is_valid()) if (!ril.is_valid()) {
return RES(); return RES();
}
ril->set_local_path(p_original_path); ril->set_local_path(p_original_path);
while (true) { while (true) {
Error err = ril->poll(); Error err = ril->poll();
if (err == ERR_FILE_EOF) { if (err == ERR_FILE_EOF) {
if (r_error) if (r_error) {
*r_error = OK; *r_error = OK;
}
return ril->get_resource(); return ril->get_resource();
} }
if (r_error) if (r_error) {
*r_error = err; *r_error = err;
}
ERR_FAIL_COND_V_MSG(err != OK, RES(), "Failed to load resource '" + p_path + "'."); ERR_FAIL_COND_V_MSG(err != OK, RES(), "Failed to load resource '" + p_path + "'.");
} }
@ -310,14 +318,16 @@ void ResourceLoader::_remove_from_loading_map_and_thread(const String &p_path, T
} }
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) {
{ {
@ -336,8 +346,9 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
//it is possible this resource was just freed in a thread. If so, this referencing will not work and resource is considered not cached //it is possible this resource was just freed in a thread. If so, this referencing will not work and resource is considered not cached
if (res.is_valid()) { if (res.is_valid()) {
//referencing is fine //referencing is fine
if (r_error) if (r_error) {
*r_error = OK; *r_error = OK;
}
ResourceCache::lock.read_unlock(); ResourceCache::lock.read_unlock();
_remove_from_loading_map(local_path); _remove_from_loading_map(local_path);
return res; return res;
@ -365,11 +376,13 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
} }
return RES(); return RES();
} }
if (!p_no_cache) if (!p_no_cache) {
res->set_path(local_path); res->set_path(local_path);
}
if (xl_remapped) if (xl_remapped) {
res->set_as_translation_remapped(true); res->set_as_translation_remapped(true);
}
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
@ -394,10 +407,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
@ -412,22 +426,25 @@ 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;
} }
Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) { Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(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) {
bool success = _add_to_loading_map(local_path); bool success = _add_to_loading_map(local_path);
@ -458,20 +475,23 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
bool found = false; bool found = false;
for (int i = 0; i < loader_count; i++) { for (int i = 0; i < loader_count; i++) {
if (!loader[i]->recognize_path(path, p_type_hint)) if (!loader[i]->recognize_path(path, p_type_hint)) {
continue; continue;
}
found = true; found = true;
Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, local_path, r_error); Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, local_path, r_error);
if (ril.is_null()) if (ril.is_null()) {
continue; continue;
}
if (!p_no_cache) { if (!p_no_cache) {
ril->set_local_path(local_path); ril->set_local_path(local_path);
ril->path_loading = local_path; ril->path_loading = local_path;
ril->path_loading_thread = Thread::get_caller_id(); ril->path_loading_thread = Thread::get_caller_id();
} }
if (xl_remapped) if (xl_remapped) {
ril->set_translation_remapped(true); ril->set_translation_remapped(true);
}
return ril; return ril;
} }
@ -506,8 +526,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
@ -524,14 +545,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;
@ -547,14 +570,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;
@ -570,14 +595,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;
@ -593,14 +620,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;
@ -616,14 +645,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;
@ -637,14 +668,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;
@ -658,15 +691,17 @@ 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);
if (result != "") if (result != "") {
return result; return result;
}
} }
return ""; return "";
@ -801,8 +836,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;
@ -827,8 +863,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;
}
PoolVector<String> remaps = ProjectSettings::get_singleton()->get("path_remap/remapped_paths"); PoolVector<String> remaps = ProjectSettings::get_singleton()->get("path_remap/remapped_paths");
int rc = remaps.size(); int rc = remaps.size();
@ -860,8 +897,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);
@ -885,8 +923,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

@ -157,8 +157,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;
@ -166,8 +167,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 PoolVector<uint8_t> &p_data) { Error StreamPeer::_put_data(const PoolVector<uint8_t> &p_data) {
int len = p_data.size(); int len = p_data.size();
if (len == 0) if (len == 0) {
return OK; return OK;
}
PoolVector<uint8_t>::Read r = p_data.read(); PoolVector<uint8_t>::Read r = p_data.read();
return put_data(&r[0], len); return put_data(&r[0], len);
} }
@ -299,8 +300,9 @@ double StreamPeer::get_double() {
return decode_double(buf); return decode_double(buf);
} }
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;
@ -312,8 +314,9 @@ String StreamPeer::get_string(int p_bytes) {
return buf.ptr(); return buf.ptr();
} }
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;
@ -399,8 +402,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);
@ -421,8 +425,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;
@ -303,8 +305,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

@ -46,8 +46,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;
@ -131,10 +134,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++;
} }
@ -143,10 +147,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: " + path + "."); ERR_FAIL_COND_V_MSG(config == "", RES(), "No config found in file: " + path + ".");
@ -155,8 +161,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();
@ -165,15 +172,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) { RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error) {
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 + "'.");
@ -189,8 +198,9 @@ 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

@ -94,13 +94,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);
@ -124,8 +126,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;
}
return pending.size() > 0; return pending.size() > 0;
} }

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();
@ -412,8 +435,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;
@ -441,8 +465,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;
} }
bool XMLParser::is_empty() const { bool XMLParser::is_empty() const {
@ -489,8 +514,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;
@ -499,14 +525,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;
@ -529,6 +557,7 @@ XMLParser::XMLParser() {
special_characters.push_back("'apos;"); special_characters.push_back("'apos;");
} }
XMLParser::~XMLParser() { XMLParser::~XMLParser() {
if (data) if (data) {
memdelete_arr(data); memdelete_arr(data);
}
} }

View file

@ -42,8 +42,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

@ -153,14 +153,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--;
@ -224,8 +227,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++;
@ -233,8 +237,9 @@ public:
}; };
void pop_back() { void pop_back() {
if (_data && _data->last) if (_data && _data->last) {
erase(_data->last); erase(_data->last);
}
} }
/** /**
@ -260,8 +265,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++;
@ -269,8 +275,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) {
@ -332,8 +339,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();
}; };
@ -470,18 +478,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;
@ -504,20 +515,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;
@ -565,8 +579,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;
@ -587,15 +602,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 = NULL; current->prev_ptr = NULL;
current->next_ptr = NULL; current->next_ptr = NULL;
@ -621,8 +638,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

@ -147,13 +147,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;
@ -162,13 +164,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;
@ -188,8 +192,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;
} }
} }
@ -208,8 +213,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;
} }
} }
@ -219,12 +225,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;
@ -238,19 +245,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;
} }
@ -311,11 +321,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
} }
@ -337,10 +347,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);
@ -435,10 +447,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;
@ -447,10 +461,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--;
@ -458,19 +474,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);
@ -487,32 +506,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 NULL; return NULL;
}
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;
@ -523,31 +546,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;
} }
@ -559,40 +588,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;
} }
@ -602,8 +639,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);
@ -611,8 +649,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.
}
// Keep the closest point's ID, and in case of multiple closest IDs, // Keep the closest point's ID, and in case of multiple closest IDs,
// the smallest one (makes it deterministic). // the smallest one (makes it deterministic).
@ -324,8 +328,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;
@ -383,8 +388,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);
@ -398,8 +404,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);
@ -431,8 +438,9 @@ PoolVector<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 PoolVector<Vector3>(); return PoolVector<Vector3>();
}
Point *p = end_point; Point *p = end_point;
int pc = 1; // Begin point int pc = 1; // Begin point
@ -479,8 +487,9 @@ PoolVector<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 PoolVector<int>(); return PoolVector<int>();
}
Point *p = end_point; Point *p = end_point;
int pc = 1; // Begin point int pc = 1; // Begin point
@ -656,8 +665,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);
@ -671,8 +681,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);
@ -704,8 +715,9 @@ PoolVector<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 PoolVector<Vector2>(); return PoolVector<Vector2>();
}
AStar::Point *p = end_point; AStar::Point *p = end_point;
int pc = 1; // Begin point int pc = 1; // Begin point
@ -752,8 +764,9 @@ PoolVector<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 PoolVector<int>(); return PoolVector<int>();
}
AStar::Point *p = end_point; AStar::Point *p = end_point;
int pc = 1; // Begin point int pc = 1; // Begin point
@ -784,8 +797,9 @@ PoolVector<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

@ -77,23 +77,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;
} }
@ -133,8 +133,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;
@ -157,16 +158,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;
@ -178,10 +181,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;
@ -192,8 +197,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;
} }
@ -214,10 +220,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

@ -113,35 +113,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;
} }
@ -206,8 +218,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
@ -247,26 +260,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;
} }
@ -275,19 +295,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;
@ -352,12 +378,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;
@ -365,12 +394,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

@ -113,12 +113,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;
} }
@ -723,8 +726,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;
}
} }
} }
@ -734,8 +738,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;
}
} }
} }
@ -750,8 +755,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]);
} }
@ -829,20 +835,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;
@ -922,8 +930,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

@ -95,8 +95,9 @@ int BSP_Tree::_get_points_inside(int p_node, const Vector3 *p_points, int *p_ind
// kind of slow (but cache friendly), should try something else, // kind of slow (but cache friendly), should try something else,
// but this is a corner case most of the time // but this is a corner case most of the time
for (int j = index; j < p_indices_count - 1; j++) for (int j = index; j < p_indices_count - 1; j++) {
p_indices[j] = p_indices[j + 1]; p_indices[j] = p_indices[j + 1];
}
p_indices[p_indices_count - 1] = index; p_indices[p_indices_count - 1] = index;
@ -142,8 +143,9 @@ int BSP_Tree::_get_points_inside(int p_node, const Vector3 *p_points, int *p_ind
} }
int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) const { int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) const {
if (nodes.size() == 0) if (nodes.size() == 0) {
return 0; return 0;
}
#if 1 #if 1
//this version is easier to debug, and and MUCH faster in real world cases //this version is easier to debug, and and MUCH faster in real world cases
@ -153,8 +155,9 @@ int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) cons
const Plane *planesptr = &planes[0]; const Plane *planesptr = &planes[0];
int node_count = nodes.size(); int node_count = nodes.size();
if (node_count == 0) // no nodes! if (node_count == 0) { // no nodes!
return 0; return 0;
}
for (int i = 0; i < p_point_count; i++) { for (int i = 0; i < p_point_count; i++) {
const Vector3 &point = p_points[i]; const Vector3 &point = p_points[i];
@ -189,8 +192,9 @@ int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) cons
#endif #endif
} }
if (pass) if (pass) {
pass_count++; pass_count++;
}
} }
return pass_count; return pass_count;
@ -221,8 +225,9 @@ bool BSP_Tree::point_is_inside(const Vector3 &p_point) const {
int node_count = nodes.size(); int node_count = nodes.size();
if (node_count == 0) // no nodes! if (node_count == 0) { // no nodes!
return false; return false;
}
const Node *nodesptr = &nodes[0]; const Node *nodesptr = &nodes[0];
const Plane *planesptr = &planes[0]; const Plane *planesptr = &planes[0];
@ -269,8 +274,9 @@ static int _bsp_find_best_half_plane(const Face3 *p_faces, const Vector<int> &p_
int num_over = 0, num_under = 0, num_spanning = 0; int num_over = 0, num_under = 0, num_spanning = 0;
for (int j = 0; j < ic; j++) { for (int j = 0; j < ic; j++) {
if (i == j) if (i == j) {
continue; continue;
}
const Face3 &g = p_faces[indices[j]]; const Face3 &g = p_faces[indices[j]];
int over = 0, under = 0; int over = 0, under = 0;
@ -279,19 +285,21 @@ static int _bsp_find_best_half_plane(const Face3 *p_faces, const Vector<int> &p_
real_t d = p.distance_to(g.vertex[j]); real_t d = p.distance_to(g.vertex[j]);
if (Math::abs(d) > p_tolerance) { if (Math::abs(d) > p_tolerance) {
if (d > 0) if (d > 0) {
over++; over++;
else } else {
under++; under++;
}
} }
} }
if (over && under) if (over && under) {
num_spanning++; num_spanning++;
else if (over) } else if (over) {
num_over++; num_over++;
else } else {
num_under++; num_under++;
}
} }
//real_t split_cost = num_spanning / (real_t) face_count; //real_t split_cost = num_spanning / (real_t) face_count;
@ -332,8 +340,9 @@ static int _bsp_create_node(const Face3 *p_faces, const Vector<int> &p_indices,
Plane divisor_plane = p_faces[indices[divisor_idx]].get_plane(); Plane divisor_plane = p_faces[indices[divisor_idx]].get_plane();
for (int i = 0; i < ic; i++) { for (int i = 0; i < ic; i++) {
if (i == divisor_idx) if (i == divisor_idx) {
continue; continue;
}
const Face3 &f = p_faces[indices[i]]; const Face3 &f = p_faces[indices[i]];
@ -348,17 +357,20 @@ static int _bsp_create_node(const Face3 *p_faces, const Vector<int> &p_indices,
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
real_t d = divisor_plane.distance_to(f.vertex[j]); real_t d = divisor_plane.distance_to(f.vertex[j]);
if (Math::abs(d) > p_tolerance) { if (Math::abs(d) > p_tolerance) {
if (d > 0) if (d > 0) {
over_count++; over_count++;
else } else {
under_count++; under_count++;
}
} }
} }
if (over_count) if (over_count) {
faces_over.push_back(indices[i]); faces_over.push_back(indices[i]);
if (under_count) }
if (under_count) {
faces_under.push_back(indices[i]); faces_under.push_back(indices[i]);
}
} }
uint16_t over_idx = BSP_Tree::OVER_LEAF, under_idx = BSP_Tree::UNDER_LEAF; uint16_t over_idx = BSP_Tree::OVER_LEAF, under_idx = BSP_Tree::UNDER_LEAF;
@ -366,15 +378,17 @@ static int _bsp_create_node(const Face3 *p_faces, const Vector<int> &p_indices,
if (faces_over.size() > 0) { //have facess above? if (faces_over.size() > 0) { //have facess above?
int idx = _bsp_create_node(p_faces, faces_over, p_planes, p_nodes, p_tolerance); int idx = _bsp_create_node(p_faces, faces_over, p_planes, p_nodes, p_tolerance);
if (idx >= 0) if (idx >= 0) {
over_idx = idx; over_idx = idx;
}
} }
if (faces_under.size() > 0) { //have facess above? if (faces_under.size() > 0) { //have facess above?
int idx = _bsp_create_node(p_faces, faces_under, p_planes, p_nodes, p_tolerance); int idx = _bsp_create_node(p_faces, faces_under, p_planes, p_nodes, p_tolerance);
if (idx >= 0) if (idx >= 0) {
under_idx = idx; under_idx = idx;
}
} }
/* Create the node */ /* Create the node */
@ -498,8 +512,9 @@ BSP_Tree::BSP_Tree(const PoolVector<Face3> &p_faces, real_t p_error_radius) {
for (int i = 0; i < face_count; i++) { for (int i = 0; i < face_count; i++) {
const Face3 &f = facesptr[i]; const Face3 &f = facesptr[i];
if (f.is_degenerate()) if (f.is_degenerate()) {
continue; continue;
}
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
if (first) { if (first) {

View file

@ -94,10 +94,11 @@ public:
template <class T> template <class T>
bool BSP_Tree::_test_convex(const Node *p_nodes, const Plane *p_planes, int p_current, const T &p_convex) const { bool BSP_Tree::_test_convex(const Node *p_nodes, const Plane *p_planes, int p_current, const T &p_convex) const {
if (p_current == UNDER_LEAF) if (p_current == UNDER_LEAF) {
return true; return true;
else if (p_current == OVER_LEAF) } else if (p_current == OVER_LEAF) {
return false; return false;
}
bool collided = false; bool collided = false;
const Node &n = p_nodes[p_current]; const Node &n = p_nodes[p_current];
@ -110,10 +111,12 @@ bool BSP_Tree::_test_convex(const Node *p_nodes, const Plane *p_planes, int p_cu
bool go_under = min < p.d; bool go_under = min < p.d;
bool go_over = max >= p.d; bool go_over = max >= p.d;
if (go_under && _test_convex(p_nodes, p_planes, n.under, p_convex)) if (go_under && _test_convex(p_nodes, p_planes, n.under, p_convex)) {
collided = true; collided = true;
if (go_over && _test_convex(p_nodes, p_planes, n.over, p_convex)) }
if (go_over && _test_convex(p_nodes, p_planes, n.over, p_convex)) {
collided = true; collided = true;
}
return collided; return collided;
} }
@ -121,8 +124,9 @@ bool BSP_Tree::_test_convex(const Node *p_nodes, const Plane *p_planes, int p_cu
template <class T> template <class T>
bool BSP_Tree::convex_is_inside(const T &p_convex) const { bool BSP_Tree::convex_is_inside(const T &p_convex) const {
int node_count = nodes.size(); int node_count = nodes.size();
if (node_count == 0) if (node_count == 0) {
return false; return false;
}
const Node *nodes = &this->nodes[0]; const Node *nodes = &this->nodes[0];
const Plane *planes = &this->planes[0]; const Plane *planes = &this->planes[0];

View file

@ -359,12 +359,14 @@ public:
} }
int cull_convex(const Vector<Plane> &p_convex, T **p_result_array, int p_result_max, uint32_t p_mask = 0xFFFFFFFF) { int cull_convex(const Vector<Plane> &p_convex, T **p_result_array, int p_result_max, uint32_t p_mask = 0xFFFFFFFF) {
if (!p_convex.size()) if (!p_convex.size()) {
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;
}
typename BVHTREE_CLASS::CullParams params; typename BVHTREE_CLASS::CullParams params;
params.result_count_overall = 0; params.result_count_overall = 0;
@ -431,8 +433,9 @@ private:
uint32_t ref_id = tree._cull_hits[i]; uint32_t ref_id = tree._cull_hits[i];
// don't collide against ourself // don't collide against ourself
if (ref_id == changed_item_ref_id) if (ref_id == changed_item_ref_id) {
continue; continue;
}
#ifdef BVH_CHECKS #ifdef BVH_CHECKS
// if neither are pairable, they should ignore each other // if neither are pairable, they should ignore each other
@ -558,11 +561,13 @@ private:
// does this pair exist already? // does this pair exist already?
// or only check the one with lower number of pairs for greater speed // or only check the one with lower number of pairs for greater speed
if (p_from.num_pairs <= p_to.num_pairs) { if (p_from.num_pairs <= p_to.num_pairs) {
if (p_from.contains_pair_to(p_hb)) if (p_from.contains_pair_to(p_hb)) {
return; return;
}
} else { } else {
if (p_to.contains_pair_to(p_ha)) if (p_to.contains_pair_to(p_ha)) {
return; return;
}
} }
// callback // callback
@ -614,8 +619,9 @@ private:
// passing p_check_aabb false disables the optimization which prevents collision checks if // passing p_check_aabb false disables the optimization which prevents collision checks if
// the aabb hasn't changed. This is needed where set_pairable has been called, but the position // the aabb hasn't changed. This is needed where set_pairable has been called, but the position
// has not changed. // has not changed.
if (p_check_aabb && expanded_aabb.encloses(aabb)) if (p_check_aabb && expanded_aabb.encloses(aabb)) {
return; return;
}
// ALWAYS update the new expanded aabb, even if already changed once // ALWAYS update the new expanded aabb, even if already changed once
// this tick, because it is vital that the AABB is kept up to date // this tick, because it is vital that the AABB is kept up to date
@ -626,8 +632,9 @@ private:
// collision checking them multiple times is not needed, and repeats the same thing // collision checking them multiple times is not needed, and repeats the same thing
uint32_t &last_updated_tick = tree._extra[p_handle.id()].last_updated_tick; uint32_t &last_updated_tick = tree._extra[p_handle.id()].last_updated_tick;
if (last_updated_tick == _tick) if (last_updated_tick == _tick) {
return; // already on changed list return; // already on changed list
}
// mark as on list // mark as on list
last_updated_tick = _tick; last_updated_tick = _tick;

View file

@ -129,12 +129,14 @@ struct BVH_ABB {
(p_p.normal.z < 0) ? -half_extents.z : half_extents.z); (p_p.normal.z < 0) ? -half_extents.z : half_extents.z);
Vector3 point = point_offset + ofs; Vector3 point = point_offset + ofs;
if (!p_p.is_point_over(point)) if (!p_p.is_point_over(point)) {
return false; return false;
}
point = -point_offset + ofs; point = -point_offset + ofs;
if (p_p.is_point_over(point)) if (p_p.is_point_over(point)) {
return false; return false;
}
return true; return true;
} }
@ -151,8 +153,9 @@ struct BVH_ABB {
(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;
@ -186,8 +189,9 @@ struct BVH_ABB {
bool is_point_within_hull(const ConvexHull &p_hull, const Vector3 &p_pt) const { bool is_point_within_hull(const ConvexHull &p_hull, const Vector3 &p_pt) const {
for (int n = 0; n < p_hull.num_planes; n++) { for (int n = 0; n < p_hull.num_planes; n++) {
if (p_hull.planes[n].distance_to(p_pt) > 0.0f) if (p_hull.planes[n].distance_to(p_pt) > 0.0f) {
return false; return false;
}
} }
return true; return true;
} }
@ -199,26 +203,32 @@ struct BVH_ABB {
} }
bool intersects_point(const Point &p_pt) const { bool intersects_point(const Point &p_pt) const {
if (_any_lessthan(-p_pt, neg_max)) if (_any_lessthan(-p_pt, neg_max)) {
return false; return false;
if (_any_lessthan(p_pt, min)) }
if (_any_lessthan(p_pt, min)) {
return false; return false;
}
return true; return true;
} }
bool intersects(const BVH_ABB &p_o) const { bool intersects(const BVH_ABB &p_o) const {
if (_any_morethan(p_o.min, -neg_max)) if (_any_morethan(p_o.min, -neg_max)) {
return false; return false;
if (_any_morethan(min, -p_o.neg_max)) }
if (_any_morethan(min, -p_o.neg_max)) {
return false; return false;
}
return true; return true;
} }
bool is_other_within(const BVH_ABB &p_o) const { bool is_other_within(const BVH_ABB &p_o) const {
if (_any_lessthan(p_o.neg_max, neg_max)) if (_any_lessthan(p_o.neg_max, neg_max)) {
return false; return false;
if (_any_lessthan(p_o.min, min)) }
if (_any_lessthan(p_o.min, min)) {
return false; return false;
}
return true; return true;
} }

View file

@ -30,8 +30,9 @@ void _cull_translate_hits(CullParams &p) {
int num_hits = _cull_hits.size(); int num_hits = _cull_hits.size();
int left = p.result_max - p.result_count_overall; int left = p.result_max - p.result_count_overall;
if (num_hits > left) if (num_hits > left) {
num_hits = left; num_hits = left;
}
int out_n = p.result_count_overall; int out_n = p.result_count_overall;
@ -41,8 +42,9 @@ void _cull_translate_hits(CullParams &p) {
const ItemExtra &ex = _extra[ref_id]; const ItemExtra &ex = _extra[ref_id];
p.result_array[out_n] = ex.userdata; p.result_array[out_n] = ex.userdata;
if (p.subindex_array) if (p.subindex_array) {
p.subindex_array[out_n] = ex.subindex; p.subindex_array[out_n] = ex.subindex;
}
out_n++; out_n++;
} }
@ -57,14 +59,16 @@ int cull_convex(CullParams &r_params, bool p_translate_hits = true) {
r_params.result_count = 0; r_params.result_count = 0;
for (int n = 0; n < NUM_TREES; n++) { for (int n = 0; n < NUM_TREES; n++) {
if (_root_node_id[n] == BVHCommon::INVALID) if (_root_node_id[n] == BVHCommon::INVALID) {
continue; continue;
}
_cull_convex_iterative(_root_node_id[n], r_params); _cull_convex_iterative(_root_node_id[n], r_params);
} }
if (p_translate_hits) if (p_translate_hits) {
_cull_translate_hits(r_params); _cull_translate_hits(r_params);
}
return r_params.result_count; return r_params.result_count;
} }
@ -74,14 +78,16 @@ int cull_segment(CullParams &r_params, bool p_translate_hits = true) {
r_params.result_count = 0; r_params.result_count = 0;
for (int n = 0; n < NUM_TREES; n++) { for (int n = 0; n < NUM_TREES; n++) {
if (_root_node_id[n] == BVHCommon::INVALID) if (_root_node_id[n] == BVHCommon::INVALID) {
continue; continue;
}
_cull_segment_iterative(_root_node_id[n], r_params); _cull_segment_iterative(_root_node_id[n], r_params);
} }
if (p_translate_hits) if (p_translate_hits) {
_cull_translate_hits(r_params); _cull_translate_hits(r_params);
}
return r_params.result_count; return r_params.result_count;
} }
@ -91,14 +97,16 @@ int cull_point(CullParams &r_params, bool p_translate_hits = true) {
r_params.result_count = 0; r_params.result_count = 0;
for (int n = 0; n < NUM_TREES; n++) { for (int n = 0; n < NUM_TREES; n++) {
if (_root_node_id[n] == BVHCommon::INVALID) if (_root_node_id[n] == BVHCommon::INVALID) {
continue; continue;
}
_cull_point_iterative(_root_node_id[n], r_params); _cull_point_iterative(_root_node_id[n], r_params);
} }
if (p_translate_hits) if (p_translate_hits) {
_cull_translate_hits(r_params); _cull_translate_hits(r_params);
}
return r_params.result_count; return r_params.result_count;
} }
@ -108,17 +116,20 @@ int cull_aabb(CullParams &r_params, bool p_translate_hits = true) {
r_params.result_count = 0; r_params.result_count = 0;
for (int n = 0; n < NUM_TREES; n++) { for (int n = 0; n < NUM_TREES; n++) {
if (_root_node_id[n] == BVHCommon::INVALID) if (_root_node_id[n] == BVHCommon::INVALID) {
continue; continue;
}
if ((n == 0) && r_params.test_pairable_only) if ((n == 0) && r_params.test_pairable_only) {
continue; continue;
}
_cull_aabb_iterative(_root_node_id[n], r_params); _cull_aabb_iterative(_root_node_id[n], r_params);
} }
if (p_translate_hits) if (p_translate_hits) {
_cull_translate_hits(r_params); _cull_translate_hits(r_params);
}
return r_params.result_count; return r_params.result_count;
} }
@ -245,8 +256,9 @@ bool _cull_point_iterative(uint32_t p_node_id, CullParams &r_params) {
while (ii.pop(cpp)) { while (ii.pop(cpp)) {
TNode &tnode = _nodes[cpp.node_id]; TNode &tnode = _nodes[cpp.node_id];
// no hit with this node? // no hit with this node?
if (!tnode.aabb.intersects_point(r_params.point)) if (!tnode.aabb.intersects_point(r_params.point)) {
continue; continue;
}
if (tnode.is_leaf()) { if (tnode.is_leaf()) {
// lazy check for hits full up condition // lazy check for hits full up condition

View file

@ -6,12 +6,14 @@ void _logic_item_remove_and_reinsert(uint32_t p_ref_id) {
ItemRef &ref = _refs[p_ref_id]; ItemRef &ref = _refs[p_ref_id];
// no need to optimize inactive items // no need to optimize inactive items
if (!ref.is_active()) if (!ref.is_active()) {
return; return;
}
// special case of debug draw // special case of debug draw
if (ref.item_id == BVHCommon::INVALID) if (ref.item_id == BVHCommon::INVALID) {
return; return;
}
BVH_ASSERT(ref.tnode_id != BVHCommon::INVALID); BVH_ASSERT(ref.tnode_id != BVHCommon::INVALID);
@ -69,8 +71,9 @@ int32_t _logic_balance(int32_t iA) {
TNode *A = &_nodes[iA]; TNode *A = &_nodes[iA];
if (A->is_leaf() || A->height == 1) if (A->is_leaf() || A->height == 1) {
return iA; return iA;
}
/* A /* A
/ \ / \
@ -96,11 +99,12 @@ int32_t _logic_balance(int32_t iA) {
// grandParent point to C // grandParent point to C
if (A->parent_id != BVHCommon::INVALID) { if (A->parent_id != BVHCommon::INVALID) {
if (_nodes[A->parent_id].children[0] == iA) if (_nodes[A->parent_id].children[0] == iA) {
_nodes[A->parent_id].children[0] = iC; _nodes[A->parent_id].children[0] = iC;
else } else {
_nodes[A->parent_id].children[1] = iC; _nodes[A->parent_id].children[1] = iC;
}
} else { } else {
// check this .. seems dodgy // check this .. seems dodgy
change_root_node(iC); change_root_node(iC);
@ -146,10 +150,11 @@ int32_t _logic_balance(int32_t iA) {
// grandParent point to B // grandParent point to B
if (A->parent_id != BVHCommon::INVALID) { if (A->parent_id != BVHCommon::INVALID) {
if (_nodes[A->parent_id].children[0] == iA) if (_nodes[A->parent_id].children[0] == iA) {
_nodes[A->parent_id].children[0] = iB; _nodes[A->parent_id].children[0] = iB;
else } else {
_nodes[A->parent_id].children[1] = iB; _nodes[A->parent_id].children[1] = iB;
}
} }
else { else {
@ -199,8 +204,9 @@ uint32_t _logic_choose_item_add_node(uint32_t p_node_id, const BVHABB_CLASS &p_a
if (tnode.is_leaf()) { if (tnode.is_leaf()) {
// if a leaf, and non full, use this to add to // if a leaf, and non full, use this to add to
if (!node_is_leaf_full(tnode)) if (!node_is_leaf_full(tnode)) {
return p_node_id; return p_node_id;
}
// else split the leaf, and use one of the children to add to // else split the leaf, and use one of the children to add to
return split_leaf(p_node_id, p_aabb); return split_leaf(p_node_id, p_aabb);

View file

@ -2,8 +2,9 @@
int _handle_get_tree_id(BVHHandle p_handle) const { int _handle_get_tree_id(BVHHandle p_handle) const {
if (USE_PAIRS) { if (USE_PAIRS) {
int tree = 0; int tree = 0;
if (_extra[p_handle.id()].pairable) if (_extra[p_handle.id()].pairable) {
tree = 1; tree = 1;
}
return tree; return tree;
} }
return 0; return 0;

View file

@ -54,8 +54,9 @@ BVHHandle item_add(T *p_userdata, bool p_active, const Bounds &p_aabb, int32_t p
handle.set_id(ref_id); handle.set_id(ref_id);
_current_tree = 0; _current_tree = 0;
if (p_pairable) if (p_pairable) {
_current_tree = 1; _current_tree = 1;
}
create_root_node(_current_tree); create_root_node(_current_tree);
@ -68,8 +69,9 @@ BVHHandle item_add(T *p_userdata, bool p_active, const Bounds &p_aabb, int32_t p
if (refit) { if (refit) {
// only need to refit from the parent // only need to refit from the parent
const TNode &add_node = _nodes[ref->tnode_id]; const TNode &add_node = _nodes[ref->tnode_id];
if (add_node.parent_id != BVHCommon::INVALID) if (add_node.parent_id != BVHCommon::INVALID) {
refit_upward_and_balance(add_node.parent_id); refit_upward_and_balance(add_node.parent_id);
}
} }
} else { } else {
ref->set_inactive(); ref->set_inactive();
@ -152,9 +154,10 @@ bool item_move(BVHHandle p_handle, const Bounds &p_aabb) {
if (needs_refit) { if (needs_refit) {
// only need to refit from the parent // only need to refit from the parent
const TNode &add_node = _nodes[ref.tnode_id]; const TNode &add_node = _nodes[ref.tnode_id];
if (add_node.parent_id != BVHCommon::INVALID) if (add_node.parent_id != BVHCommon::INVALID) {
// not sure we need to rebalance all the time, this can be done less often // not sure we need to rebalance all the time, this can be done less often
refit_upward(add_node.parent_id); refit_upward(add_node.parent_id);
}
//refit_upward_and_balance(add_node.parent_id); //refit_upward_and_balance(add_node.parent_id);
} }
@ -322,8 +325,9 @@ bool item_set_pairable(const BVHHandle &p_handle, bool p_pairable, uint32_t p_pa
if (needs_refit) { if (needs_refit) {
// only need to refit from the parent // only need to refit from the parent
const TNode &add_node = _nodes[ref.tnode_id]; const TNode &add_node = _nodes[ref.tnode_id];
if (add_node.parent_id != BVHCommon::INVALID) if (add_node.parent_id != BVHCommon::INVALID) {
refit_upward_and_balance(add_node.parent_id); refit_upward_and_balance(add_node.parent_id);
}
} }
} else { } else {
// always keep this up to date // always keep this up to date
@ -338,8 +342,9 @@ void incremental_optimize() {
// this is cheaper than doing it on each move as each leaf may get touched multiple times // this is cheaper than doing it on each move as each leaf may get touched multiple times
// in a frame. // in a frame.
for (int n = 0; n < NUM_TREES; n++) { for (int n = 0; n < NUM_TREES; n++) {
if (_root_node_id[n] != BVHCommon::INVALID) if (_root_node_id[n] != BVHCommon::INVALID) {
refit_branch(_root_node_id[n]); refit_branch(_root_node_id[n]);
}
} }
// now do small section reinserting to get things moving // now do small section reinserting to get things moving
@ -349,8 +354,9 @@ void incremental_optimize() {
} }
// special case // special case
if (!_active_refs.size()) if (!_active_refs.size()) {
return; return;
}
uint32_t ref_id = _active_refs[_current_active_ref++]; uint32_t ref_id = _active_refs[_current_active_ref++];

View file

@ -21,8 +21,9 @@ void node_update_aabb(TNode &tnode) {
tnode.aabb.merge(tchild.aabb); tnode.aabb.merge(tchild.aabb);
// do heights at the same time // do heights at the same time
if (tchild.height > tnode.height) if (tchild.height > tnode.height) {
tnode.height = tchild.height; tnode.height = tchild.height;
}
} }
// the height of a non leaf is always 1 bigger than the biggest child // the height of a non leaf is always 1 bigger than the biggest child

View file

@ -156,8 +156,9 @@ void _split_leaf_sort_groups(int &num_a, int &num_b, uint16_t *group_a, uint16_t
// find aabb of all the rest // find aabb of all the rest
for (int rest = 0; rest < num_a; rest++) { for (int rest = 0; rest < num_a; rest++) {
if (rest == check) if (rest == check) {
continue; continue;
}
int which = group_a[rest]; int which = group_a[rest];
rest_aabb.merge(temp_bounds[which]); rest_aabb.merge(temp_bounds[which]);

View file

@ -121,8 +121,9 @@ struct TNode {
BVH_ASSERT(!is_leaf()); BVH_ASSERT(!is_leaf());
for (int n = 0; n < num_children; n++) { for (int n = 0; n < num_children; n++) {
if (children[n] == p_child_node_id) if (children[n] == p_child_node_id) {
return n; return n;
}
} }
// not found // not found

View file

@ -170,8 +170,9 @@ public:
private: private:
bool node_add_child(uint32_t p_node_id, uint32_t p_child_node_id) { bool node_add_child(uint32_t p_node_id, uint32_t p_child_node_id) {
TNode &tnode = _nodes[p_node_id]; TNode &tnode = _nodes[p_node_id];
if (tnode.is_full_of_children()) if (tnode.is_full_of_children()) {
return false; return false;
}
tnode.children[tnode.num_children] = p_child_node_id; tnode.children[tnode.num_children] = p_child_node_id;
tnode.num_children += 1; tnode.num_children += 1;
@ -278,8 +279,9 @@ private:
// debug draw special // debug draw special
// This may not be needed // This may not be needed
if (owner_node_id == BVHCommon::INVALID) if (owner_node_id == BVHCommon::INVALID) {
return; return;
}
TNode &tnode = _nodes[owner_node_id]; TNode &tnode = _nodes[owner_node_id];
CRASH_COND(!tnode.is_leaf()); CRASH_COND(!tnode.is_leaf());

View file

@ -424,23 +424,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). **/
@ -460,12 +463,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;
} }
}
} }
} }
@ -479,8 +483,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;
} }
} }
@ -532,9 +537,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

@ -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

@ -112,8 +112,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;
@ -1050,8 +1051,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 {
@ -1060,8 +1062,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();
} }
@ -1070,10 +1073,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 == '_') {
@ -1210,8 +1214,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: {
@ -1227,8 +1232,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);
@ -1238,8 +1244,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);
@ -1270,8 +1277,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;
@ -1290,8 +1298,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 ')'");
@ -1322,8 +1331,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);
@ -1400,8 +1410,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);
@ -1440,8 +1451,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);
@ -1490,8 +1502,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;
@ -1503,8 +1516,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;
@ -1543,8 +1557,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);
@ -1577,8 +1592,9 @@ Expression::ENode *Expression::_parse_expression() {
} break; } break;
} }
if (done) if (done) {
break; break;
}
} }
//push expression //push expression
@ -1593,8 +1609,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;
@ -1857,8 +1874,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);
@ -1912,15 +1930,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;
@ -1936,14 +1956,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);
@ -1958,8 +1980,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);
@ -1978,8 +2001,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;
} }
@ -1994,13 +2018,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;
} }
@ -2019,8 +2045,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];
} }
@ -2045,8 +2072,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];
} }
@ -2066,8 +2094,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;
@ -2078,8 +2107,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

@ -187,8 +187,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

@ -89,8 +89,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;
} }
@ -131,11 +132,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];
@ -164,29 +167,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;
@ -227,8 +235,9 @@ PoolVector<PoolVector<Face3>> Geometry::separate_objects(PoolVector<Face3> p_arr
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++;
} }
@ -246,8 +255,9 @@ PoolVector<PoolVector<Face3>> Geometry::separate_objects(PoolVector<Face3> p_arr
PoolVector<Face3> *group_faces = obw.ptr(); PoolVector<Face3> *group_faces = obw.ptr();
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);
} }
@ -289,8 +299,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;
@ -336,8 +347,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;
@ -423,15 +435,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;
@ -445,8 +461,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)
@ -468,21 +485,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(
@ -521,20 +544,23 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
// 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;
@ -626,8 +652,9 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
} }
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;
} }
@ -677,8 +704,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<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();
@ -693,17 +721,20 @@ Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<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();
@ -725,8 +756,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<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;
@ -737,8 +769,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<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.
@ -782,8 +815,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<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;
@ -935,13 +969,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;
@ -953,29 +989,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;

View file

@ -79,8 +79,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;
@ -111,14 +112,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.linear_interpolate(p2, mua); c1 = p1.linear_interpolate(p2, mua);
c2 = q1.linear_interpolate(q2, mub); c2 = q1.linear_interpolate(q2, mub);
} }
@ -159,22 +164,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;
} }
@ -194,34 +199,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) {
@ -230,67 +240,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;
} }
@ -298,8 +319,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, int p_cylinder_axis = 2) { 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, int p_cylinder_axis = 2) {
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.
}
ERR_FAIL_COND_V(p_cylinder_axis < 0, false); ERR_FAIL_COND_V(p_cylinder_axis < 0, false);
ERR_FAIL_COND_V(p_cylinder_axis > 2, false); ERR_FAIL_COND_V(p_cylinder_axis > 2, false);
@ -323,13 +345,15 @@ public:
real_t dist = axis_dir.dot(p_from); real_t dist = axis_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 side_dir = axis_dir.cross(cylinder_axis).normalized(); Vector3 side_dir = axis_dir.cross(cylinder_axis).normalized();
@ -349,15 +373,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;
@ -367,10 +393,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.
@ -388,10 +416,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;
} }
@ -402,8 +432,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;
@ -414,15 +445,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) {
@ -432,13 +465,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;
} }
@ -447,25 +483,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;
@ -476,17 +515,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) {
@ -496,8 +537,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;
} }
@ -527,8 +569,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;
@ -555,24 +598,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;
} }
@ -582,18 +629,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;
} }
@ -601,8 +651,9 @@ 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);
@ -694,8 +745,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.
@ -703,10 +755,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;
} }
@ -717,8 +771,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;
@ -849,15 +904,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++) {
@ -872,8 +929,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);
@ -945,25 +1003,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;
} }
@ -985,15 +1047,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];
} }

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

@ -474,10 +474,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

@ -186,8 +186,9 @@ private:
#ifdef OCTREE_USE_CACHED_LISTS #ifdef OCTREE_USE_CACHED_LISTS
dirty = true; dirty = true;
#endif #endif
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++) {
children[i] = nullptr; children[i] = nullptr;
}
} }
~Octant() { ~Octant() {
@ -297,12 +298,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);
@ -327,8 +330,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);
@ -414,12 +418,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);
@ -503,11 +509,13 @@ OCTREE_FUNC(void)::_insert_element(Element *p_element, Octant *p_octant) {
bool can_split = true; bool can_split = true;
if (p_element->pairable) { if (p_element->pairable) {
if (p_octant->pairable_elements.size() < octant_elements_limit) if (p_octant->pairable_elements.size() < octant_elements_limit) {
can_split = false; can_split = false;
}
} else { } else {
if (p_octant->elements.size() < octant_elements_limit) if (p_octant->elements.size() < octant_elements_limit) {
can_split = false; can_split = false;
}
} }
if (!can_split || (element_size > (p_octant->aabb.size.x / OCTREE_DIVISOR))) { if (!can_split || (element_size > (p_octant->aabb.size.x / OCTREE_DIVISOR))) {
@ -561,12 +569,15 @@ OCTREE_FUNC(void)::_insert_element(Element *p_element, Octant *p_octant) {
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 */
@ -671,8 +682,9 @@ OCTREE_FUNC(bool)::_remove_element_pair_and_remove_empty_octants(Element *p_elem
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;
@ -719,8 +731,9 @@ OCTREE_FUNC(bool)::_remove_element_pair_and_remove_empty_octants(Element *p_elem
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;
} }
@ -753,12 +766,14 @@ OCTREE_FUNC(void)::_unpair_element(Element *p_element, Octant *p_octant) {
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]);
}
} }
} }
@ -788,12 +803,14 @@ OCTREE_FUNC(void)::_pair_element(Element *p_element, Octant *p_octant) {
} }
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]);
}
} }
} }
@ -869,8 +886,9 @@ OCTREE_FUNC(OctreeElementID)::create(T *p_userdata, const AABB &p_aabb, int p_su
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;
@ -907,21 +925,24 @@ OCTREE_FUNC(void)::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
}
#ifdef OCTREE_USE_CACHED_LISTS #ifdef OCTREE_USE_CACHED_LISTS
e.moving(); e.moving();
@ -944,8 +965,9 @@ OCTREE_FUNC(void)::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);
@ -967,10 +989,11 @@ OCTREE_FUNC(void)::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);
}
#ifdef OCTREE_USE_CACHED_LISTS #ifdef OCTREE_USE_CACHED_LISTS
o->dirty = true; o->dirty = true;
@ -991,8 +1014,9 @@ OCTREE_FUNC(void)::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]);
}
} }
} }
@ -1008,8 +1032,9 @@ OCTREE_FUNC(void)::set_pairable(OctreeElementID p_id, bool p_pairable, uint32_t
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);
@ -1023,8 +1048,9 @@ OCTREE_FUNC(void)::set_pairable(OctreeElementID p_id, bool p_pairable, uint32_t
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);
}
} }
} }
@ -1043,8 +1069,9 @@ OCTREE_FUNC(void)::erase(OctreeElementID p_id) {
} }
OCTREE_FUNC(void)::_cull_convex(Octant *p_octant, _CullConvexData *p_cull) { OCTREE_FUNC(void)::_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()) {
#ifdef OCTREE_USE_CACHED_LISTS #ifdef OCTREE_USE_CACHED_LISTS
@ -1060,8 +1087,9 @@ OCTREE_FUNC(void)::_cull_convex(Octant *p_octant, _CullConvexData *p_cull) {
// The reason is that the later checks are more expensive because they are not in cache, and many of the AABB // The reason is that the later checks are more expensive because they are not in cache, and many of the AABB
// tests will fail so we can avoid these cache misses. // tests will fail so we can avoid these cache misses.
if (aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) { if (aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) {
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 (*p_cull->result_idx < p_cull->result_max) { if (*p_cull->result_idx < p_cull->result_max) {
@ -1080,8 +1108,9 @@ OCTREE_FUNC(void)::_cull_convex(Octant *p_octant, _CullConvexData *p_cull) {
Element *e = I->get(); Element *e = I->get();
const AABB &aabb = e->aabb; const AABB &aabb = e->aabb;
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 (aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) { if (aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) {
@ -1107,8 +1136,9 @@ OCTREE_FUNC(void)::_cull_convex(Octant *p_octant, _CullConvexData *p_cull) {
Element *e = p_octant->clist_pairable.elements[n]; Element *e = p_octant->clist_pairable.elements[n];
if (aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) { if (aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) {
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 (*p_cull->result_idx < p_cull->result_max) { if (*p_cull->result_idx < p_cull->result_max) {
@ -1128,8 +1158,9 @@ OCTREE_FUNC(void)::_cull_convex(Octant *p_octant, _CullConvexData *p_cull) {
Element *e = I->get(); Element *e = I->get();
const AABB &aabb = e->aabb; const AABB &aabb = e->aabb;
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 (aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) { if (aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) {
@ -1152,8 +1183,9 @@ OCTREE_FUNC(void)::_cull_convex(Octant *p_octant, _CullConvexData *p_cull) {
} }
OCTREE_FUNC(void)::_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) { OCTREE_FUNC(void)::_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()) {
#ifdef OCTREE_USE_CACHED_LISTS #ifdef OCTREE_USE_CACHED_LISTS
@ -1166,14 +1198,16 @@ OCTREE_FUNC(void)::_cull_aabb(Octant *p_octant, const AABB &p_aabb, T **p_result
Element *e = p_octant->clist.elements[n]; Element *e = p_octant->clist.elements[n];
if (p_aabb.intersects_inclusive(aabb)) { if (p_aabb.intersects_inclusive(aabb)) {
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_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 {
@ -1189,14 +1223,16 @@ OCTREE_FUNC(void)::_cull_aabb(Octant *p_octant, const AABB &p_aabb, T **p_result
const AABB &aabb = e->aabb; const AABB &aabb = e->aabb;
if (p_aabb.intersects_inclusive(aabb)) { if (p_aabb.intersects_inclusive(aabb)) {
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_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 {
@ -1218,14 +1254,16 @@ OCTREE_FUNC(void)::_cull_aabb(Octant *p_octant, const AABB &p_aabb, T **p_result
Element *e = p_octant->clist_pairable.elements[n]; Element *e = p_octant->clist_pairable.elements[n];
if (p_aabb.intersects_inclusive(aabb)) { if (p_aabb.intersects_inclusive(aabb)) {
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_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
@ -1240,15 +1278,17 @@ OCTREE_FUNC(void)::_cull_aabb(Octant *p_octant, const AABB &p_aabb, T **p_result
Element *e = I->get(); Element *e = I->get();
const AABB &aabb = e->aabb; const AABB &aabb = e->aabb;
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(aabb)) { if (p_aabb.intersects_inclusive(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
@ -1266,8 +1306,9 @@ OCTREE_FUNC(void)::_cull_aabb(Octant *p_octant, const AABB &p_aabb, T **p_result
} }
OCTREE_FUNC(void)::_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) { OCTREE_FUNC(void)::_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()) {
#ifdef OCTREE_USE_CACHED_LISTS #ifdef OCTREE_USE_CACHED_LISTS
@ -1279,15 +1320,17 @@ OCTREE_FUNC(void)::_cull_segment(Octant *p_octant, const Vector3 &p_from, const
const AABB &aabb = p_octant->clist.aabbs[n]; const AABB &aabb = p_octant->clist.aabbs[n];
Element *e = p_octant->clist.elements[n]; Element *e = p_octant->clist.elements[n];
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 (aabb.intersects_segment(p_from, p_to)) { if (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 {
@ -1303,15 +1346,17 @@ OCTREE_FUNC(void)::_cull_segment(Octant *p_octant, const Vector3 &p_from, const
Element *e = I->get(); Element *e = I->get();
const AABB &aabb = e->aabb; const AABB &aabb = e->aabb;
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 (aabb.intersects_segment(p_from, p_to)) { if (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 {
@ -1332,16 +1377,18 @@ OCTREE_FUNC(void)::_cull_segment(Octant *p_octant, const Vector3 &p_from, const
const AABB &aabb = p_octant->clist_pairable.aabbs[n]; const AABB &aabb = p_octant->clist_pairable.aabbs[n];
Element *e = p_octant->clist_pairable.elements[n]; Element *e = p_octant->clist_pairable.elements[n];
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 (aabb.intersects_segment(p_from, p_to)) { if (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)++;
@ -1357,16 +1404,18 @@ OCTREE_FUNC(void)::_cull_segment(Octant *p_octant, const Vector3 &p_from, const
Element *e = I->get(); Element *e = I->get();
const AABB &aabb = e->aabb; const AABB &aabb = e->aabb;
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 (aabb.intersects_segment(p_from, p_to)) { if (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)++;
@ -1386,8 +1435,9 @@ OCTREE_FUNC(void)::_cull_segment(Octant *p_octant, const Vector3 &p_from, const
} }
OCTREE_FUNC(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) { OCTREE_FUNC(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) {
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()) {
#ifdef OCTREE_USE_CACHED_LISTS #ifdef OCTREE_USE_CACHED_LISTS
@ -1400,14 +1450,16 @@ OCTREE_FUNC(void)::_cull_point(Octant *p_octant, const Vector3 &p_point, T **p_r
Element *e = p_octant->clist.elements[n]; Element *e = p_octant->clist.elements[n];
if (aabb.has_point(p_point)) { if (aabb.has_point(p_point)) {
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_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 {
@ -1422,15 +1474,17 @@ OCTREE_FUNC(void)::_cull_point(Octant *p_octant, const Vector3 &p_point, T **p_r
Element *e = I->get(); Element *e = I->get();
const AABB &aabb = e->aabb; const AABB &aabb = e->aabb;
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 (aabb.has_point(p_point)) { if (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 {
@ -1452,15 +1506,17 @@ OCTREE_FUNC(void)::_cull_point(Octant *p_octant, const Vector3 &p_point, T **p_r
Element *e = p_octant->clist_pairable.elements[n]; Element *e = p_octant->clist_pairable.elements[n];
if (aabb.has_point(p_point)) { if (aabb.has_point(p_point)) {
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_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)++;
@ -1476,16 +1532,18 @@ OCTREE_FUNC(void)::_cull_point(Octant *p_octant, const Vector3 &p_point, T **p_r
Element *e = I->get(); Element *e = I->get();
const AABB &aabb = e->aabb; const AABB &aabb = e->aabb;
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 (aabb.has_point(p_point)) { if (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)++;
@ -1506,12 +1564,14 @@ OCTREE_FUNC(void)::_cull_point(Octant *p_octant, const Vector3 &p_point, T **p_r
} }
OCTREE_FUNC(int)::cull_convex(const Vector<Plane> &p_convex, T **p_result_array, int p_result_max, uint32_t p_mask) { OCTREE_FUNC(int)::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++;
@ -1531,8 +1591,9 @@ OCTREE_FUNC(int)::cull_convex(const Vector<Plane> &p_convex, T **p_result_array,
} }
OCTREE_FUNC(int)::cull_aabb(const AABB &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) { OCTREE_FUNC(int)::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++;
@ -1542,8 +1603,9 @@ OCTREE_FUNC(int)::cull_aabb(const AABB &p_aabb, T **p_result_array, int p_result
} }
OCTREE_FUNC(int)::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) { OCTREE_FUNC(int)::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++;
@ -1553,8 +1615,9 @@ OCTREE_FUNC(int)::cull_segment(const Vector3 &p_from, const Vector3 &p_to, T **p
} }
OCTREE_FUNC(int)::cull_point(const Vector3 &p_point, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) { OCTREE_FUNC(int)::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++;
@ -1600,14 +1663,16 @@ OCTREE_FUNC(String)::debug_aabb_to_string(const AABB &aabb) const {
} }
OCTREE_FUNC(void)::debug_octants() { OCTREE_FUNC(void)::debug_octants() {
if (root) if (root) {
debug_octant(*root); debug_octant(*root);
}
} }
OCTREE_FUNC(void)::debug_octant(const Octant &oct, int depth) { OCTREE_FUNC(void)::debug_octant(const Octant &oct, int depth) {
String sz = ""; String sz = "";
for (int d = 0; d < depth; d++) for (int d = 0; d < depth; d++) {
sz += "\t"; sz += "\t";
}
sz += "Octant " + debug_aabb_to_string(oct.aabb); sz += "Octant " + debug_aabb_to_string(oct.aabb);
sz += "\tnum_children " + itos(oct.children_count); sz += "\tnum_children " + itos(oct.children_count);

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 &p_to, const real_t &p_weight) const {
real_t dot = from.dot(p_to); real_t dot = from.dot(p_to);
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

@ -63,10 +63,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;
} }
@ -208,15 +222,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;
@ -251,14 +269,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;
} }
@ -276,8 +298,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);
@ -306,15 +329,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;
} }
@ -360,15 +387,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

@ -147,8 +147,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;
@ -156,8 +157,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(PoolVector<int> *r_triangles_indices) const { void TriangleMesh::get_indices(PoolVector<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 PoolVector<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();
@ -246,18 +248,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;
} }
@ -346,19 +351,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;
@ -446,19 +454,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;
@ -518,16 +529,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)) {
@ -535,8 +548,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;
@ -563,14 +577,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;
@ -612,8 +628,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) {
@ -626,8 +643,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;
}
} }
} }
@ -655,14 +673,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;
@ -673,8 +693,9 @@ bool TriangleMesh::is_valid() const {
} }
PoolVector<Face3> TriangleMesh::get_faces() const { PoolVector<Face3> TriangleMesh::get_faces() const {
if (!valid) if (!valid) {
return PoolVector<Face3>(); return PoolVector<Face3>();
}
PoolVector<Face3> faces; PoolVector<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

@ -75,10 +75,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_weight; real_t t = p_weight;

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 (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;
} }
@ -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 (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;
} }
@ -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 (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;
} }
@ -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 (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

@ -46,8 +46,9 @@ Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, const V
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 method: " + type + ":" + p_method + " target ID: " + itos(p_id)); print_line("Failed method: " + type + ":" + p_method + " 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.");
@ -58,8 +59,9 @@ Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, const V
msg->instance_id = p_id; msg->instance_id = p_id;
msg->target = p_method; msg->target = p_method;
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);
@ -78,8 +80,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++;
} }
@ -93,8 +96,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.");
@ -166,22 +170,25 @@ 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->target)) if (!call_count.has(message->target)) {
call_count[message->target] = 0; call_count[message->target] = 0;
}
call_count[message->target]++; call_count[message->target]++;
} 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: {
if (!set_count.has(message->target)) if (!set_count.has(message->target)) {
set_count[message->target] = 0; set_count[message->target] = 0;
}
set_count[message->target]++; set_count[message->target]++;
@ -196,8 +203,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));
@ -255,8 +263,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;
@ -331,14 +340,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;

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