Merge pull request #48924 from akien-mga/3.x-cherrypicks
Cherry-picks for the 3.x branch (future 3.4) - 4th batch
This commit is contained in:
commit
7cd5967e99
|
@ -132,7 +132,7 @@ void XMLParser::_parse_closing_xml_element() {
|
||||||
++P;
|
++P;
|
||||||
const char *pBeginClose = P;
|
const char *pBeginClose = P;
|
||||||
|
|
||||||
while (*P != '>') {
|
while (*P && *P != '>') {
|
||||||
++P;
|
++P;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +140,10 @@ void XMLParser::_parse_closing_xml_element() {
|
||||||
#ifdef DEBUG_XML
|
#ifdef DEBUG_XML
|
||||||
print_line("XML CLOSE: " + node_name);
|
print_line("XML CLOSE: " + node_name);
|
||||||
#endif
|
#endif
|
||||||
++P;
|
|
||||||
|
if (*P) {
|
||||||
|
++P;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLParser::_ignore_definition() {
|
void XMLParser::_ignore_definition() {
|
||||||
|
@ -148,11 +151,14 @@ 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;
|
++P;
|
||||||
}
|
}
|
||||||
node_name.parse_utf8(F, P - F);
|
node_name.parse_utf8(F, P - F);
|
||||||
++P;
|
|
||||||
|
if (*P) {
|
||||||
|
++P;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XMLParser::_parse_cdata() {
|
bool XMLParser::_parse_cdata() {
|
||||||
|
@ -170,6 +176,7 @@ bool XMLParser::_parse_cdata() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*P) {
|
if (!*P) {
|
||||||
|
node_name = "";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,10 +195,9 @@ bool XMLParser::_parse_cdata() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cDataEnd) {
|
if (cDataEnd) {
|
||||||
node_name = String::utf8(cDataBegin, (int)(cDataEnd - cDataBegin));
|
cDataEnd = P;
|
||||||
} else {
|
|
||||||
node_name = "";
|
|
||||||
}
|
}
|
||||||
|
node_name = String::utf8(cDataBegin, (int)(cDataEnd - cDataBegin));
|
||||||
#ifdef DEBUG_XML
|
#ifdef DEBUG_XML
|
||||||
print_line("XML CDATA: " + node_name);
|
print_line("XML CDATA: " + node_name);
|
||||||
#endif
|
#endif
|
||||||
|
@ -203,24 +209,45 @@ void XMLParser::_parse_comment() {
|
||||||
node_type = NODE_COMMENT;
|
node_type = NODE_COMMENT;
|
||||||
P += 1;
|
P += 1;
|
||||||
|
|
||||||
char *pCommentBegin = P;
|
char *pEndOfInput = data + length;
|
||||||
|
char *pCommentBegin;
|
||||||
|
char *pCommentEnd;
|
||||||
|
|
||||||
int count = 1;
|
if (P + 1 < pEndOfInput && P[0] == '-' && P[1] == '-') {
|
||||||
|
// Comment, use '-->' as end.
|
||||||
|
pCommentBegin = P + 2;
|
||||||
|
for (pCommentEnd = pCommentBegin; pCommentEnd + 2 < pEndOfInput; pCommentEnd++) {
|
||||||
|
if (pCommentEnd[0] == '-' && pCommentEnd[1] == '-' && pCommentEnd[2] == '>') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pCommentEnd + 2 < pEndOfInput) {
|
||||||
|
P = pCommentEnd + 3;
|
||||||
|
} else {
|
||||||
|
P = pCommentEnd = pEndOfInput;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Like document type definition, match angle brackets.
|
||||||
|
pCommentBegin = P;
|
||||||
|
|
||||||
// move until end of comment reached
|
int count = 1;
|
||||||
while (count) {
|
while (*P && count) {
|
||||||
if (*P == '>') {
|
if (*P == '>') {
|
||||||
--count;
|
--count;
|
||||||
} else if (*P == '<') {
|
} else if (*P == '<') {
|
||||||
++count;
|
++count;
|
||||||
|
}
|
||||||
|
++P;
|
||||||
}
|
}
|
||||||
|
|
||||||
++P;
|
if (count) {
|
||||||
|
pCommentEnd = P;
|
||||||
|
} else {
|
||||||
|
pCommentEnd = P - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
P -= 3;
|
node_name = String::utf8(pCommentBegin, (int)(pCommentEnd - pCommentBegin));
|
||||||
node_name = String::utf8(pCommentBegin + 2, (int)(P - pCommentBegin - 2));
|
|
||||||
P += 3;
|
|
||||||
#ifdef DEBUG_XML
|
#ifdef DEBUG_XML
|
||||||
print_line("XML COMMENT: " + node_name);
|
print_line("XML COMMENT: " + node_name);
|
||||||
#endif
|
#endif
|
||||||
|
@ -235,14 +262,14 @@ 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 && *P != '>' && !_is_white_space(*P)) {
|
||||||
++P;
|
++P;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *endName = P;
|
const char *endName = P;
|
||||||
|
|
||||||
// find attributes
|
// find attributes
|
||||||
while (*P != '>') {
|
while (*P && *P != '>') {
|
||||||
if (_is_white_space(*P)) {
|
if (_is_white_space(*P)) {
|
||||||
++P;
|
++P;
|
||||||
} else {
|
} else {
|
||||||
|
@ -252,10 +279,14 @@ void XMLParser::_parse_opening_xml_element() {
|
||||||
// read the attribute names
|
// read the attribute names
|
||||||
const char *attributeNameBegin = P;
|
const char *attributeNameBegin = P;
|
||||||
|
|
||||||
while (!_is_white_space(*P) && *P != '=') {
|
while (*P && !_is_white_space(*P) && *P != '=') {
|
||||||
++P;
|
++P;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!*P) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const char *attributeNameEnd = P;
|
const char *attributeNameEnd = P;
|
||||||
++P;
|
++P;
|
||||||
|
|
||||||
|
@ -266,7 +297,7 @@ void XMLParser::_parse_opening_xml_element() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*P) { // malformatted xml file
|
if (!*P) { // malformatted xml file
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char attributeQuoteChar = *P;
|
const char attributeQuoteChar = *P;
|
||||||
|
@ -278,12 +309,10 @@ void XMLParser::_parse_opening_xml_element() {
|
||||||
++P;
|
++P;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*P) { // malformatted xml file
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *attributeValueEnd = P;
|
const char *attributeValueEnd = P;
|
||||||
++P;
|
if (*P) {
|
||||||
|
++P;
|
||||||
|
}
|
||||||
|
|
||||||
Attribute attr;
|
Attribute attr;
|
||||||
attr.name = String::utf8(attributeNameBegin,
|
attr.name = String::utf8(attributeNameBegin,
|
||||||
|
@ -315,7 +344,9 @@ void XMLParser::_parse_opening_xml_element() {
|
||||||
print_line("XML OPEN: " + node_name);
|
print_line("XML OPEN: " + node_name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
++P;
|
if (*P) {
|
||||||
|
++P;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLParser::_parse_current_node() {
|
void XMLParser::_parse_current_node() {
|
||||||
|
@ -327,10 +358,6 @@ void XMLParser::_parse_current_node() {
|
||||||
++P;
|
++P;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*P) {
|
|
||||||
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)) {
|
||||||
|
@ -338,6 +365,10 @@ void XMLParser::_parse_current_node() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!*P) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
++P;
|
++P;
|
||||||
|
|
||||||
// based on current token, parse and report next element
|
// based on current token, parse and report next element
|
||||||
|
|
|
@ -255,8 +255,8 @@ public:
|
||||||
static _ALWAYS_INLINE_ double db2linear(double p_db) { return Math::exp(p_db * 0.11512925464970228420089957273422); }
|
static _ALWAYS_INLINE_ double db2linear(double p_db) { return Math::exp(p_db * 0.11512925464970228420089957273422); }
|
||||||
static _ALWAYS_INLINE_ float db2linear(float p_db) { return Math::exp(p_db * 0.11512925464970228420089957273422); }
|
static _ALWAYS_INLINE_ float db2linear(float p_db) { return Math::exp(p_db * 0.11512925464970228420089957273422); }
|
||||||
|
|
||||||
static _ALWAYS_INLINE_ double round(double p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); }
|
static _ALWAYS_INLINE_ double round(double p_val) { return ::round(p_val); }
|
||||||
static _ALWAYS_INLINE_ float round(float p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); }
|
static _ALWAYS_INLINE_ float round(float p_val) { return ::roundf(p_val); }
|
||||||
|
|
||||||
static _ALWAYS_INLINE_ int64_t wrapi(int64_t value, int64_t min, int64_t max) {
|
static _ALWAYS_INLINE_ int64_t wrapi(int64_t value, int64_t min, int64_t max) {
|
||||||
int64_t range = max - min;
|
int64_t range = max - min;
|
||||||
|
@ -376,28 +376,10 @@ public:
|
||||||
return u.d;
|
return u.d;
|
||||||
}
|
}
|
||||||
|
|
||||||
//this function should be as fast as possible and rounding mode should not matter
|
// This function should be as fast as possible and rounding mode should not matter.
|
||||||
static _ALWAYS_INLINE_ int fast_ftoi(float a) {
|
static _ALWAYS_INLINE_ int fast_ftoi(float a) {
|
||||||
static int b;
|
// Assuming every supported compiler has `lrint()`.
|
||||||
|
return lrintf(a);
|
||||||
#if (defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0603) || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // windows 8 phone?
|
|
||||||
b = (int)((a > 0.0) ? (a + 0.5) : (a - 0.5));
|
|
||||||
|
|
||||||
#elif defined(_MSC_VER) && _MSC_VER < 1800
|
|
||||||
__asm fld a __asm fistp b
|
|
||||||
/*#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
|
|
||||||
// use AT&T inline assembly style, document that
|
|
||||||
// we use memory as output (=m) and input (m)
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"flds %1 \n\t"
|
|
||||||
"fistpl %0 \n\t"
|
|
||||||
: "=m" (b)
|
|
||||||
: "m" (a));*/
|
|
||||||
|
|
||||||
#else
|
|
||||||
b = lrintf(a); //assuming everything but msvc 2012 or earlier has lrint
|
|
||||||
#endif
|
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static _ALWAYS_INLINE_ uint32_t halfbits_to_floatbits(uint16_t h) {
|
static _ALWAYS_INLINE_ uint32_t halfbits_to_floatbits(uint16_t h) {
|
||||||
|
|
|
@ -65,8 +65,8 @@ public:
|
||||||
bool _set(const StringName &p_name, const Variant &p_value) {
|
bool _set(const StringName &p_name, const Variant &p_value) {
|
||||||
String name = p_name;
|
String name = p_name;
|
||||||
|
|
||||||
if (name.begins_with("bind/")) {
|
if (name.begins_with("bind/argument_")) {
|
||||||
int which = name.get_slice("/", 1).to_int() - 1;
|
int which = name.get_slice("_", 1).to_int() - 1;
|
||||||
ERR_FAIL_INDEX_V(which, params.size(), false);
|
ERR_FAIL_INDEX_V(which, params.size(), false);
|
||||||
params.write[which] = p_value;
|
params.write[which] = p_value;
|
||||||
} else {
|
} else {
|
||||||
|
@ -79,8 +79,8 @@ public:
|
||||||
bool _get(const StringName &p_name, Variant &r_ret) const {
|
bool _get(const StringName &p_name, Variant &r_ret) const {
|
||||||
String name = p_name;
|
String name = p_name;
|
||||||
|
|
||||||
if (name.begins_with("bind/")) {
|
if (name.begins_with("bind/argument_")) {
|
||||||
int which = name.get_slice("/", 1).to_int() - 1;
|
int which = name.get_slice("_", 1).to_int() - 1;
|
||||||
ERR_FAIL_INDEX_V(which, params.size(), false);
|
ERR_FAIL_INDEX_V(which, params.size(), false);
|
||||||
r_ret = params[which];
|
r_ret = params[which];
|
||||||
} else {
|
} else {
|
||||||
|
@ -92,7 +92,7 @@ public:
|
||||||
|
|
||||||
void _get_property_list(List<PropertyInfo> *p_list) const {
|
void _get_property_list(List<PropertyInfo> *p_list) const {
|
||||||
for (int i = 0; i < params.size(); i++) {
|
for (int i = 0; i < params.size(); i++) {
|
||||||
p_list->push_back(PropertyInfo(params[i].get_type(), "bind/" + itos(i + 1)));
|
p_list->push_back(PropertyInfo(params[i].get_type(), "bind/argument_" + itos(i + 1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -613,23 +613,35 @@ Vector<Vector<String>> EditorProfiler::get_data_as_csv() const {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// signatures
|
// Different metrics may contain different number of categories.
|
||||||
Vector<String> signatures;
|
Set<StringName> possible_signatures;
|
||||||
const Vector<EditorProfiler::Metric::Category> &categories = frame_metrics[0].categories;
|
for (int i = 0; i < frame_metrics.size(); i++) {
|
||||||
|
const Metric &m = frame_metrics[i];
|
||||||
for (int j = 0; j < categories.size(); j++) {
|
if (!m.valid) {
|
||||||
const EditorProfiler::Metric::Category &c = categories[j];
|
continue;
|
||||||
signatures.push_back(c.signature);
|
|
||||||
|
|
||||||
for (int k = 0; k < c.items.size(); k++) {
|
|
||||||
signatures.push_back(c.items[k].signature);
|
|
||||||
}
|
}
|
||||||
|
for (Map<StringName, Metric::Category *>::Element *E = m.category_ptrs.front(); E; E = E->next()) {
|
||||||
|
possible_signatures.insert(E->key());
|
||||||
|
}
|
||||||
|
for (Map<StringName, Metric::Category::Item *>::Element *E = m.item_ptrs.front(); E; E = E->next()) {
|
||||||
|
possible_signatures.insert(E->key());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate CSV header and cache indices.
|
||||||
|
Map<StringName, int> sig_map;
|
||||||
|
Vector<String> signatures;
|
||||||
|
signatures.resize(possible_signatures.size());
|
||||||
|
int sig_index = 0;
|
||||||
|
for (const Set<StringName>::Element *E = possible_signatures.front(); E; E = E->next()) {
|
||||||
|
signatures.write[sig_index] = E->get();
|
||||||
|
sig_map[E->get()] = sig_index;
|
||||||
|
sig_index++;
|
||||||
}
|
}
|
||||||
res.push_back(signatures);
|
res.push_back(signatures);
|
||||||
|
|
||||||
// values
|
// values
|
||||||
Vector<String> values;
|
Vector<String> values;
|
||||||
values.resize(signatures.size());
|
|
||||||
|
|
||||||
int index = last_metric;
|
int index = last_metric;
|
||||||
|
|
||||||
|
@ -640,20 +652,23 @@ Vector<Vector<String>> EditorProfiler::get_data_as_csv() const {
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!frame_metrics[index].valid) {
|
const Metric &m = frame_metrics[index];
|
||||||
|
|
||||||
|
if (!m.valid) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int it = 0;
|
|
||||||
const Vector<EditorProfiler::Metric::Category> &frame_cat = frame_metrics[index].categories;
|
|
||||||
|
|
||||||
for (int j = 0; j < frame_cat.size(); j++) {
|
// Don't keep old values since there may be empty cells.
|
||||||
const EditorProfiler::Metric::Category &c = frame_cat[j];
|
values.clear();
|
||||||
values.write[it++] = String::num_real(c.total_time);
|
values.resize(possible_signatures.size());
|
||||||
|
|
||||||
for (int k = 0; k < c.items.size(); k++) {
|
for (Map<StringName, Metric::Category *>::Element *E = m.category_ptrs.front(); E; E = E->next()) {
|
||||||
values.write[it++] = String::num_real(c.items[k].total);
|
values.write[sig_map[E->key()]] = String::num_real(E->value()->total_time);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
for (Map<StringName, Metric::Category::Item *>::Element *E = m.item_ptrs.front(); E; E = E->next()) {
|
||||||
|
values.write[sig_map[E->key()]] = String::num_real(E->value()->total);
|
||||||
|
}
|
||||||
|
|
||||||
res.push_back(values);
|
res.push_back(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -707,8 +707,10 @@ void FindInFilesPanel::draw_result_text(Object *item_obj, Rect2 rect) {
|
||||||
match_rect.position.y += 1 * EDSCALE;
|
match_rect.position.y += 1 * EDSCALE;
|
||||||
match_rect.size.y -= 2 * EDSCALE;
|
match_rect.size.y -= 2 * EDSCALE;
|
||||||
|
|
||||||
_results_display->draw_rect(match_rect, Color(0, 0, 0, 0.5));
|
// Use the inverted accent color to help match rectangles stand out even on the currently selected line.
|
||||||
// Text is drawn by Tree already
|
_results_display->draw_rect(match_rect, get_color("accent_color", "Editor").inverted() * Color(1, 1, 1, 0.5));
|
||||||
|
|
||||||
|
// Text is drawn by Tree already.
|
||||||
}
|
}
|
||||||
|
|
||||||
void FindInFilesPanel::_on_item_edited() {
|
void FindInFilesPanel::_on_item_edited() {
|
||||||
|
|
|
@ -1451,8 +1451,11 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR_FAIL_COND_V_MSG(img.is_null(), ERR_FILE_CORRUPT,
|
if (img.is_null()) {
|
||||||
vformat("glTF: Couldn't load image index '%d' with its given mimetype: %s.", i, mimetype));
|
ERR_PRINT(vformat("glTF: Couldn't load image index '%d' with its given mimetype: %s.", i, mimetype));
|
||||||
|
state.images.push_back(Ref<Texture>());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Ref<ImageTexture> t;
|
Ref<ImageTexture> t;
|
||||||
t.instance();
|
t.instance();
|
||||||
|
@ -2356,6 +2359,9 @@ bool EditorSceneImporterGLTF::_skins_are_same(const Ref<Skin> &skin_a, const Ref
|
||||||
if (skin_a->get_bind_bone(i) != skin_b->get_bind_bone(i)) {
|
if (skin_a->get_bind_bone(i) != skin_b->get_bind_bone(i)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (skin_a->get_bind_name(i) != skin_b->get_bind_name(i)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Transform a_xform = skin_a->get_bind_pose(i);
|
Transform a_xform = skin_a->get_bind_pose(i);
|
||||||
Transform b_xform = skin_b->get_bind_pose(i);
|
Transform b_xform = skin_b->get_bind_pose(i);
|
||||||
|
@ -3135,13 +3141,15 @@ void EditorSceneImporterGLTF::_process_mesh_instances(GLTFState &state, Spatial
|
||||||
const GLTFSkinIndex skin_i = node->skin;
|
const GLTFSkinIndex skin_i = node->skin;
|
||||||
|
|
||||||
Map<GLTFNodeIndex, Node *>::Element *mi_element = state.scene_nodes.find(node_i);
|
Map<GLTFNodeIndex, Node *>::Element *mi_element = state.scene_nodes.find(node_i);
|
||||||
|
ERR_CONTINUE_MSG(mi_element == nullptr, vformat("Unable to find node %d", node_i));
|
||||||
|
|
||||||
MeshInstance *mi = Object::cast_to<MeshInstance>(mi_element->get());
|
MeshInstance *mi = Object::cast_to<MeshInstance>(mi_element->get());
|
||||||
ERR_FAIL_COND(mi == nullptr);
|
ERR_CONTINUE_MSG(mi == nullptr, vformat("Unable to cast node %d of type %s to MeshInstance", node_i, mi_element->get()->get_class_name()));
|
||||||
|
|
||||||
const GLTFSkeletonIndex skel_i = state.skins[node->skin].skeleton;
|
const GLTFSkeletonIndex skel_i = state.skins[node->skin].skeleton;
|
||||||
const GLTFSkeleton &gltf_skeleton = state.skeletons[skel_i];
|
const GLTFSkeleton &gltf_skeleton = state.skeletons[skel_i];
|
||||||
Skeleton *skeleton = gltf_skeleton.godot_skeleton;
|
Skeleton *skeleton = gltf_skeleton.godot_skeleton;
|
||||||
ERR_FAIL_COND(skeleton == nullptr);
|
ERR_CONTINUE_MSG(skeleton == nullptr, vformat("Unable to find Skeleton for node %d skin %d", node_i, skin_i));
|
||||||
|
|
||||||
mi->get_parent()->remove_child(mi);
|
mi->get_parent()->remove_child(mi);
|
||||||
skeleton->add_child(mi);
|
skeleton->add_child(mi);
|
||||||
|
|
|
@ -80,10 +80,10 @@ void ViewportRotationControl::_notification(int p_what) {
|
||||||
axis_menu_options.clear();
|
axis_menu_options.clear();
|
||||||
axis_menu_options.push_back(SpatialEditorViewport::VIEW_RIGHT);
|
axis_menu_options.push_back(SpatialEditorViewport::VIEW_RIGHT);
|
||||||
axis_menu_options.push_back(SpatialEditorViewport::VIEW_TOP);
|
axis_menu_options.push_back(SpatialEditorViewport::VIEW_TOP);
|
||||||
axis_menu_options.push_back(SpatialEditorViewport::VIEW_FRONT);
|
axis_menu_options.push_back(SpatialEditorViewport::VIEW_REAR);
|
||||||
axis_menu_options.push_back(SpatialEditorViewport::VIEW_LEFT);
|
axis_menu_options.push_back(SpatialEditorViewport::VIEW_LEFT);
|
||||||
axis_menu_options.push_back(SpatialEditorViewport::VIEW_BOTTOM);
|
axis_menu_options.push_back(SpatialEditorViewport::VIEW_BOTTOM);
|
||||||
axis_menu_options.push_back(SpatialEditorViewport::VIEW_REAR);
|
axis_menu_options.push_back(SpatialEditorViewport::VIEW_FRONT);
|
||||||
|
|
||||||
axis_colors.clear();
|
axis_colors.clear();
|
||||||
axis_colors.push_back(get_color("axis_x_color", "Editor"));
|
axis_colors.push_back(get_color("axis_x_color", "Editor"));
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.device.audio-input</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.device.camera</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.cs.disable-library-validation</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.cs.allow-jit</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.cs.disable-library-validation</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.device.audio-input</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.device.camera</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -2238,31 +2238,45 @@ MainLoop *OS_OSX::get_main_loop() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
String OS_OSX::get_config_path() const {
|
String OS_OSX::get_config_path() const {
|
||||||
|
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well.
|
||||||
if (has_environment("XDG_CONFIG_HOME")) {
|
if (has_environment("XDG_CONFIG_HOME")) {
|
||||||
return get_environment("XDG_CONFIG_HOME");
|
if (get_environment("XDG_CONFIG_HOME").is_abs_path()) {
|
||||||
} else if (has_environment("HOME")) {
|
return get_environment("XDG_CONFIG_HOME");
|
||||||
return get_environment("HOME").plus_file("Library/Application Support");
|
} else {
|
||||||
} else {
|
WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `$HOME/Library/Application Support` or `.` per the XDG Base Directory specification.");
|
||||||
return ".";
|
}
|
||||||
}
|
}
|
||||||
|
if (has_environment("HOME")) {
|
||||||
|
return get_environment("HOME").plus_file("Library/Application Support");
|
||||||
|
}
|
||||||
|
return ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
String OS_OSX::get_data_path() const {
|
String OS_OSX::get_data_path() const {
|
||||||
|
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well.
|
||||||
if (has_environment("XDG_DATA_HOME")) {
|
if (has_environment("XDG_DATA_HOME")) {
|
||||||
return get_environment("XDG_DATA_HOME");
|
if (get_environment("XDG_DATA_HOME").is_abs_path()) {
|
||||||
} else {
|
return get_environment("XDG_DATA_HOME");
|
||||||
return get_config_path();
|
} else {
|
||||||
|
WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `get_config_path()` per the XDG Base Directory specification.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return get_config_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
String OS_OSX::get_cache_path() const {
|
String OS_OSX::get_cache_path() const {
|
||||||
|
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well.
|
||||||
if (has_environment("XDG_CACHE_HOME")) {
|
if (has_environment("XDG_CACHE_HOME")) {
|
||||||
return get_environment("XDG_CACHE_HOME");
|
if (get_environment("XDG_CACHE_HOME").is_abs_path()) {
|
||||||
} else if (has_environment("HOME")) {
|
return get_environment("XDG_CACHE_HOME");
|
||||||
return get_environment("HOME").plus_file("Library/Caches");
|
} else {
|
||||||
} else {
|
WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `$HOME/Libary/Caches` or `get_config_path()` per the XDG Base Directory specification.");
|
||||||
return get_config_path();
|
}
|
||||||
}
|
}
|
||||||
|
if (has_environment("HOME")) {
|
||||||
|
return get_environment("HOME").plus_file("Library/Caches");
|
||||||
|
}
|
||||||
|
return get_config_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
String OS_OSX::get_bundle_resource_dir() const {
|
String OS_OSX::get_bundle_resource_dir() const {
|
||||||
|
|
|
@ -3316,31 +3316,45 @@ MainLoop *OS_Windows::get_main_loop() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
String OS_Windows::get_config_path() const {
|
String OS_Windows::get_config_path() const {
|
||||||
if (has_environment("XDG_CONFIG_HOME")) { // unlikely, but after all why not?
|
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well.
|
||||||
return get_environment("XDG_CONFIG_HOME");
|
if (has_environment("XDG_CONFIG_HOME")) {
|
||||||
} else if (has_environment("APPDATA")) {
|
if (get_environment("XDG_CONFIG_HOME").is_abs_path()) {
|
||||||
return get_environment("APPDATA");
|
return get_environment("XDG_CONFIG_HOME");
|
||||||
} else {
|
} else {
|
||||||
return ".";
|
WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `%APPDATA%` or `.` per the XDG Base Directory specification.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (has_environment("APPDATA")) {
|
||||||
|
return get_environment("APPDATA");
|
||||||
|
}
|
||||||
|
return ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
String OS_Windows::get_data_path() const {
|
String OS_Windows::get_data_path() const {
|
||||||
|
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well.
|
||||||
if (has_environment("XDG_DATA_HOME")) {
|
if (has_environment("XDG_DATA_HOME")) {
|
||||||
return get_environment("XDG_DATA_HOME");
|
if (get_environment("XDG_DATA_HOME").is_abs_path()) {
|
||||||
} else {
|
return get_environment("XDG_DATA_HOME");
|
||||||
return get_config_path();
|
} else {
|
||||||
|
WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `get_config_path()` per the XDG Base Directory specification.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return get_config_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
String OS_Windows::get_cache_path() const {
|
String OS_Windows::get_cache_path() const {
|
||||||
|
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well.
|
||||||
if (has_environment("XDG_CACHE_HOME")) {
|
if (has_environment("XDG_CACHE_HOME")) {
|
||||||
return get_environment("XDG_CACHE_HOME");
|
if (get_environment("XDG_CACHE_HOME").is_abs_path()) {
|
||||||
} else if (has_environment("TEMP")) {
|
return get_environment("XDG_CACHE_HOME");
|
||||||
return get_environment("TEMP");
|
} else {
|
||||||
} else {
|
WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `%TEMP%` or `get_config_path()` per the XDG Base Directory specification.");
|
||||||
return get_config_path();
|
}
|
||||||
}
|
}
|
||||||
|
if (has_environment("TEMP")) {
|
||||||
|
return get_environment("TEMP");
|
||||||
|
}
|
||||||
|
return get_config_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get properly capitalized engine name for system paths
|
// Get properly capitalized engine name for system paths
|
||||||
|
|
|
@ -3208,32 +3208,44 @@ bool OS_X11::_check_internal_feature_support(const String &p_feature) {
|
||||||
|
|
||||||
String OS_X11::get_config_path() const {
|
String OS_X11::get_config_path() const {
|
||||||
if (has_environment("XDG_CONFIG_HOME")) {
|
if (has_environment("XDG_CONFIG_HOME")) {
|
||||||
return get_environment("XDG_CONFIG_HOME");
|
if (get_environment("XDG_CONFIG_HOME").is_abs_path()) {
|
||||||
} else if (has_environment("HOME")) {
|
return get_environment("XDG_CONFIG_HOME");
|
||||||
return get_environment("HOME").plus_file(".config");
|
} else {
|
||||||
} else {
|
WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `$HOME/.config` or `.` per the XDG Base Directory specification.");
|
||||||
return ".";
|
}
|
||||||
}
|
}
|
||||||
|
if (has_environment("HOME")) {
|
||||||
|
return get_environment("HOME").plus_file(".config");
|
||||||
|
}
|
||||||
|
return ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
String OS_X11::get_data_path() const {
|
String OS_X11::get_data_path() const {
|
||||||
if (has_environment("XDG_DATA_HOME")) {
|
if (has_environment("XDG_DATA_HOME")) {
|
||||||
return get_environment("XDG_DATA_HOME");
|
if (get_environment("XDG_DATA_HOME").is_abs_path()) {
|
||||||
} else if (has_environment("HOME")) {
|
return get_environment("XDG_DATA_HOME");
|
||||||
return get_environment("HOME").plus_file(".local/share");
|
} else {
|
||||||
} else {
|
WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `$HOME/.local/share` or `get_config_path()` per the XDG Base Directory specification.");
|
||||||
return get_config_path();
|
}
|
||||||
}
|
}
|
||||||
|
if (has_environment("HOME")) {
|
||||||
|
return get_environment("HOME").plus_file(".local/share");
|
||||||
|
}
|
||||||
|
return get_config_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
String OS_X11::get_cache_path() const {
|
String OS_X11::get_cache_path() const {
|
||||||
if (has_environment("XDG_CACHE_HOME")) {
|
if (has_environment("XDG_CACHE_HOME")) {
|
||||||
return get_environment("XDG_CACHE_HOME");
|
if (get_environment("XDG_CACHE_HOME").is_abs_path()) {
|
||||||
} else if (has_environment("HOME")) {
|
return get_environment("XDG_CACHE_HOME");
|
||||||
return get_environment("HOME").plus_file(".cache");
|
} else {
|
||||||
} else {
|
WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `$HOME/.cache` or `get_config_path()` per the XDG Base Directory specification.");
|
||||||
return get_config_path();
|
}
|
||||||
}
|
}
|
||||||
|
if (has_environment("HOME")) {
|
||||||
|
return get_environment("HOME").plus_file(".cache");
|
||||||
|
}
|
||||||
|
return get_config_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
String OS_X11::get_system_dir(SystemDir p_dir) const {
|
String OS_X11::get_system_dir(SystemDir p_dir) const {
|
||||||
|
|
|
@ -1166,7 +1166,7 @@ int TriangulatorPartition::MonotonePartition(List<TriangulatorPoly> *inpolys, Li
|
||||||
newedge.p1 = v->p;
|
newedge.p1 = v->p;
|
||||||
newedge.p2 = v->p;
|
newedge.p2 = v->p;
|
||||||
edgeIter = edgeTree.lower_bound(newedge);
|
edgeIter = edgeTree.lower_bound(newedge);
|
||||||
if(edgeIter == edgeTree.front()) {
|
if(edgeIter == nullptr || edgeIter == edgeTree.front()) {
|
||||||
error = true;
|
error = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1202,7 +1202,7 @@ int TriangulatorPartition::MonotonePartition(List<TriangulatorPoly> *inpolys, Li
|
||||||
newedge.p1 = v->p;
|
newedge.p1 = v->p;
|
||||||
newedge.p2 = v->p;
|
newedge.p2 = v->p;
|
||||||
edgeIter = edgeTree.lower_bound(newedge);
|
edgeIter = edgeTree.lower_bound(newedge);
|
||||||
if(edgeIter == edgeTree.front()) {
|
if(edgeIter == nullptr || edgeIter == edgeTree.front()) {
|
||||||
error = true;
|
error = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1241,7 +1241,7 @@ int TriangulatorPartition::MonotonePartition(List<TriangulatorPoly> *inpolys, Li
|
||||||
newedge.p1 = v->p;
|
newedge.p1 = v->p;
|
||||||
newedge.p2 = v->p;
|
newedge.p2 = v->p;
|
||||||
edgeIter = edgeTree.lower_bound(newedge);
|
edgeIter = edgeTree.lower_bound(newedge);
|
||||||
if(edgeIter == edgeTree.front()) {
|
if(edgeIter == nullptr || edgeIter == edgeTree.front()) {
|
||||||
error = true;
|
error = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue