Merge branch 'master' of git://github.com/godotengine/godot into kcc_lightoccluder2d_doc
This commit is contained in:
commit
134e24408a
177 changed files with 3729 additions and 1806 deletions
141
DONORS.md
Normal file
141
DONORS.md
Normal file
|
@ -0,0 +1,141 @@
|
|||
# Donors to the Godot Engine project
|
||||
|
||||
Godot Engine is a non-profit project developed by a community of voluntary
|
||||
contributors, as well as occasional paid contributors thanks to the financial
|
||||
support of generous donors.
|
||||
|
||||
The ways to donate to the project, as well as details on how the funds are
|
||||
used, are described on [Godot's website](https://godotengine.org/donate).
|
||||
|
||||
The following is a list of the current monthly donors, to be have their
|
||||
generous deed immortalized in the next stable release of Godot Engine.
|
||||
|
||||
## Platinum sponsors
|
||||
|
||||
None so far, but your company could be the first! :)
|
||||
|
||||
## Gold sponsors
|
||||
|
||||
Gamblify <https://www.gamblify.com>
|
||||
|
||||
## Mini sponsors
|
||||
|
||||
Arron Washington
|
||||
Chrisartguy
|
||||
Christian Uldall Pedersen
|
||||
Hein-Pieter van Braam
|
||||
Matthieu Huvé
|
||||
Neal Gompa (Conan Kudo)
|
||||
Olimpiu Metiu
|
||||
Ruslan Mustakov
|
||||
|
||||
## Gold donors
|
||||
|
||||
Alexander Otto
|
||||
Jake Bo
|
||||
Javier
|
||||
Nathan Warden
|
||||
Ranoller
|
||||
Rémi Verschelde
|
||||
Stephan Lanfermann
|
||||
|
||||
Andreas Schüle
|
||||
Bernhard Liebl
|
||||
Jordan M Lucas
|
||||
|
||||
BanjoNode2D
|
||||
Chris Serino
|
||||
Conrad Curry
|
||||
Craig Smith
|
||||
David Churchill
|
||||
Dean Harmon
|
||||
Guilherme Felipe de C. G. da Silva
|
||||
Henrique Alves
|
||||
Laurence Bannister
|
||||
Leo
|
||||
Przemysław Gołąb (n-pigeon)
|
||||
Robert Willes
|
||||
Robin Arys
|
||||
summerblind
|
||||
Testus Maximus
|
||||
Thomas Bjarnelöf
|
||||
|
||||
Amanda Haldy
|
||||
Andreas Haas
|
||||
Bryanna M
|
||||
Cody Parker
|
||||
D
|
||||
Ezra Theunissen
|
||||
flesk
|
||||
François Cantin
|
||||
Hendrik Mans
|
||||
Jeppe Zapp
|
||||
Johannes Wuensch
|
||||
Justin Arnold
|
||||
Justo Delgado Baudí
|
||||
Leandro Voltolino
|
||||
Myles
|
||||
Robert Podgorski
|
||||
Scott Beacon
|
||||
x1212
|
||||
|
||||
## Silver donors
|
||||
|
||||
Alex Barsukov
|
||||
Avencherus
|
||||
Bastian Böhm
|
||||
Ben Vercammen
|
||||
Bryan Stevenson
|
||||
Collin Shooltz
|
||||
Fabian Becker
|
||||
fengjiongmax
|
||||
Geequlim
|
||||
Gerrit Großkopf
|
||||
Guldoman
|
||||
hatniX
|
||||
HeartBeast
|
||||
Heribert Hirth
|
||||
Hunter Jones
|
||||
imekon
|
||||
Jacob McKenney
|
||||
Jonathon
|
||||
Josh 'Cheeseness' Bush
|
||||
Julian Murgia
|
||||
Juraj Móza
|
||||
Kevin Boyer
|
||||
Klavdij Voncina
|
||||
Lisandro Lorea
|
||||
magodev
|
||||
Martin Novák
|
||||
Matthew Fitzpatrick
|
||||
Matthew Valancy
|
||||
Matthias Hölzl
|
||||
Max R.R. Collada
|
||||
Michael Gringauz
|
||||
Mikael Olsson
|
||||
Moritz Laass
|
||||
nee
|
||||
nvgrod
|
||||
Pablo Seibelt
|
||||
Pan Ip
|
||||
Paul Mason
|
||||
Paweł Kowal
|
||||
Pietro Vertechi
|
||||
rayos
|
||||
Richman Stewart
|
||||
Roger Smith
|
||||
Sam Van Campenhout
|
||||
Sam Vila
|
||||
Sasori Olkof
|
||||
Sootstone
|
||||
Tavo Tell
|
||||
Tom Larrow
|
||||
Trent McPheron
|
||||
Troy Bonneau
|
||||
UltyX
|
||||
Xananax & karroffel
|
||||
|
||||
## Bronze donors
|
||||
|
||||
There are even more donors that support the project with a small monthly donation.
|
||||
Every bit counts and we thank every one of them for their amazing support!
|
|
@ -210,6 +210,17 @@ const Variant &Array::get(int p_idx) const {
|
|||
return operator[](p_idx);
|
||||
}
|
||||
|
||||
Array Array::duplicate() const {
|
||||
|
||||
Array new_arr;
|
||||
int element_count = size();
|
||||
new_arr.resize(element_count);
|
||||
for (int i = 0; i < element_count; i++) {
|
||||
new_arr[i] = get(i);
|
||||
}
|
||||
|
||||
return new_arr;
|
||||
}
|
||||
struct _ArrayVariantSort {
|
||||
|
||||
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
|
||||
|
|
|
@ -84,6 +84,8 @@ public:
|
|||
Variant pop_back();
|
||||
Variant pop_front();
|
||||
|
||||
Array duplicate() const;
|
||||
|
||||
Array(const Array &p_from);
|
||||
Array();
|
||||
~Array();
|
||||
|
|
|
@ -536,11 +536,9 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
|
|||
minfo.return_val = method->get_return_info();
|
||||
minfo.flags = method->get_hint_flags();
|
||||
|
||||
int defval_count = method->get_default_argument_count();
|
||||
minfo.default_arguments.resize(defval_count);
|
||||
|
||||
for (int i = 0; i < defval_count; i++) {
|
||||
minfo.default_arguments[i] = method->get_default_argument(defval_count - i - 1);
|
||||
for (int i = 0; i < method->get_argument_count(); i++) {
|
||||
if (method->has_default_argument(i))
|
||||
minfo.default_arguments.push_back(method->get_default_argument(i));
|
||||
}
|
||||
|
||||
p_methods->push_back(minfo);
|
||||
|
|
|
@ -1117,6 +1117,9 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
|
|||
memdelete(f);
|
||||
}
|
||||
ERR_FAIL_COND_V(!fw, ERR_CANT_CREATE);
|
||||
|
||||
uint8_t magic[4] = { 'R', 'S', 'R', 'C' };
|
||||
fw->store_buffer(magic, 4);
|
||||
}
|
||||
|
||||
bool big_endian = f->get_32();
|
||||
|
|
48
core/list.h
48
core/list.h
|
@ -291,6 +291,54 @@ public:
|
|||
erase(_data->first);
|
||||
}
|
||||
|
||||
Element *insert_after(Element *p_element, const T &p_value) {
|
||||
CRASH_COND(p_element && (!_data || p_element->data != _data));
|
||||
|
||||
if (!p_element) {
|
||||
return push_back(p_value);
|
||||
}
|
||||
|
||||
Element *n = memnew_allocator(Element, A);
|
||||
n->value = (T &)p_value;
|
||||
n->prev_ptr = p_element;
|
||||
n->next_ptr = p_element->next_ptr;
|
||||
n->data = _data;
|
||||
|
||||
if (!p_element->next_ptr) {
|
||||
_data->last = n;
|
||||
}
|
||||
|
||||
p_element->next_ptr = n;
|
||||
|
||||
_data->size_cache++;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
Element *insert_before(Element *p_element, const T &p_value) {
|
||||
CRASH_COND(p_element && (!_data || p_element->data != _data));
|
||||
|
||||
if (!p_element) {
|
||||
return push_back(p_value);
|
||||
}
|
||||
|
||||
Element *n = memnew_allocator(Element, A);
|
||||
n->value = (T &)p_value;
|
||||
n->prev_ptr = p_element->prev_ptr;
|
||||
n->next_ptr = p_element;
|
||||
n->data = _data;
|
||||
|
||||
if (!p_element->prev_ptr) {
|
||||
_data->first = n;
|
||||
}
|
||||
|
||||
p_element->prev_ptr = n;
|
||||
|
||||
_data->size_cache++;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* find an element in the list,
|
||||
*/
|
||||
|
|
|
@ -265,76 +265,28 @@ void CameraMatrix::get_viewport_size(real_t &r_width, real_t &r_height) const {
|
|||
|
||||
bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8points) const {
|
||||
|
||||
const real_t *matrix = (const real_t *)this->matrix;
|
||||
Vector<Plane> planes = get_projection_planes(Transform());
|
||||
const Planes intersections[8][3]={
|
||||
{PLANE_FAR,PLANE_LEFT,PLANE_TOP},
|
||||
{PLANE_FAR,PLANE_LEFT,PLANE_BOTTOM},
|
||||
{PLANE_FAR,PLANE_RIGHT,PLANE_TOP},
|
||||
{PLANE_FAR,PLANE_RIGHT,PLANE_BOTTOM},
|
||||
{PLANE_NEAR,PLANE_LEFT,PLANE_TOP},
|
||||
{PLANE_NEAR,PLANE_LEFT,PLANE_BOTTOM},
|
||||
{PLANE_NEAR,PLANE_RIGHT,PLANE_TOP},
|
||||
{PLANE_NEAR,PLANE_RIGHT,PLANE_BOTTOM},
|
||||
};
|
||||
|
||||
///////--- Near Plane ---///////
|
||||
Plane near_plane = Plane(matrix[3] + matrix[2],
|
||||
matrix[7] + matrix[6],
|
||||
matrix[11] + matrix[10],
|
||||
-matrix[15] - matrix[14]);
|
||||
near_plane.normalize();
|
||||
for(int i=0;i<8;i++) {
|
||||
|
||||
///////--- Far Plane ---///////
|
||||
Plane far_plane = Plane(matrix[2] - matrix[3],
|
||||
matrix[6] - matrix[7],
|
||||
matrix[10] - matrix[11],
|
||||
matrix[15] - matrix[14]);
|
||||
far_plane.normalize();
|
||||
|
||||
///////--- Right Plane ---///////
|
||||
Plane right_plane = Plane(matrix[0] - matrix[3],
|
||||
matrix[4] - matrix[7],
|
||||
matrix[8] - matrix[11],
|
||||
-matrix[15] + matrix[12]);
|
||||
right_plane.normalize();
|
||||
|
||||
///////--- Top Plane ---///////
|
||||
Plane top_plane = Plane(matrix[1] - matrix[3],
|
||||
matrix[5] - matrix[7],
|
||||
matrix[9] - matrix[11],
|
||||
-matrix[15] + matrix[13]);
|
||||
top_plane.normalize();
|
||||
|
||||
Vector3 near_endpoint_left, near_endpoint_right;
|
||||
Vector3 far_endpoint_left, far_endpoint_right;
|
||||
|
||||
bool res = near_plane.intersect_3(right_plane, top_plane, &near_endpoint_right);
|
||||
ERR_FAIL_COND_V(!res, false);
|
||||
|
||||
res = far_plane.intersect_3(right_plane, top_plane, &far_endpoint_right);
|
||||
ERR_FAIL_COND_V(!res, false);
|
||||
|
||||
if ((matrix[8] == 0) && (matrix[9] == 0)) {
|
||||
near_endpoint_left = near_endpoint_right;
|
||||
near_endpoint_left.x = -near_endpoint_left.x;
|
||||
|
||||
far_endpoint_left = far_endpoint_right;
|
||||
far_endpoint_left.x = -far_endpoint_left.x;
|
||||
} else {
|
||||
///////--- Left Plane ---///////
|
||||
Plane left_plane = Plane(matrix[0] + matrix[3],
|
||||
matrix[4] + matrix[7],
|
||||
matrix[8] + matrix[11],
|
||||
-matrix[15] - matrix[12]);
|
||||
left_plane.normalize();
|
||||
|
||||
res = near_plane.intersect_3(left_plane, top_plane, &near_endpoint_left);
|
||||
ERR_FAIL_COND_V(!res, false);
|
||||
|
||||
res = far_plane.intersect_3(left_plane, top_plane, &far_endpoint_left);
|
||||
Vector3 point;
|
||||
bool res = planes[intersections[i][0]].intersect_3(planes[intersections[i][1]],planes[intersections[i][2]], &point);
|
||||
ERR_FAIL_COND_V(!res, false);
|
||||
p_8points[i]=p_transform.xform(point);
|
||||
}
|
||||
|
||||
p_8points[0] = p_transform.xform(Vector3(near_endpoint_right.x, near_endpoint_right.y, near_endpoint_right.z));
|
||||
p_8points[1] = p_transform.xform(Vector3(near_endpoint_right.x, -near_endpoint_right.y, near_endpoint_right.z));
|
||||
p_8points[2] = p_transform.xform(Vector3(near_endpoint_left.x, near_endpoint_left.y, near_endpoint_left.z));
|
||||
p_8points[3] = p_transform.xform(Vector3(near_endpoint_left.x, -near_endpoint_left.y, near_endpoint_left.z));
|
||||
p_8points[4] = p_transform.xform(Vector3(far_endpoint_right.x, far_endpoint_right.y, far_endpoint_right.z));
|
||||
p_8points[5] = p_transform.xform(Vector3(far_endpoint_right.x, -far_endpoint_right.y, far_endpoint_right.z));
|
||||
p_8points[6] = p_transform.xform(Vector3(far_endpoint_left.x, far_endpoint_left.y, far_endpoint_left.z));
|
||||
p_8points[7] = p_transform.xform(Vector3(far_endpoint_left.x, -far_endpoint_left.y, far_endpoint_left.z));
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
Vector<Plane> CameraMatrix::get_projection_planes(const Transform &p_transform) const {
|
||||
|
@ -610,6 +562,12 @@ int CameraMatrix::get_pixels_per_meter(int p_for_pixel_width) const {
|
|||
return int((result.x * 0.5 + 0.5) * p_for_pixel_width);
|
||||
}
|
||||
|
||||
bool CameraMatrix::is_orthogonal() const {
|
||||
|
||||
return matrix[3][3]==1.0;
|
||||
}
|
||||
|
||||
|
||||
real_t CameraMatrix::get_fov() const {
|
||||
const real_t *matrix = (const real_t *)this->matrix;
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ struct CameraMatrix {
|
|||
real_t get_z_near() const;
|
||||
real_t get_aspect() const;
|
||||
real_t get_fov() const;
|
||||
bool is_orthogonal() const;
|
||||
|
||||
Vector<Plane> get_projection_planes(const Transform &p_transform) const;
|
||||
|
||||
|
@ -83,6 +84,7 @@ struct CameraMatrix {
|
|||
Plane xform4(const Plane &p_vec4) const;
|
||||
_FORCE_INLINE_ Vector3 xform(const Vector3 &p_vec3) const;
|
||||
|
||||
|
||||
operator String() const;
|
||||
|
||||
void scale_translate_to_fit(const Rect3 &p_aabb);
|
||||
|
|
|
@ -234,7 +234,22 @@ Basis Basis::scaled(const Vector3 &p_scale) const {
|
|||
return m;
|
||||
}
|
||||
|
||||
void Basis::set_scale(const Vector3 &p_scale) {
|
||||
|
||||
set_axis(0, get_axis(0).normalized() * p_scale.x);
|
||||
set_axis(1, get_axis(1).normalized() * p_scale.y);
|
||||
set_axis(2, get_axis(2).normalized() * p_scale.z);
|
||||
}
|
||||
|
||||
Vector3 Basis::get_scale() const {
|
||||
|
||||
return Vector3(
|
||||
Vector3(elements[0][0], elements[1][0], elements[2][0]).length(),
|
||||
Vector3(elements[0][1], elements[1][1], elements[2][1]).length(),
|
||||
Vector3(elements[0][2], elements[1][2], elements[2][2]).length());
|
||||
}
|
||||
|
||||
Vector3 Basis::get_signed_scale() const {
|
||||
// FIXME: We are assuming M = R.S (R is rotation and S is scaling), and use polar decomposition to extract R and S.
|
||||
// A polar decomposition is M = O.P, where O is an orthogonal matrix (meaning rotation and reflection) and
|
||||
// P is a positive semi-definite matrix (meaning it contains absolute values of scaling along its diagonal).
|
||||
|
|
|
@ -97,7 +97,9 @@ public:
|
|||
void scale(const Vector3 &p_scale);
|
||||
Basis scaled(const Vector3 &p_scale) const;
|
||||
|
||||
void set_scale(const Vector3 &p_scale);
|
||||
Vector3 get_scale() const;
|
||||
Vector3 get_signed_scale() const;
|
||||
|
||||
// transposed dot products
|
||||
_FORCE_INLINE_ real_t tdotx(const Vector3 &v) const {
|
||||
|
|
|
@ -118,17 +118,17 @@ Transform Transform::interpolate_with(const Transform &p_transform, real_t p_c)
|
|||
|
||||
/* not sure if very "efficient" but good enough? */
|
||||
|
||||
Vector3 src_scale = basis.get_scale();
|
||||
Quat src_rot = basis;
|
||||
Vector3 src_scale = basis.get_signed_scale();
|
||||
Quat src_rot = basis.orthonormalized();
|
||||
Vector3 src_loc = origin;
|
||||
|
||||
Vector3 dst_scale = p_transform.basis.get_scale();
|
||||
Vector3 dst_scale = p_transform.basis.get_signed_scale();
|
||||
Quat dst_rot = p_transform.basis;
|
||||
Vector3 dst_loc = p_transform.origin;
|
||||
|
||||
Transform dst;
|
||||
dst.basis = src_rot.slerp(dst_rot, p_c);
|
||||
dst.basis.scale(src_scale.linear_interpolate(dst_scale, p_c));
|
||||
Transform dst; //this could be made faster by using a single function in Basis..
|
||||
dst.basis = src_rot.slerp(dst_rot, p_c).normalized();
|
||||
dst.basis.set_scale(src_scale.linear_interpolate(dst_scale, p_c));
|
||||
dst.origin = src_loc.linear_interpolate(dst_loc, p_c);
|
||||
|
||||
return dst;
|
||||
|
|
|
@ -567,12 +567,6 @@ public:
|
|||
|
||||
template <class T>
|
||||
static T *cast_to(Object *p_object) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
// TODO there are some legitimate reasons to pass NULL as p_object.
|
||||
// we need to figure out how to deal with that in debug mode.
|
||||
// This code will return NULL for a NULL input in release mode also.
|
||||
ERR_FAIL_COND_V(p_object == NULL, NULL);
|
||||
#endif
|
||||
#ifndef NO_SAFE_CAST
|
||||
return dynamic_cast<T *>(p_object);
|
||||
#else
|
||||
|
@ -587,12 +581,6 @@ public:
|
|||
|
||||
template <class T>
|
||||
static const T *cast_to(const Object *p_object) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
// TODO there are some legitimate reasons to pass NULL as p_object.
|
||||
// we need to figure out how to deal with that in debug mode.
|
||||
// This code will return NULL for a NULL input in release mode also.
|
||||
ERR_FAIL_COND_V(p_object == NULL, NULL);
|
||||
#endif
|
||||
#ifndef NO_SAFE_CAST
|
||||
return dynamic_cast<const T *>(p_object);
|
||||
#else
|
||||
|
|
|
@ -69,12 +69,11 @@ void Resource::set_path(const String &p_path, bool p_take_over) {
|
|||
ResourceCache::resources.get(p_path)->set_name("");
|
||||
ResourceCache::lock->write_unlock();
|
||||
} else {
|
||||
ERR_EXPLAIN("Another resource is loaded from path: " + p_path);
|
||||
|
||||
ResourceCache::lock->read_lock();
|
||||
bool exists = ResourceCache::resources.has(p_path);
|
||||
ResourceCache::lock->read_unlock();
|
||||
|
||||
ERR_EXPLAIN("Another resource is loaded from path: " + p_path);
|
||||
ERR_FAIL_COND(exists);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -206,6 +206,7 @@ public:
|
|||
virtual int find_function(const String &p_function, const String &p_code) const = 0;
|
||||
virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const = 0;
|
||||
virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return ERR_UNAVAILABLE; }
|
||||
virtual bool overrides_external_editor() { return false; }
|
||||
|
||||
virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; }
|
||||
|
||||
|
|
102
core/string_buffer.cpp
Normal file
102
core/string_buffer.cpp
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*************************************************************************/
|
||||
/* string_buffer.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "string_buffer.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
StringBuffer &StringBuffer::append(CharType p_char) {
|
||||
reserve(string_length + 2);
|
||||
current_buffer_ptr()[string_length++] = p_char;
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringBuffer &StringBuffer::append(const String &p_string) {
|
||||
return append(p_string.c_str());
|
||||
}
|
||||
|
||||
StringBuffer &StringBuffer::append(const char *p_str) {
|
||||
int len = strlen(p_str);
|
||||
reserve(string_length + len + 1);
|
||||
|
||||
CharType *buf = current_buffer_ptr();
|
||||
for (const char *c_ptr = p_str; c_ptr; ++c_ptr) {
|
||||
buf[string_length++] = *c_ptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringBuffer &StringBuffer::append(const CharType *p_str, int p_clip_to_len) {
|
||||
int len = 0;
|
||||
while ((p_clip_to_len < 0 || len < p_clip_to_len) && p_str[len]) {
|
||||
++len;
|
||||
}
|
||||
reserve(string_length + len + 1);
|
||||
memcpy(&(current_buffer_ptr()[string_length]), p_str, len * sizeof(CharType));
|
||||
string_length += len;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringBuffer &StringBuffer::reserve(int p_size) {
|
||||
if (p_size < SHORT_BUFFER_SIZE || p_size < buffer.size())
|
||||
return *this;
|
||||
|
||||
bool need_copy = string_length > 0 && buffer.empty();
|
||||
buffer.resize(next_power_of_2(p_size));
|
||||
if (need_copy) {
|
||||
memcpy(buffer.ptr(), short_buffer, string_length * sizeof(CharType));
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
int StringBuffer::length() const {
|
||||
return string_length;
|
||||
}
|
||||
|
||||
String StringBuffer::as_string() {
|
||||
current_buffer_ptr()[string_length] = '\0';
|
||||
if (buffer.empty()) {
|
||||
return String(short_buffer);
|
||||
} else {
|
||||
buffer.resize(string_length + 1);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
double StringBuffer::as_double() {
|
||||
current_buffer_ptr()[string_length] = '\0';
|
||||
return String::to_double(current_buffer_ptr());
|
||||
}
|
||||
|
||||
int64_t StringBuffer::as_int() {
|
||||
current_buffer_ptr()[string_length] = '\0';
|
||||
return String::to_int(current_buffer_ptr());
|
||||
}
|
82
core/string_buffer.h
Normal file
82
core/string_buffer.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*************************************************************************/
|
||||
/* string_buffer.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef STRING_BUFFER_H
|
||||
#define STRING_BUFFER_H
|
||||
|
||||
#include "ustring.h"
|
||||
|
||||
class StringBuffer {
|
||||
static const int SHORT_BUFFER_SIZE = 64;
|
||||
|
||||
CharType short_buffer[SHORT_BUFFER_SIZE];
|
||||
String buffer;
|
||||
int string_length = 0;
|
||||
|
||||
_FORCE_INLINE_ CharType *current_buffer_ptr() {
|
||||
return static_cast<Vector<CharType> &>(buffer).empty() ? short_buffer : buffer.ptr();
|
||||
}
|
||||
|
||||
public:
|
||||
StringBuffer &append(CharType p_char);
|
||||
StringBuffer &append(const String &p_string);
|
||||
StringBuffer &append(const char *p_str);
|
||||
StringBuffer &append(const CharType *p_str, int p_clip_to_len = -1);
|
||||
|
||||
_FORCE_INLINE_ void operator+=(CharType p_char) {
|
||||
append(p_char);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void operator+=(const String &p_string) {
|
||||
append(p_string);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void operator+=(const char *p_str) {
|
||||
append(p_str);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void operator+=(const CharType *p_str) {
|
||||
append(p_str);
|
||||
}
|
||||
|
||||
StringBuffer &reserve(int p_size);
|
||||
|
||||
int length() const;
|
||||
|
||||
String as_string();
|
||||
|
||||
double as_double();
|
||||
int64_t as_int();
|
||||
|
||||
_FORCE_INLINE_ operator String() {
|
||||
return as_string();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
94
core/string_builder.cpp
Normal file
94
core/string_builder.cpp
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*************************************************************************/
|
||||
/* string_builder.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "string_builder.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
StringBuilder &StringBuilder::append(const String &p_string) {
|
||||
|
||||
strings.push_back(p_string);
|
||||
appended_strings.push_back(-1);
|
||||
|
||||
string_length += p_string.length();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringBuilder &StringBuilder::append(const char *p_cstring) {
|
||||
|
||||
int32_t len = strlen(p_cstring);
|
||||
|
||||
c_strings.push_back(p_cstring);
|
||||
appended_strings.push_back(len);
|
||||
|
||||
string_length += len;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
String StringBuilder::as_string() const {
|
||||
|
||||
CharType *buffer = memnew_arr(CharType, string_length);
|
||||
|
||||
int current_position = 0;
|
||||
|
||||
int godot_string_elem = 0;
|
||||
int c_string_elem = 0;
|
||||
|
||||
for (int i = 0; i < appended_strings.size(); i++) {
|
||||
if (appended_strings[i] == -1) {
|
||||
// Godot string
|
||||
const String &s = strings[godot_string_elem];
|
||||
|
||||
memcpy(buffer + current_position, s.ptr(), s.length() * sizeof(CharType));
|
||||
|
||||
current_position += s.length();
|
||||
|
||||
godot_string_elem++;
|
||||
} else {
|
||||
|
||||
const char *s = c_strings[c_string_elem];
|
||||
|
||||
for (int32_t j = 0; j < appended_strings[i]; j++) {
|
||||
buffer[current_position + j] = s[j];
|
||||
}
|
||||
|
||||
current_position += appended_strings[i];
|
||||
|
||||
c_string_elem++;
|
||||
}
|
||||
}
|
||||
|
||||
String final_string = String(buffer, string_length);
|
||||
|
||||
memdelete_arr(buffer);
|
||||
|
||||
return final_string;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*************************************************************************/
|
||||
/* button_group.h */
|
||||
/* string_builder.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
|
@ -27,42 +27,53 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef BUTTON_GROUP_H
|
||||
#define BUTTON_GROUP_H
|
||||
#ifndef STRING_BUILDER_H
|
||||
#define STRING_BUILDER_H
|
||||
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "core/ustring.h"
|
||||
|
||||
#if 0
|
||||
class BaseButton;
|
||||
#include "core/vector.h"
|
||||
|
||||
class ButtonGroup : public BoxContainer {
|
||||
class StringBuilder {
|
||||
|
||||
GDCLASS(ButtonGroup,BoxContainer);
|
||||
uint32_t string_length = 0;
|
||||
|
||||
Vector<String> strings;
|
||||
Vector<const char *> c_strings;
|
||||
|
||||
Set<BaseButton*> buttons;
|
||||
// -1 means it's a Godot String
|
||||
// a natural number means C string.
|
||||
Vector<int32_t> appended_strings;
|
||||
|
||||
|
||||
Array _get_button_list() const;
|
||||
void _pressed(Object *p_button);
|
||||
|
||||
protected:
|
||||
friend class BaseButton;
|
||||
|
||||
void _add_button(BaseButton *p_button);
|
||||
void _remove_button(BaseButton *p_button);
|
||||
|
||||
static void _bind_methods();
|
||||
public:
|
||||
StringBuilder &append(const String &p_string);
|
||||
StringBuilder &append(const char *p_cstring);
|
||||
|
||||
void get_button_list(List<BaseButton*> *p_buttons) const;
|
||||
BaseButton *get_pressed_button() const;
|
||||
BaseButton *get_focused_button() const;
|
||||
void set_pressed_button(BaseButton *p_button);
|
||||
int get_pressed_button_index() const;
|
||||
_FORCE_INLINE_ StringBuilder &operator+(const String &p_string) {
|
||||
return append(p_string);
|
||||
}
|
||||
|
||||
ButtonGroup();
|
||||
_FORCE_INLINE_ StringBuilder &operator+(const char *p_cstring) {
|
||||
return append(p_cstring);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void operator+=(const String &p_string) {
|
||||
append(p_string);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void operator+=(const char *p_cstring) {
|
||||
append(p_cstring);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ int num_strings_appended() const {
|
||||
return appended_strings.size();
|
||||
}
|
||||
|
||||
String as_string() const;
|
||||
|
||||
_FORCE_INLINE_ operator String() const {
|
||||
return as_string();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // BUTTON_GROUP_H
|
||||
#endif // STRING_BUILDER_H
|
|
@ -481,6 +481,7 @@ struct _VariantCall {
|
|||
VCALL_LOCALMEM1(Array, erase);
|
||||
VCALL_LOCALMEM0(Array, sort);
|
||||
VCALL_LOCALMEM2(Array, sort_custom);
|
||||
VCALL_LOCALMEM0R(Array, duplicate);
|
||||
VCALL_LOCALMEM0(Array, invert);
|
||||
|
||||
static void _call_PoolByteArray_get_string_from_ascii(Variant &r_ret, Variant &p_self, const Variant **p_args) {
|
||||
|
@ -1575,6 +1576,7 @@ void register_variant_methods() {
|
|||
ADDFUNC0(ARRAY, NIL, Array, sort, varray());
|
||||
ADDFUNC2(ARRAY, NIL, Array, sort_custom, OBJECT, "obj", STRING, "func", varray());
|
||||
ADDFUNC0(ARRAY, NIL, Array, invert, varray());
|
||||
ADDFUNC0(ARRAY, ARRAY, Array, duplicate, varray());
|
||||
|
||||
ADDFUNC0(POOL_BYTE_ARRAY, INT, PoolByteArray, size, varray());
|
||||
ADDFUNC2(POOL_BYTE_ARRAY, NIL, PoolByteArray, set, INT, "idx", INT, "byte", varray());
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
/*************************************************************************/
|
||||
#include "variant_parser.h"
|
||||
|
||||
#include "core/string_buffer.h"
|
||||
#include "io/resource_loader.h"
|
||||
#include "os/input_event.h"
|
||||
#include "os/keyboard.h"
|
||||
|
@ -176,14 +177,15 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
|
|||
};
|
||||
case '#': {
|
||||
|
||||
String color_str = "#";
|
||||
StringBuffer color_str;
|
||||
color_str += '#';
|
||||
while (true) {
|
||||
CharType ch = p_stream->get_char();
|
||||
if (p_stream->is_eof()) {
|
||||
r_token.type = TK_EOF;
|
||||
return OK;
|
||||
} else if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) {
|
||||
color_str += String::chr(ch);
|
||||
color_str += ch;
|
||||
|
||||
} else {
|
||||
p_stream->saved = ch;
|
||||
|
@ -191,7 +193,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
|
|||
}
|
||||
}
|
||||
|
||||
r_token.value = Color::html(color_str);
|
||||
r_token.value = Color::html(color_str.as_string());
|
||||
r_token.type = TK_COLOR;
|
||||
return OK;
|
||||
};
|
||||
|
@ -296,7 +298,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
|
|||
if (cchar == '-' || (cchar >= '0' && cchar <= '9')) {
|
||||
//a number
|
||||
|
||||
String num;
|
||||
StringBuffer num;
|
||||
#define READING_SIGN 0
|
||||
#define READING_INT 1
|
||||
#define READING_DEC 2
|
||||
|
@ -359,7 +361,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
|
|||
|
||||
if (reading == READING_DONE)
|
||||
break;
|
||||
num += String::chr(c);
|
||||
num += c;
|
||||
c = p_stream->get_char();
|
||||
}
|
||||
|
||||
|
@ -368,19 +370,19 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
|
|||
r_token.type = TK_NUMBER;
|
||||
|
||||
if (is_float)
|
||||
r_token.value = num.to_double();
|
||||
r_token.value = num.as_double();
|
||||
else
|
||||
r_token.value = num.to_int();
|
||||
r_token.value = num.as_int();
|
||||
return OK;
|
||||
|
||||
} else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') {
|
||||
|
||||
String id;
|
||||
StringBuffer id;
|
||||
bool first = true;
|
||||
|
||||
while ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_' || (!first && cchar >= '0' && cchar <= '9')) {
|
||||
|
||||
id += String::chr(cchar);
|
||||
id += cchar;
|
||||
cchar = p_stream->get_char();
|
||||
first = false;
|
||||
}
|
||||
|
@ -388,7 +390,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
|
|||
p_stream->saved = cchar;
|
||||
|
||||
r_token.type = TK_IDENTIFIER;
|
||||
r_token.value = id;
|
||||
r_token.value = id.as_string();
|
||||
return OK;
|
||||
} else {
|
||||
r_err_str = "Unexpected character.";
|
||||
|
|
1470
doc/base/classes.xml
1470
doc/base/classes.xml
File diff suppressed because it is too large
Load diff
|
@ -1115,6 +1115,10 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
|
|||
_copy_texscreen(Rect2());
|
||||
}
|
||||
|
||||
if (shader_ptr->canvas_item.uses_time) {
|
||||
VisualServerRaster::redraw_request();
|
||||
}
|
||||
|
||||
state.canvas_shader.set_custom_shader(shader_ptr->custom_code_id);
|
||||
state.canvas_shader.bind();
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "os/os.h"
|
||||
#include "project_settings.h"
|
||||
#include "rasterizer_canvas_gles3.h"
|
||||
#include "servers/visual/visual_server_raster.h"
|
||||
|
||||
#ifndef GLES_OVER_GL
|
||||
#define glClearDepth glClearDepthf
|
||||
|
@ -1939,6 +1940,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
|
|||
bool prev_use_instancing = false;
|
||||
|
||||
storage->info.render.draw_call_count += p_element_count;
|
||||
bool prev_opaque_prepass = false;
|
||||
|
||||
for (int i = 0; i < p_element_count; i++) {
|
||||
|
||||
|
@ -2072,6 +2074,13 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
|
|||
}
|
||||
}
|
||||
|
||||
bool use_opaque_prepass = e->sort_key & RenderList::SORT_KEY_OPAQUE_PRE_PASS;
|
||||
|
||||
if (use_opaque_prepass != prev_opaque_prepass) {
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_OPAQUE_PREPASS, use_opaque_prepass);
|
||||
rebind = true;
|
||||
}
|
||||
|
||||
bool use_instancing = e->instance->base_type == VS::INSTANCE_MULTIMESH || e->instance->base_type == VS::INSTANCE_PARTICLES;
|
||||
|
||||
if (use_instancing != prev_use_instancing) {
|
||||
|
@ -2127,6 +2136,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
|
|||
prev_shading = shading;
|
||||
prev_skeleton = skeleton;
|
||||
prev_use_instancing = use_instancing;
|
||||
prev_opaque_prepass = use_opaque_prepass;
|
||||
first = false;
|
||||
}
|
||||
|
||||
|
@ -2148,9 +2158,10 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
|
|||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_GI_PROBES, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_CONTACT_SHADOWS, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_VERTEX_LIGHTING, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_OPAQUE_PREPASS, false);
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_shadow) {
|
||||
void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_pass) {
|
||||
|
||||
RasterizerStorageGLES3::Material *m = NULL;
|
||||
RID m_src = p_instance->material_override.is_valid() ? p_instance->material_override : (p_material >= 0 ? p_instance->materials[p_material] : p_geometry->material);
|
||||
|
@ -2182,22 +2193,21 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
|
|||
|
||||
ERR_FAIL_COND(!m);
|
||||
|
||||
_add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_shadow);
|
||||
_add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_depth_pass);
|
||||
|
||||
while (m->next_pass.is_valid()) {
|
||||
m = storage->material_owner.getornull(m->next_pass);
|
||||
if (!m || !m->shader || !m->shader->valid)
|
||||
break;
|
||||
_add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_shadow);
|
||||
_add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_depth_pass);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_shadow) {
|
||||
void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass) {
|
||||
|
||||
bool has_base_alpha = (p_material->shader->spatial.uses_alpha && !p_material->shader->spatial.uses_alpha_scissor) || p_material->shader->spatial.uses_screen_texture;
|
||||
bool has_blend_alpha = p_material->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX;
|
||||
bool has_alpha = has_base_alpha || has_blend_alpha;
|
||||
bool shadow = false;
|
||||
|
||||
bool mirror = p_instance->mirror;
|
||||
bool no_cull = false;
|
||||
|
@ -2217,7 +2227,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
|
|||
state.used_screen_texture = true;
|
||||
}
|
||||
|
||||
if (p_shadow) {
|
||||
if (p_depth_pass) {
|
||||
|
||||
if (has_blend_alpha || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))
|
||||
return; //bye
|
||||
|
@ -2252,14 +2262,14 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
|
|||
e->geometry->index = current_geometry_index++;
|
||||
}
|
||||
|
||||
if (!p_shadow && directional_light && (directional_light->light_ptr->cull_mask & e->instance->layer_mask) == 0) {
|
||||
if (!p_depth_pass && directional_light && (directional_light->light_ptr->cull_mask & e->instance->layer_mask) == 0) {
|
||||
e->sort_key |= SORT_KEY_NO_DIRECTIONAL_FLAG;
|
||||
}
|
||||
|
||||
e->sort_key |= uint64_t(e->geometry->index) << RenderList::SORT_KEY_GEOMETRY_INDEX_SHIFT;
|
||||
e->sort_key |= uint64_t(e->instance->base_type) << RenderList::SORT_KEY_GEOMETRY_TYPE_SHIFT;
|
||||
|
||||
if (!p_shadow) {
|
||||
if (!p_depth_pass) {
|
||||
|
||||
if (e->material->last_pass != render_pass) {
|
||||
e->material->last_pass = render_pass;
|
||||
|
@ -2269,17 +2279,6 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
|
|||
e->sort_key |= uint64_t(e->material->index) << RenderList::SORT_KEY_MATERIAL_INDEX_SHIFT;
|
||||
e->sort_key |= uint64_t(e->instance->depth_layer) << RenderList::SORT_KEY_OPAQUE_DEPTH_LAYER_SHIFT;
|
||||
|
||||
if (!has_blend_alpha && has_alpha && p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
|
||||
|
||||
//if nothing exists, add this element as opaque too
|
||||
RenderList::Element *oe = render_list.add_element();
|
||||
|
||||
if (!oe)
|
||||
return;
|
||||
|
||||
copymem(oe, e, sizeof(RenderList::Element));
|
||||
}
|
||||
|
||||
if (e->instance->gi_probe_instances.size()) {
|
||||
e->sort_key |= SORT_KEY_GI_PROBES_FLAG;
|
||||
}
|
||||
|
@ -2302,24 +2301,21 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
|
|||
|
||||
//e->light_type=0xFF; // no lights!
|
||||
|
||||
if (shadow || p_material->shader->spatial.unshaded || state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
|
||||
|
||||
if (p_depth_pass || p_material->shader->spatial.unshaded || state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
|
||||
e->sort_key |= SORT_KEY_UNSHADED_FLAG;
|
||||
}
|
||||
|
||||
if (!shadow && (p_material->shader->spatial.uses_vertex_lighting || storage->config.force_vertex_shading)) {
|
||||
if (p_depth_pass && p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
|
||||
e->sort_key |= RenderList::SORT_KEY_OPAQUE_PRE_PASS;
|
||||
}
|
||||
|
||||
if (!p_depth_pass && (p_material->shader->spatial.uses_vertex_lighting || storage->config.force_vertex_shading)) {
|
||||
|
||||
e->sort_key |= SORT_KEY_VERTEX_LIT_FLAG;
|
||||
}
|
||||
|
||||
if (!shadow && has_alpha && p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
|
||||
//depth prepass for alpha
|
||||
RenderList::Element *eo = render_list.add_element();
|
||||
|
||||
eo->instance = e->instance;
|
||||
eo->geometry = e->geometry;
|
||||
eo->material = e->material;
|
||||
eo->sort_key = e->sort_key;
|
||||
if (p_material->shader->spatial.uses_time) {
|
||||
VisualServerRaster::redraw_request();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2603,7 +2599,7 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform
|
|||
}
|
||||
}
|
||||
|
||||
ubo_data.shadow_split_offsets[j] = 1.0 / li->shadow_transform[j].split;
|
||||
ubo_data.shadow_split_offsets[j] = li->shadow_transform[j].split;
|
||||
|
||||
Transform modelview = (p_camera_inverse_transform * li->shadow_transform[j].transform).inverse();
|
||||
|
||||
|
@ -3032,7 +3028,7 @@ void RasterizerSceneGLES3::_copy_texture_to_front_buffer(GLuint p_texture) {
|
|||
storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, false);
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_shadow) {
|
||||
void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass) {
|
||||
|
||||
current_geometry_index = 0;
|
||||
current_material_index = 0;
|
||||
|
@ -3057,7 +3053,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
|
|||
|
||||
int mat_idx = inst->materials[i].is_valid() ? i : -1;
|
||||
RasterizerStorageGLES3::Surface *s = mesh->surfaces[i];
|
||||
_add_geometry(s, inst, NULL, mat_idx, p_shadow);
|
||||
_add_geometry(s, inst, NULL, mat_idx, p_depth_pass);
|
||||
}
|
||||
|
||||
//mesh->last_pass=frame;
|
||||
|
@ -3080,7 +3076,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
|
|||
for (int i = 0; i < ssize; i++) {
|
||||
|
||||
RasterizerStorageGLES3::Surface *s = mesh->surfaces[i];
|
||||
_add_geometry(s, inst, multi_mesh, -1, p_shadow);
|
||||
_add_geometry(s, inst, multi_mesh, -1, p_depth_pass);
|
||||
}
|
||||
|
||||
} break;
|
||||
|
@ -3089,7 +3085,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
|
|||
RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getptr(inst->base);
|
||||
ERR_CONTINUE(!immediate);
|
||||
|
||||
_add_geometry(immediate, inst, NULL, -1, p_shadow);
|
||||
_add_geometry(immediate, inst, NULL, -1, p_depth_pass);
|
||||
|
||||
} break;
|
||||
case VS::INSTANCE_PARTICLES: {
|
||||
|
@ -3111,7 +3107,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
|
|||
for (int j = 0; j < ssize; j++) {
|
||||
|
||||
RasterizerStorageGLES3::Surface *s = mesh->surfaces[j];
|
||||
_add_geometry(s, inst, particles, -1, p_shadow);
|
||||
_add_geometry(s, inst, particles, -1, p_depth_pass);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3178,6 +3174,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
|
|||
for (int i = 0; i < storage->frame.current_rt->effects.ssao.depth_mipmap_fbos.size(); i++) {
|
||||
|
||||
state.ssao_minify_shader.set_conditional(SsaoMinifyShaderGLES3::MINIFY_START, i == 0);
|
||||
state.ssao_minify_shader.set_conditional(SsaoMinifyShaderGLES3::USE_ORTHOGONAL_PROJECTION, p_cam_projection.is_orthogonal());
|
||||
state.ssao_minify_shader.bind();
|
||||
state.ssao_minify_shader.set_uniform(SsaoMinifyShaderGLES3::CAMERA_Z_FAR, p_cam_projection.get_z_far());
|
||||
state.ssao_minify_shader.set_uniform(SsaoMinifyShaderGLES3::CAMERA_Z_NEAR, p_cam_projection.get_z_near());
|
||||
|
@ -3207,6 +3204,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
|
|||
glDepthFunc(GL_GREATER);
|
||||
// do SSAO!
|
||||
state.ssao_shader.set_conditional(SsaoShaderGLES3::ENABLE_RADIUS2, env->ssao_radius2 > 0.001);
|
||||
state.ssao_shader.set_conditional(SsaoShaderGLES3::USE_ORTHOGONAL_PROJECTION, p_cam_projection.is_orthogonal());
|
||||
state.ssao_shader.bind();
|
||||
state.ssao_shader.set_uniform(SsaoShaderGLES3::CAMERA_Z_FAR, p_cam_projection.get_z_far());
|
||||
state.ssao_shader.set_uniform(SsaoShaderGLES3::CAMERA_Z_NEAR, p_cam_projection.get_z_near());
|
||||
|
@ -3316,6 +3314,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
|
|||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->effects.ssao.blur_fbo[0]);
|
||||
glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
||||
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_ORTHOGONAL_PROJECTION, p_cam_projection.is_orthogonal());
|
||||
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_11_SAMPLES, subsurface_scatter_quality == SSS_QUALITY_LOW);
|
||||
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_17_SAMPLES, subsurface_scatter_quality == SSS_QUALITY_MEDIUM);
|
||||
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_25_SAMPLES, subsurface_scatter_quality == SSS_QUALITY_HIGH);
|
||||
|
@ -3370,6 +3369,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
|
|||
//perform SSR
|
||||
|
||||
state.ssr_shader.set_conditional(ScreenSpaceReflectionShaderGLES3::REFLECT_ROUGHNESS, env->ssr_roughness);
|
||||
state.ssr_shader.set_conditional(ScreenSpaceReflectionShaderGLES3::USE_ORTHOGONAL_PROJECTION, p_cam_projection.is_orthogonal());
|
||||
|
||||
state.ssr_shader.bind();
|
||||
|
||||
|
@ -3523,6 +3523,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
|
|||
int vp_h = storage->frame.current_rt->height;
|
||||
int vp_w = storage->frame.current_rt->width;
|
||||
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::USE_ORTHOGONAL_PROJECTION, p_cam_projection.is_orthogonal());
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_FAR_BLUR, true);
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_LOW, env->dof_blur_far_quality == VS::ENV_DOF_BLUR_QUALITY_LOW);
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_MEDIUM, env->dof_blur_far_quality == VS::ENV_DOF_BLUR_QUALITY_MEDIUM);
|
||||
|
@ -3565,6 +3566,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
|
|||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_LOW, false);
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_MEDIUM, false);
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_HIGH, false);
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::USE_ORTHOGONAL_PROJECTION, false);
|
||||
|
||||
composite_from = storage->frame.current_rt->effects.mip_maps[0].color;
|
||||
}
|
||||
|
@ -3577,6 +3579,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
|
|||
int vp_h = storage->frame.current_rt->height;
|
||||
int vp_w = storage->frame.current_rt->width;
|
||||
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::USE_ORTHOGONAL_PROJECTION, p_cam_projection.is_orthogonal());
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_NEAR_BLUR, true);
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_NEAR_FIRST_TAP, true);
|
||||
|
||||
|
@ -3652,6 +3655,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
|
|||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_LOW, false);
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_MEDIUM, false);
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_HIGH, false);
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::USE_ORTHOGONAL_PROJECTION, false);
|
||||
|
||||
composite_from = storage->frame.current_rt->effects.mip_maps[0].color;
|
||||
}
|
||||
|
@ -3743,6 +3747,8 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
|
|||
SWAP(exposure_shrink[exposure_shrink.size() - 1].color, storage->frame.current_rt->exposure.color);
|
||||
|
||||
glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
|
||||
|
||||
VisualServerRaster::redraw_request(); //if using auto exposure, redraw must happen
|
||||
}
|
||||
|
||||
int max_glow_level = -1;
|
||||
|
@ -4159,7 +4165,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
|
|||
|
||||
clear_color = env->bg_color.to_linear();
|
||||
storage->frame.clear_request = false;
|
||||
} else if (env->bg_mode == VS::ENV_BG_SKY) {
|
||||
} else if (env->bg_mode == VS::ENV_BG_SKY || env->bg_mode == VS::ENV_BG_COLOR_SKY) {
|
||||
|
||||
sky = storage->sky_owner.getornull(env->sky);
|
||||
|
||||
|
@ -4167,6 +4173,9 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
|
|||
env_radiance_tex = sky->radiance;
|
||||
}
|
||||
storage->frame.clear_request = false;
|
||||
if (env->bg_mode == VS::ENV_BG_COLOR_SKY) {
|
||||
clear_color = env->bg_color.to_linear();
|
||||
}
|
||||
|
||||
} else {
|
||||
storage->frame.clear_request = false;
|
||||
|
|
|
@ -664,6 +664,7 @@ public:
|
|||
//bits 12-8 geometry type
|
||||
SORT_KEY_GEOMETRY_TYPE_SHIFT = 8,
|
||||
//bits 0-7 for flags
|
||||
SORT_KEY_OPAQUE_PRE_PASS = 8,
|
||||
SORT_KEY_CULL_DISABLED_FLAG = 4,
|
||||
SORT_KEY_SKELETON_FLAG = 2,
|
||||
SORT_KEY_MIRROR_FLAG = 1
|
||||
|
@ -805,9 +806,9 @@ public:
|
|||
|
||||
void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const CameraMatrix &p_projection, GLuint p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows);
|
||||
|
||||
_FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_shadow);
|
||||
_FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_passs);
|
||||
|
||||
_FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_shadow);
|
||||
_FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass);
|
||||
|
||||
void _draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale, float p_energy);
|
||||
|
||||
|
@ -820,7 +821,7 @@ public:
|
|||
void _copy_to_front_buffer(Environment *env);
|
||||
void _copy_texture_to_front_buffer(GLuint p_texture); //used for debug
|
||||
|
||||
void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_shadow);
|
||||
void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass);
|
||||
|
||||
void _blur_effect_buffer();
|
||||
void _render_mrts(Environment *env, const CameraMatrix &p_cam_projection);
|
||||
|
|
|
@ -1584,6 +1584,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
|
|||
shaders.actions_canvas.usage_flag_pointers["SCREEN_UV"] = &p_shader->canvas_item.uses_screen_uv;
|
||||
shaders.actions_canvas.usage_flag_pointers["SCREEN_PIXEL_SIZE"] = &p_shader->canvas_item.uses_screen_uv;
|
||||
shaders.actions_canvas.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->canvas_item.uses_screen_texture;
|
||||
shaders.actions_canvas.usage_flag_pointers["TIME"] = &p_shader->canvas_item.uses_time;
|
||||
|
||||
actions = &shaders.actions_canvas;
|
||||
actions->uniforms = &p_shader->uniforms;
|
||||
|
@ -1632,6 +1633,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
|
|||
shaders.actions_scene.usage_flag_pointers["SSS_STRENGTH"] = &p_shader->spatial.uses_sss;
|
||||
shaders.actions_scene.usage_flag_pointers["DISCARD"] = &p_shader->spatial.uses_discard;
|
||||
shaders.actions_scene.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->spatial.uses_screen_texture;
|
||||
shaders.actions_scene.usage_flag_pointers["TIME"] = &p_shader->spatial.uses_time;
|
||||
|
||||
shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
|
||||
shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
|
||||
|
@ -4471,6 +4473,7 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type) {
|
|||
light->omni_shadow_mode = VS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID;
|
||||
light->omni_shadow_detail = VS::LIGHT_OMNI_SHADOW_DETAIL_VERTICAL;
|
||||
light->directional_blend_splits = false;
|
||||
light->directional_range_mode = VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE;
|
||||
light->reverse_cull = false;
|
||||
light->version = 0;
|
||||
|
||||
|
@ -4623,6 +4626,22 @@ VS::LightDirectionalShadowMode RasterizerStorageGLES3::light_directional_get_sha
|
|||
return light->directional_shadow_mode;
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::light_directional_set_shadow_depth_range_mode(RID p_light, VS::LightDirectionalShadowDepthRangeMode p_range_mode) {
|
||||
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
light->directional_range_mode=p_range_mode;
|
||||
}
|
||||
|
||||
VS::LightDirectionalShadowDepthRangeMode RasterizerStorageGLES3::light_directional_get_shadow_depth_range_mode(RID p_light) const {
|
||||
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE);
|
||||
|
||||
return light->directional_range_mode;
|
||||
}
|
||||
|
||||
VS::LightType RasterizerStorageGLES3::light_get_type(RID p_light) const {
|
||||
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
|
|
|
@ -410,6 +410,7 @@ public:
|
|||
int light_mode;
|
||||
bool uses_screen_texture;
|
||||
bool uses_screen_uv;
|
||||
bool uses_time;
|
||||
|
||||
} canvas_item;
|
||||
|
||||
|
@ -449,6 +450,7 @@ public:
|
|||
bool uses_discard;
|
||||
bool uses_sss;
|
||||
bool uses_screen_texture;
|
||||
bool uses_time;
|
||||
bool writes_modelview_or_projection;
|
||||
bool uses_vertex_lighting;
|
||||
|
||||
|
@ -877,6 +879,7 @@ public:
|
|||
VS::LightOmniShadowMode omni_shadow_mode;
|
||||
VS::LightOmniShadowDetail omni_shadow_detail;
|
||||
VS::LightDirectionalShadowMode directional_shadow_mode;
|
||||
VS::LightDirectionalShadowDepthRangeMode directional_range_mode;
|
||||
bool directional_blend_splits;
|
||||
uint64_t version;
|
||||
};
|
||||
|
@ -904,6 +907,9 @@ public:
|
|||
virtual VS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light);
|
||||
virtual VS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light);
|
||||
|
||||
virtual void light_directional_set_shadow_depth_range_mode(RID p_light, VS::LightDirectionalShadowDepthRangeMode p_range_mode);
|
||||
virtual VS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const;
|
||||
|
||||
virtual bool light_has_shadow(RID p_light) const;
|
||||
|
||||
virtual VS::LightType light_get_type(RID p_light) const;
|
||||
|
|
|
@ -438,26 +438,44 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
SL::BlockNode *bnode = (SL::BlockNode *)p_node;
|
||||
|
||||
//variables
|
||||
code += _mktab(p_level - 1) + "{\n";
|
||||
for (Map<StringName, SL::BlockNode::Variable>::Element *E = bnode->variables.front(); E; E = E->next()) {
|
||||
|
||||
code += _mktab(p_level) + _prestr(E->get().precision) + _typestr(E->get().type) + " " + _mkid(E->key()) + ";\n";
|
||||
if (!bnode->single_statement) {
|
||||
code += _mktab(p_level - 1) + "{\n";
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < bnode->statements.size(); i++) {
|
||||
|
||||
String scode = _dump_node_code(bnode->statements[i], p_level, r_gen_code, p_actions, p_default_actions);
|
||||
|
||||
if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW) {
|
||||
// FIXME: if (A || A) ? I am hesitant to delete one of them, could be copy-paste error.
|
||||
if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->single_statement ) {
|
||||
code += scode; //use directly
|
||||
} else {
|
||||
code += _mktab(p_level) + scode + ";\n";
|
||||
}
|
||||
}
|
||||
code += _mktab(p_level - 1) + "}\n";
|
||||
if (!bnode->single_statement) {
|
||||
code += _mktab(p_level - 1) + "}\n";
|
||||
}
|
||||
|
||||
} break;
|
||||
case SL::Node::TYPE_VARIABLE_DECLARATION: {
|
||||
SL::VariableDeclarationNode *vdnode = (SL::VariableDeclarationNode *)p_node;
|
||||
|
||||
String declaration = _prestr(vdnode->precision) + _typestr(vdnode->datatype);
|
||||
for(int i=0;i<vdnode->declarations.size();i++) {
|
||||
if (i>0) {
|
||||
declaration+=",";
|
||||
} else {
|
||||
declaration+=" ";
|
||||
}
|
||||
declaration += _mkid(vdnode->declarations[i].name);
|
||||
if (vdnode->declarations[i].initializer) {
|
||||
declaration+="=";
|
||||
declaration+=_dump_node_code(vdnode->declarations[i].initializer, p_level, r_gen_code, p_actions, p_default_actions);
|
||||
}
|
||||
}
|
||||
|
||||
code+=declaration;
|
||||
} break;
|
||||
case SL::Node::TYPE_VARIABLE: {
|
||||
SL::VariableNode *vnode = (SL::VariableNode *)p_node;
|
||||
|
||||
|
@ -600,6 +618,13 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
|
||||
code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions) + ")\n";
|
||||
code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions);
|
||||
} else if (cfnode->flow_op == SL::FLOW_OP_FOR) {
|
||||
|
||||
String left = _dump_node_code(cfnode->blocks[0], p_level, r_gen_code, p_actions, p_default_actions);
|
||||
String middle = _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions);
|
||||
String right = _dump_node_code(cfnode->expressions[1], p_level, r_gen_code, p_actions, p_default_actions);
|
||||
code += _mktab(p_level) + "for (" +left+";"+middle+";"+right+")\n";
|
||||
code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions);
|
||||
|
||||
} else if (cfnode->flow_op == SL::FLOW_OP_RETURN) {
|
||||
|
||||
|
@ -611,6 +636,12 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
} else if (cfnode->flow_op == SL::FLOW_OP_DISCARD) {
|
||||
|
||||
code = "discard;";
|
||||
} else if (cfnode->flow_op == SL::FLOW_OP_CONTINUE) {
|
||||
|
||||
code = "continue;";
|
||||
} else if (cfnode->flow_op == SL::FLOW_OP_BREAK) {
|
||||
|
||||
code = "break;";
|
||||
}
|
||||
|
||||
} break;
|
||||
|
@ -751,8 +782,9 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
|
|||
actions[VS::SHADER_SPATIAL].renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss";
|
||||
actions[VS::SHADER_SPATIAL].renames["ANISOTROPY"] = "anisotropy";
|
||||
actions[VS::SHADER_SPATIAL].renames["ANISOTROPY_FLOW"] = "anisotropy_flow";
|
||||
actions[VS::SHADER_SPATIAL].renames["SSS_SPREAD"] = "sss_spread";
|
||||
//actions[VS::SHADER_SPATIAL].renames["SSS_SPREAD"] = "sss_spread";
|
||||
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength";
|
||||
actions[VS::SHADER_SPATIAL].renames["TRANSMISSION"] = "transmission";
|
||||
actions[VS::SHADER_SPATIAL].renames["AO"] = "ao";
|
||||
actions[VS::SHADER_SPATIAL].renames["EMISSION"] = "emission";
|
||||
//actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"]=ShaderLanguage::TYPE_VEC2;
|
||||
|
@ -782,6 +814,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
|
|||
actions[VS::SHADER_SPATIAL].usage_defines["ALPHA_SCISSOR"] = "#define ALPHA_SCISSOR_USED\n";
|
||||
|
||||
actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
|
||||
actions[VS::SHADER_SPATIAL].usage_defines["TRANSMISSION"] = "#define TRANSMISSION_USED\n";
|
||||
actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
|
||||
actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
|
||||
|
||||
|
@ -792,7 +825,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
|
|||
|
||||
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
|
||||
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n";
|
||||
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_half_lambert"] = "#define DIFFUSE_HALF_LAMBERT\n";
|
||||
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
|
||||
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
|
||||
|
||||
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n";
|
||||
|
|
|
@ -116,7 +116,7 @@ void main() {
|
|||
|
||||
#ifdef USE_TEXTURE_RECT
|
||||
|
||||
if (dst_rect.z < 0) { // Transpose is encoded as negative dst_rect.z
|
||||
if (dst_rect.z < 0.0) { // Transpose is encoded as negative dst_rect.z
|
||||
uv_interp = src_rect.xy + abs(src_rect.zw) * vertex.yx;
|
||||
} else {
|
||||
uv_interp = src_rect.xy + abs(src_rect.zw) * vertex;
|
||||
|
@ -139,7 +139,7 @@ void main() {
|
|||
float frame_w = 1.0/float(h_frames);
|
||||
float frame_h = 1.0/float(v_frames);
|
||||
uv_interp.x = uv_interp.x * frame_w + frame_w * float(frame % h_frames);
|
||||
uv_interp.y = uv_interp.y * frame_h + frame_h * float(frame / v_frames);
|
||||
uv_interp.y = uv_interp.y * frame_h + frame_h * float(frame / h_frames);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -168,7 +168,11 @@ void main() {
|
|||
|
||||
float depth = textureLod( dof_source_depth, uv_interp, 0.0).r;
|
||||
depth = depth * 2.0 - 1.0;
|
||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
||||
depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0;
|
||||
#else
|
||||
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
|
||||
#endif
|
||||
|
||||
float amount = smoothstep(dof_begin,dof_end,depth);
|
||||
float k_accum=0.0;
|
||||
|
@ -182,8 +186,11 @@ void main() {
|
|||
|
||||
float tap_depth = texture( dof_source_depth, tap_uv, 0.0).r;
|
||||
tap_depth = tap_depth * 2.0 - 1.0;
|
||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
||||
tap_depth = ((tap_depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0;
|
||||
#else
|
||||
tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near));
|
||||
|
||||
#endif
|
||||
float tap_amount = mix(smoothstep(dof_begin,dof_end,tap_depth),1.0,int_ofs==0);
|
||||
tap_amount*=tap_amount*tap_amount; //prevent undesired glow effect
|
||||
|
||||
|
@ -221,7 +228,11 @@ void main() {
|
|||
|
||||
float tap_depth = texture( dof_source_depth, tap_uv, 0.0).r;
|
||||
tap_depth = tap_depth * 2.0 - 1.0;
|
||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
||||
tap_depth = ((tap_depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0;
|
||||
#else
|
||||
tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near));
|
||||
#endif
|
||||
float tap_amount = 1.0-smoothstep(dof_end,dof_begin,tap_depth);
|
||||
tap_amount*=tap_amount*tap_amount; //prevent undesired glow effect
|
||||
|
||||
|
|
|
@ -484,7 +484,7 @@ VERTEX_SHADER_CODE
|
|||
|
||||
vec3 directional_diffuse = vec3(0.0);
|
||||
vec3 directional_specular = vec3(0.0);
|
||||
light_compute(normal_interp,-light_direction_attenuation.xyz,-normalize( vertex_interp ),normal_interp,roughness,directional_diffuse,directional_specular);
|
||||
light_compute(normal_interp,-light_direction_attenuation.xyz,-normalize( vertex_interp ),light_color_energy.rgb,roughness,directional_diffuse,directional_specular);
|
||||
|
||||
float diff_avg = dot(diffuse_light_interp.rgb,vec3(0.33333));
|
||||
float diff_dir_avg = dot(directional_diffuse,vec3(0.33333));
|
||||
|
@ -887,7 +887,7 @@ float GTR1(float NdotH, float a)
|
|||
|
||||
|
||||
|
||||
void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 diffuse_color, float specular_blob_intensity, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse, inout vec3 specular) {
|
||||
void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse, inout vec3 specular) {
|
||||
|
||||
#if defined(USE_LIGHT_SHADER_CODE)
|
||||
//light is written by the light shader
|
||||
|
@ -900,10 +900,16 @@ LIGHT_SHADER_CODE
|
|||
|
||||
float dotNL = max(dot(N,L), 0.0 );
|
||||
|
||||
#if defined(DIFFUSE_HALF_LAMBERT)
|
||||
#if defined(DIFFUSE_OREN_NAYAR)
|
||||
vec3 light_amount;
|
||||
#else
|
||||
float light_amount;
|
||||
#endif
|
||||
|
||||
float hl = dot(N,L) * 0.5 + 0.5;
|
||||
diffuse += hl * light_color * diffuse_color;
|
||||
|
||||
#if defined(DIFFUSE_LAMBERT_WRAP)
|
||||
//energy conserving lambert wrap shader
|
||||
light_amount = max(0.0,(dot(N,L) + roughness) / ((1.0 + roughness) * (1.0 + roughness)));
|
||||
|
||||
#elif defined(DIFFUSE_OREN_NAYAR)
|
||||
|
||||
|
@ -919,12 +925,12 @@ LIGHT_SHADER_CODE
|
|||
vec3 A = 1.0 + sigma2 * (diffuse_color / (sigma2 + 0.13) + 0.5 / (sigma2 + 0.33));
|
||||
float B = 0.45 * sigma2 / (sigma2 + 0.09);
|
||||
|
||||
diffuse += diffuse_color * max(0.0, NdotL) * (A + vec3(B) * s / t) / M_PI;
|
||||
light_amount = max(0.0, NdotL) * (A + vec3(B) * s / t) / M_PI;
|
||||
}
|
||||
|
||||
#elif defined(DIFFUSE_TOON)
|
||||
|
||||
diffuse += smoothstep(-roughness,max(roughness,0.01),dot(N,L)) * light_color * diffuse_color;
|
||||
light_amount = smoothstep(-roughness,max(roughness,0.01),dot(N,L));
|
||||
|
||||
#elif defined(DIFFUSE_BURLEY)
|
||||
|
||||
|
@ -939,11 +945,17 @@ LIGHT_SHADER_CODE
|
|||
float lightScatter = f0 + (fd90 - f0) * pow(1.0 - NdotL, 5.0);
|
||||
float viewScatter = f0 + (fd90 - f0) * pow(1.0 - NdotV, 5.0);
|
||||
|
||||
diffuse+= light_color * diffuse_color * lightScatter * viewScatter * energyFactor;
|
||||
light_amount = lightScatter * viewScatter * energyFactor;
|
||||
}
|
||||
#else
|
||||
//lambert
|
||||
diffuse += dotNL * light_color * diffuse_color;
|
||||
light_amount = dotNL;
|
||||
#endif
|
||||
|
||||
#if defined(TRANSMISSION_USED)
|
||||
diffuse += light_color * diffuse_color * mix(vec3(light_amount),vec3(1.0),transmission);
|
||||
#else
|
||||
diffuse += light_color * diffuse_color * light_amount;
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -1116,7 +1128,7 @@ vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 po
|
|||
}
|
||||
#endif
|
||||
|
||||
void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity,inout vec3 diffuse_light, inout vec3 specular_light) {
|
||||
void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity,inout vec3 diffuse_light, inout vec3 specular_light) {
|
||||
|
||||
vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex;
|
||||
float light_length = length( light_rel_vec );
|
||||
|
@ -1170,11 +1182,11 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 bino
|
|||
light_attenuation*=mix(omni_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
|
||||
}
|
||||
|
||||
light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,omni_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
|
||||
light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,transmission,omni_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
|
||||
|
||||
}
|
||||
|
||||
void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
|
||||
void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, vec3 transmission,float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
|
||||
|
||||
vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz-vertex;
|
||||
float light_length = length( light_rel_vec );
|
||||
|
@ -1204,7 +1216,7 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi
|
|||
light_attenuation*=mix(spot_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
|
||||
}
|
||||
|
||||
light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,spot_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
|
||||
light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,transmission,spot_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1499,6 +1511,7 @@ void main() {
|
|||
//lay out everything, whathever is unused is optimized away anyway
|
||||
highp vec3 vertex = vertex_interp;
|
||||
vec3 albedo = vec3(0.8,0.8,0.8);
|
||||
vec3 transmission = vec3(0.0);
|
||||
float metallic = 0.0;
|
||||
float specular = 0.5;
|
||||
vec3 emission = vec3(0.0,0.0,0.0);
|
||||
|
@ -1577,6 +1590,12 @@ FRAGMENT_SHADER_CODE
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPAQUE_PREPASS
|
||||
|
||||
if (alpha<0.99) {
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_NORMALMAP)
|
||||
|
||||
|
@ -1678,9 +1697,16 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
vec3 light_attenuation=vec3(1.0);
|
||||
|
||||
float depth_z = -vertex.z;
|
||||
#ifdef LIGHT_DIRECTIONAL_SHADOW
|
||||
|
||||
if (gl_FragCoord.w > shadow_split_offsets.w) {
|
||||
#ifdef LIGHT_USE_PSSM4
|
||||
if (depth_z < shadow_split_offsets.w) {
|
||||
#elif defined(LIGHT_USE_PSSM2)
|
||||
if (depth_z < shadow_split_offsets.y) {
|
||||
#else
|
||||
if (depth_z < shadow_split_offsets.x) {
|
||||
#endif //LIGHT_USE_PSSM4
|
||||
|
||||
vec3 pssm_coord;
|
||||
float pssm_fade=0.0;
|
||||
|
@ -1689,17 +1715,15 @@ FRAGMENT_SHADER_CODE
|
|||
float pssm_blend;
|
||||
vec3 pssm_coord2;
|
||||
bool use_blend=true;
|
||||
vec3 light_pssm_split_inv = 1.0/shadow_split_offsets.xyz;
|
||||
float w_inv = 1.0/gl_FragCoord.w;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef LIGHT_USE_PSSM4
|
||||
|
||||
|
||||
if (gl_FragCoord.w > shadow_split_offsets.y) {
|
||||
if (depth_z < shadow_split_offsets.y) {
|
||||
|
||||
if (gl_FragCoord.w > shadow_split_offsets.x) {
|
||||
if (depth_z < shadow_split_offsets.x) {
|
||||
|
||||
highp vec4 splane=(shadow_matrix1 * vec4(vertex,1.0));
|
||||
pssm_coord=splane.xyz/splane.w;
|
||||
|
@ -1709,7 +1733,7 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
splane=(shadow_matrix2 * vec4(vertex,1.0));
|
||||
pssm_coord2=splane.xyz/splane.w;
|
||||
pssm_blend=smoothstep(0.0,light_pssm_split_inv.x,w_inv);
|
||||
pssm_blend=smoothstep(0.0,shadow_split_offsets.x,depth_z);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
|
@ -1720,14 +1744,14 @@ FRAGMENT_SHADER_CODE
|
|||
#if defined(LIGHT_USE_PSSM_BLEND)
|
||||
splane=(shadow_matrix3 * vec4(vertex,1.0));
|
||||
pssm_coord2=splane.xyz/splane.w;
|
||||
pssm_blend=smoothstep(light_pssm_split_inv.x,light_pssm_split_inv.y,w_inv);
|
||||
pssm_blend=smoothstep(shadow_split_offsets.x,shadow_split_offsets.y,depth_z);
|
||||
#endif
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
|
||||
if (gl_FragCoord.w > shadow_split_offsets.z) {
|
||||
if (depth_z < shadow_split_offsets.z) {
|
||||
|
||||
highp vec4 splane=(shadow_matrix3 * vec4(vertex,1.0));
|
||||
pssm_coord=splane.xyz/splane.w;
|
||||
|
@ -1735,13 +1759,14 @@ FRAGMENT_SHADER_CODE
|
|||
#if defined(LIGHT_USE_PSSM_BLEND)
|
||||
splane=(shadow_matrix4 * vec4(vertex,1.0));
|
||||
pssm_coord2=splane.xyz/splane.w;
|
||||
pssm_blend=smoothstep(light_pssm_split_inv.y,light_pssm_split_inv.z,w_inv);
|
||||
pssm_blend=smoothstep(shadow_split_offsets.y,shadow_split_offsets.z,depth_z);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
|
||||
highp vec4 splane=(shadow_matrix4 * vec4(vertex,1.0));
|
||||
pssm_coord=splane.xyz/splane.w;
|
||||
pssm_fade = smoothstep(shadow_split_offsets.z,shadow_split_offsets.w,gl_FragCoord.w);
|
||||
pssm_fade = smoothstep(shadow_split_offsets.z,shadow_split_offsets.w,depth_z);
|
||||
|
||||
#if defined(LIGHT_USE_PSSM_BLEND)
|
||||
use_blend=false;
|
||||
|
@ -1757,7 +1782,7 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
#ifdef LIGHT_USE_PSSM2
|
||||
|
||||
if (gl_FragCoord.w > shadow_split_offsets.x) {
|
||||
if (depth_z < shadow_split_offsets.x) {
|
||||
|
||||
highp vec4 splane=(shadow_matrix1 * vec4(vertex,1.0));
|
||||
pssm_coord=splane.xyz/splane.w;
|
||||
|
@ -1767,13 +1792,13 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
splane=(shadow_matrix2 * vec4(vertex,1.0));
|
||||
pssm_coord2=splane.xyz/splane.w;
|
||||
pssm_blend=smoothstep(0.0,light_pssm_split_inv.x,w_inv);
|
||||
pssm_blend=smoothstep(0.0,shadow_split_offsets.x,depth_z);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
highp vec4 splane=(shadow_matrix2 * vec4(vertex,1.0));
|
||||
pssm_coord=splane.xyz/splane.w;
|
||||
pssm_fade = smoothstep(shadow_split_offsets.x,shadow_split_offsets.y,gl_FragCoord.w);
|
||||
pssm_fade = smoothstep(shadow_split_offsets.x,shadow_split_offsets.y,depth_z);
|
||||
#if defined(LIGHT_USE_PSSM_BLEND)
|
||||
use_blend=false;
|
||||
|
||||
|
@ -1815,6 +1840,7 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
}
|
||||
|
||||
|
||||
#endif //LIGHT_DIRECTIONAL_SHADOW
|
||||
|
||||
#ifdef USE_VERTEX_LIGHTING
|
||||
|
@ -1822,7 +1848,7 @@ FRAGMENT_SHADER_CODE
|
|||
specular_light*=mix(vec3(1.0),light_attenuation,specular_light_interp.a);
|
||||
|
||||
#else
|
||||
light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb*light_attenuation,albedo,light_params.z*specular_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
|
||||
light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb*light_attenuation,albedo,transmission,light_params.z*specular_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -1860,11 +1886,11 @@ FRAGMENT_SHADER_CODE
|
|||
#else
|
||||
|
||||
for(int i=0;i<omni_light_count;i++) {
|
||||
light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light);
|
||||
light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,transmission,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light);
|
||||
}
|
||||
|
||||
for(int i=0;i<spot_light_count;i++) {
|
||||
light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light);
|
||||
light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,transmission,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light);
|
||||
}
|
||||
|
||||
#endif //USE_VERTEX_LIGHTING
|
||||
|
|
|
@ -56,7 +56,6 @@ vec2 view_to_screen(vec3 view_pos,out float w) {
|
|||
|
||||
#define M_PI 3.14159265359
|
||||
|
||||
|
||||
void main() {
|
||||
|
||||
|
||||
|
@ -158,8 +157,13 @@ void main() {
|
|||
w+=w_advance;
|
||||
|
||||
//convert to linear depth
|
||||
|
||||
depth = texture(source_depth, pos*pixel_size).r * 2.0 - 1.0;
|
||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
||||
depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0;
|
||||
#else
|
||||
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
|
||||
#endif
|
||||
depth=-depth;
|
||||
|
||||
z_from = z_to;
|
||||
|
|
|
@ -65,7 +65,12 @@ layout(location = 0) out float visibility;
|
|||
uniform vec4 proj_info;
|
||||
|
||||
vec3 reconstructCSPosition(vec2 S, float z) {
|
||||
return vec3((S.xy * proj_info.xy + proj_info.zw) * z, z);
|
||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
||||
return vec3((S.xy * proj_info.xy + proj_info.zw), z);
|
||||
#else
|
||||
return vec3((S.xy * proj_info.xy + proj_info.zw) * z, z);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
vec3 getPosition(ivec2 ssP) {
|
||||
|
@ -73,7 +78,11 @@ vec3 getPosition(ivec2 ssP) {
|
|||
P.z = texelFetch(source_depth, ssP, 0).r;
|
||||
|
||||
P.z = P.z * 2.0 - 1.0;
|
||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
||||
P.z = ((P.z + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0;
|
||||
#else
|
||||
P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near));
|
||||
#endif
|
||||
P.z = -P.z;
|
||||
|
||||
// Offset to pixel center
|
||||
|
@ -118,7 +127,12 @@ vec3 getOffsetPosition(ivec2 ssC, vec2 unitOffset, float ssR) {
|
|||
//read from depth buffer
|
||||
P.z = texelFetch(source_depth, mipP, 0).r;
|
||||
P.z = P.z * 2.0 - 1.0;
|
||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
||||
P.z = ((P.z + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0;
|
||||
#else
|
||||
P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near));
|
||||
|
||||
#endif
|
||||
P.z = -P.z;
|
||||
|
||||
} else {
|
||||
|
@ -214,8 +228,11 @@ void main() {
|
|||
|
||||
// Choose the screen-space sample radius
|
||||
// proportional to the projected area of the sphere
|
||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
||||
float ssDiskRadius = -proj_scale * radius;
|
||||
#else
|
||||
float ssDiskRadius = -proj_scale * radius / C.z;
|
||||
|
||||
#endif
|
||||
float sum = 0.0;
|
||||
for (int i = 0; i < NUM_SAMPLES; ++i) {
|
||||
sum += sampleAO(ssC, C, n_C, ssDiskRadius, radius,i, randomPatternRotationAngle);
|
||||
|
|
|
@ -41,7 +41,11 @@ void main() {
|
|||
#ifdef MINIFY_START
|
||||
float fdepth = texelFetch(source_depth, clamp(ssP * 2 + ivec2(ssP.y & 1, ssP.x & 1), ivec2(0), from_size - ivec2(1)), source_mipmap).r;
|
||||
fdepth = fdepth * 2.0 - 1.0;
|
||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
||||
fdepth = ((fdepth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0;
|
||||
#else
|
||||
fdepth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - fdepth * (camera_z_far - camera_z_near));
|
||||
#endif
|
||||
fdepth /= camera_z_far;
|
||||
depth = uint(clamp(fdepth*65535.0,0.0,65535.0));
|
||||
|
||||
|
|
|
@ -17,36 +17,36 @@ void main() {
|
|||
|
||||
//#define QUALIFIER uniform // some guy on the interweb says it may be faster with this
|
||||
#define QUALIFIER const
|
||||
|
||||
#ifdef USE_25_SAMPLES
|
||||
|
||||
const int kernel_size=25;
|
||||
|
||||
QUALIFIER vec2 kernel[25] = vec2[] (
|
||||
vec2(0.099654,0.0),
|
||||
vec2(0.001133,-3.0),
|
||||
vec2(0.002316,-2.52083),
|
||||
vec2(0.00445,-2.08333),
|
||||
vec2(0.008033,-1.6875),
|
||||
vec2(0.013627,-1.33333),
|
||||
vec2(0.021724,-1.02083),
|
||||
vec2(0.032542,-0.75),
|
||||
vec2(0.04581,-0.520833),
|
||||
vec2(0.0606,-0.333333),
|
||||
vec2(0.075333,-0.1875),
|
||||
vec2(0.088001,-0.0833333),
|
||||
vec2(0.096603,-0.0208333),
|
||||
vec2(0.096603,0.0208333),
|
||||
vec2(0.088001,0.0833333),
|
||||
vec2(0.075333,0.1875),
|
||||
vec2(0.0606,0.333333),
|
||||
vec2(0.04581,0.520833),
|
||||
vec2(0.032542,0.75),
|
||||
vec2(0.021724,1.02083),
|
||||
vec2(0.013627,1.33333),
|
||||
vec2(0.008033,1.6875),
|
||||
vec2(0.00445,2.08333),
|
||||
vec2(0.002316,2.52),
|
||||
vec2(0.001133,3.0)
|
||||
vec2(0.530605, 0.0),
|
||||
vec2(0.000973794, -3.0),
|
||||
vec2(0.00333804, -2.52083),
|
||||
vec2(0.00500364, -2.08333),
|
||||
vec2(0.00700976, -1.6875),
|
||||
vec2(0.0094389, -1.33333),
|
||||
vec2(0.0128496, -1.02083),
|
||||
vec2(0.017924, -0.75),
|
||||
vec2(0.0263642, -0.520833),
|
||||
vec2(0.0410172, -0.333333),
|
||||
vec2(0.0493588, -0.1875),
|
||||
vec2(0.0402784, -0.0833333),
|
||||
vec2(0.0211412, -0.0208333),
|
||||
vec2(0.0211412, 0.0208333),
|
||||
vec2(0.0402784, 0.0833333),
|
||||
vec2(0.0493588, 0.1875),
|
||||
vec2(0.0410172, 0.333333),
|
||||
vec2(0.0263642, 0.520833),
|
||||
vec2(0.017924, 0.75),
|
||||
vec2(0.0128496, 1.02083),
|
||||
vec2(0.0094389, 1.33333),
|
||||
vec2(0.00700976, 1.6875),
|
||||
vec2(0.00500364, 2.08333),
|
||||
vec2(0.00333804, 2.52083),
|
||||
vec2(0.000973794, 3.0)
|
||||
);
|
||||
|
||||
#endif //USE_25_SAMPLES
|
||||
|
@ -56,23 +56,23 @@ vec2(0.001133,3.0)
|
|||
const int kernel_size=17;
|
||||
|
||||
QUALIFIER vec2 kernel[17] = vec2[](
|
||||
vec2(0.197417,0.0),
|
||||
vec2(0.000078,-2.0),
|
||||
vec2(0.000489,-1.53125),
|
||||
vec2(0.002403,-1.125),
|
||||
vec2(0.009245,-0.78125),
|
||||
vec2(0.027835,-0.5),
|
||||
vec2(0.065592,-0.28125),
|
||||
vec2(0.12098,-0.125),
|
||||
vec2(0.17467,-0.03125),
|
||||
vec2(0.17467,0.03125),
|
||||
vec2(0.12098,0.125),
|
||||
vec2(0.065592,0.28125),
|
||||
vec2(0.027835,0.5),
|
||||
vec2(0.009245,0.78125),
|
||||
vec2(0.002403,1.125),
|
||||
vec2(0.000489,1.53125),
|
||||
vec2(0.000078,2.0)
|
||||
vec2(0.536343, 0.0),
|
||||
vec2(0.00317394, -2.0),
|
||||
vec2(0.0100386, -1.53125),
|
||||
vec2(0.0144609, -1.125),
|
||||
vec2(0.0216301, -0.78125),
|
||||
vec2(0.0347317, -0.5),
|
||||
vec2(0.0571056, -0.28125),
|
||||
vec2(0.0582416, -0.125),
|
||||
vec2(0.0324462, -0.03125),
|
||||
vec2(0.0324462, 0.03125),
|
||||
vec2(0.0582416, 0.125),
|
||||
vec2(0.0571056, 0.28125),
|
||||
vec2(0.0347317, 0.5),
|
||||
vec2(0.0216301, 0.78125),
|
||||
vec2(0.0144609, 1.125),
|
||||
vec2(0.0100386, 1.53125),
|
||||
vec2(0.00317394,2.0)
|
||||
);
|
||||
|
||||
#endif //USE_17_SAMPLES
|
||||
|
@ -82,23 +82,24 @@ vec2(0.000078,2.0)
|
|||
|
||||
const int kernel_size=11;
|
||||
|
||||
QUALIFIER vec2 kernel[kernel_size] = vec2[](
|
||||
vec2(0.198596,0.0),
|
||||
vec2(0.0093,-2.0),
|
||||
vec2(0.028002,-1.28),
|
||||
vec2(0.065984,-0.72),
|
||||
vec2(0.121703,-0.32),
|
||||
vec2(0.175713,-0.08),
|
||||
vec2(0.175713,0.08),
|
||||
vec2(0.121703,0.32),
|
||||
vec2(0.065984,0.72),
|
||||
vec2(0.028002,1.28),
|
||||
vec2(0.0093,2.0)
|
||||
QUALIFIER vec4 kernel[11] = vec4[](
|
||||
vec4(0.560479, 0.0),
|
||||
vec4(0.00471691, -2.0),
|
||||
vec4(0.0192831, -1.28),
|
||||
vec4(0.03639, -0.72),
|
||||
vec4(0.0821904, -0.32),
|
||||
vec4(0.0771802, -0.08),
|
||||
vec4(0.0771802, 0.08),
|
||||
vec4(0.0821904, 0.32),
|
||||
vec4(0.03639, 0.72),
|
||||
vec4(0.0192831, 1.28),
|
||||
vec4(0.00471691,2.0)
|
||||
);
|
||||
|
||||
#endif //USE_11_SAMPLES
|
||||
|
||||
|
||||
|
||||
uniform float max_radius;
|
||||
uniform float camera_z_far;
|
||||
uniform float camera_z_near;
|
||||
|
@ -126,11 +127,15 @@ void main() {
|
|||
|
||||
// Fetch linear depth of current pixel:
|
||||
float depth = texture(source_depth, uv_interp).r * 2.0 - 1.0;
|
||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
||||
depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0;
|
||||
float scale = unit_size; //remember depth is negative by default in OpenGL
|
||||
#else
|
||||
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
|
||||
|
||||
|
||||
|
||||
float scale = unit_size / depth; //remember depth is negative by default in OpenGL
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Calculate the final step to fetch the surrounding pixels:
|
||||
vec2 step = max_radius * scale * dir;
|
||||
|
@ -153,9 +158,14 @@ void main() {
|
|||
#ifdef ENABLE_FOLLOW_SURFACE
|
||||
// If the difference in depth is huge, we lerp color back to "colorM":
|
||||
float depth_cmp = texture(source_depth, offset).r *2.0 - 1.0;
|
||||
depth_cmp = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth_cmp * (camera_z_far - camera_z_near));
|
||||
|
||||
float s = clamp(300.0f * distance *
|
||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
||||
depth_cmp = ((depth_cmp + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0;
|
||||
#else
|
||||
depth_cmp = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth_cmp * (camera_z_far - camera_z_near));
|
||||
#endif
|
||||
|
||||
float s = clamp(300.0f * scale *
|
||||
max_radius * abs(depth - depth_cmp),0.0,1.0);
|
||||
color = mix(color, base_color.rgb, s);
|
||||
#endif
|
||||
|
|
|
@ -211,36 +211,48 @@ Error DirAccessUnix::make_dir(String p_dir) {
|
|||
Error DirAccessUnix::change_dir(String p_dir) {
|
||||
|
||||
GLOBAL_LOCK_FUNCTION
|
||||
|
||||
p_dir = fix_path(p_dir);
|
||||
|
||||
// prev_dir is the directory we are changing out of
|
||||
String prev_dir;
|
||||
char real_current_dir_name[2048];
|
||||
getcwd(real_current_dir_name, 2048);
|
||||
String prev_dir;
|
||||
if (prev_dir.parse_utf8(real_current_dir_name))
|
||||
prev_dir = real_current_dir_name; //no utf8, maybe latin?
|
||||
|
||||
chdir(current_dir.utf8().get_data()); //ascii since this may be unicode or wathever the host os wants
|
||||
bool worked = (chdir(p_dir.utf8().get_data()) == 0); // we can only give this utf8
|
||||
//print_line("directory we are changing out of (prev_dir): " + prev_dir);
|
||||
|
||||
String base = _get_root_path();
|
||||
if (base != "") {
|
||||
|
||||
getcwd(real_current_dir_name, 2048);
|
||||
String new_dir;
|
||||
new_dir.parse_utf8(real_current_dir_name);
|
||||
if (!new_dir.begins_with(base))
|
||||
worked = false;
|
||||
// try_dir is the directory we are trying to change into
|
||||
String try_dir = "";
|
||||
if (p_dir.is_rel_path()) {
|
||||
String next_dir = current_dir + "/" + p_dir;
|
||||
//print_line("p_dir is relative: " + p_dir + " about to simplfy: " + next_dir);
|
||||
next_dir = next_dir.simplify_path();
|
||||
try_dir = next_dir;
|
||||
} else {
|
||||
try_dir = p_dir;
|
||||
//print_line("p_dir is absolute: " + p_dir);
|
||||
}
|
||||
|
||||
if (worked) {
|
||||
|
||||
getcwd(real_current_dir_name, 2048);
|
||||
if (current_dir.parse_utf8(real_current_dir_name))
|
||||
current_dir = real_current_dir_name; //no utf8, maybe latin?
|
||||
// if try_dir is nothing, it is not changing directory so change it to a "." otherwise chdir will fail
|
||||
if (try_dir == "") {
|
||||
try_dir = ".";
|
||||
}
|
||||
|
||||
//print_line("directory we are changing in to (try_dir): " + try_dir);
|
||||
|
||||
bool worked = (chdir(try_dir.utf8().get_data()) == 0); // we can only give this utf8
|
||||
if (!worked) {
|
||||
//print_line("directory does not exist");
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// the directory exists, so set current_dir to try_dir
|
||||
current_dir = try_dir;
|
||||
chdir(prev_dir.utf8().get_data());
|
||||
return worked ? OK : ERR_INVALID_PARAMETER;
|
||||
//print_line("directory exists, setting current_dir to: " + current_dir);
|
||||
return OK;
|
||||
}
|
||||
|
||||
String DirAccessUnix::get_current_dir() {
|
||||
|
|
|
@ -36,12 +36,17 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(UNIX_ENABLED)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef ANDROID_ENABLED
|
||||
#include <sys/statvfs.h>
|
||||
#endif
|
||||
|
||||
#ifdef MSVC
|
||||
#define S_ISREG(m) ((m)&_S_IFREG)
|
||||
#include <io.h>
|
||||
#endif
|
||||
#ifndef S_ISREG
|
||||
#define S_ISREG(m) ((m)&S_IFREG)
|
||||
|
@ -85,13 +90,18 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) {
|
|||
|
||||
//printf("opening %s as %s\n", p_path.utf8().get_data(), path.utf8().get_data());
|
||||
struct stat st;
|
||||
if (stat(path.utf8().get_data(), &st) == 0) {
|
||||
int err = stat(path.utf8().get_data(), &st);
|
||||
if (!err) {
|
||||
switch (st.st_mode & S_IFMT) {
|
||||
case S_IFLNK:
|
||||
case S_IFREG:
|
||||
break;
|
||||
default:
|
||||
return ERR_FILE_CANT_OPEN;
|
||||
}
|
||||
}
|
||||
|
||||
if (!S_ISREG(st.st_mode))
|
||||
return ERR_FILE_CANT_OPEN;
|
||||
};
|
||||
|
||||
if (is_backup_save_enabled() && p_mode_flags & WRITE && !(p_mode_flags & READ)) {
|
||||
if (is_backup_save_enabled() && (p_mode_flags & WRITE) && !(p_mode_flags & READ)) {
|
||||
save_path = path;
|
||||
path = path + ".tmp";
|
||||
//print_line("saving instead to "+path);
|
||||
|
@ -108,15 +118,19 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) {
|
|||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
void FileAccessUnix::close() {
|
||||
|
||||
if (!f)
|
||||
return;
|
||||
|
||||
fclose(f);
|
||||
f = NULL;
|
||||
|
||||
if (close_notification_func) {
|
||||
close_notification_func(path, flags);
|
||||
}
|
||||
|
||||
if (save_path != "") {
|
||||
|
||||
//unlink(save_path.utf8().get_data());
|
||||
|
@ -131,10 +145,12 @@ void FileAccessUnix::close() {
|
|||
ERR_FAIL_COND(rename_error != 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool FileAccessUnix::is_open() const {
|
||||
|
||||
return (f != NULL);
|
||||
}
|
||||
|
||||
void FileAccessUnix::seek(size_t p_position) {
|
||||
|
||||
ERR_FAIL_COND(!f);
|
||||
|
@ -143,29 +159,37 @@ void FileAccessUnix::seek(size_t p_position) {
|
|||
if (fseek(f, p_position, SEEK_SET))
|
||||
check_errors();
|
||||
}
|
||||
|
||||
void FileAccessUnix::seek_end(int64_t p_position) {
|
||||
|
||||
ERR_FAIL_COND(!f);
|
||||
|
||||
if (fseek(f, p_position, SEEK_END))
|
||||
check_errors();
|
||||
}
|
||||
|
||||
size_t FileAccessUnix::get_pos() const {
|
||||
|
||||
size_t aux_position = 0;
|
||||
if (!(aux_position = ftell(f))) {
|
||||
ERR_FAIL_COND_V(!f, 0);
|
||||
|
||||
int pos = ftell(f);
|
||||
if (pos < 0) {
|
||||
check_errors();
|
||||
};
|
||||
return aux_position;
|
||||
ERR_FAIL_V(0);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
size_t FileAccessUnix::get_len() const {
|
||||
|
||||
ERR_FAIL_COND_V(!f, 0);
|
||||
|
||||
FileAccessUnix *fau = const_cast<FileAccessUnix *>(this);
|
||||
int pos = fau->get_pos();
|
||||
fau->seek_end();
|
||||
int size = fau->get_pos();
|
||||
fau->seek(pos);
|
||||
int pos = ftell(f);
|
||||
ERR_FAIL_COND_V(pos < 0, 0);
|
||||
ERR_FAIL_COND_V(fseek(f, 0, SEEK_END), 0);
|
||||
int size = ftell(f);
|
||||
ERR_FAIL_COND_V(size < 0, 0);
|
||||
ERR_FAIL_COND_V(fseek(f, pos, SEEK_SET), 0);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
@ -181,8 +205,8 @@ uint8_t FileAccessUnix::get_8() const {
|
|||
uint8_t b;
|
||||
if (fread(&b, 1, 1, f) == 0) {
|
||||
check_errors();
|
||||
};
|
||||
|
||||
b = '\0';
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
|
@ -202,22 +226,36 @@ Error FileAccessUnix::get_error() const {
|
|||
void FileAccessUnix::store_8(uint8_t p_dest) {
|
||||
|
||||
ERR_FAIL_COND(!f);
|
||||
fwrite(&p_dest, 1, 1, f);
|
||||
ERR_FAIL_COND(fwrite(&p_dest, 1, 1, f) != 1);
|
||||
}
|
||||
|
||||
bool FileAccessUnix::file_exists(const String &p_path) {
|
||||
|
||||
FILE *g;
|
||||
//printf("opening file %s\n", p_fname.c_str());
|
||||
int err;
|
||||
struct stat st;
|
||||
String filename = fix_path(p_path);
|
||||
g = fopen(filename.utf8().get_data(), "rb");
|
||||
if (g == NULL) {
|
||||
|
||||
// Does the name exist at all?
|
||||
err = stat(filename.utf8().get_data(), &st);
|
||||
if (err)
|
||||
return false;
|
||||
} else {
|
||||
|
||||
fclose(g);
|
||||
return true;
|
||||
#ifdef UNIX_ENABLED
|
||||
// See if we have access to the file
|
||||
if (access(filename.utf8().get_data(), F_OK))
|
||||
return false;
|
||||
#else
|
||||
if (_access(filename.utf8().get_data(), 4) == -1)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// See if this is a regular file
|
||||
switch (st.st_mode & S_IFMT) {
|
||||
case S_IFLNK:
|
||||
case S_IFREG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,9 +263,9 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) {
|
|||
|
||||
String file = fix_path(p_file);
|
||||
struct stat flags;
|
||||
bool success = (stat(file.utf8().get_data(), &flags) == 0);
|
||||
int err = stat(file.utf8().get_data(), &flags);
|
||||
|
||||
if (success) {
|
||||
if (!err) {
|
||||
return flags.st_mtime;
|
||||
} else {
|
||||
print_line("ERROR IN: " + p_file);
|
||||
|
@ -249,6 +287,7 @@ FileAccessUnix::FileAccessUnix() {
|
|||
flags = 0;
|
||||
last_error = OK;
|
||||
}
|
||||
|
||||
FileAccessUnix::~FileAccessUnix() {
|
||||
|
||||
close();
|
||||
|
|
60
editor/SCsub
60
editor/SCsub
|
@ -155,31 +155,71 @@ def make_authors_header(target, source, env):
|
|||
g.write("#define _EDITOR_AUTHORS_H\n")
|
||||
|
||||
current_section = ""
|
||||
name_count = -1
|
||||
reading = False
|
||||
|
||||
def close_section():
|
||||
g.write("\t0\n")
|
||||
g.write("};\n")
|
||||
g.write("#define " + current_section.upper() + "_COUNT " + str(name_count) + "\n")
|
||||
|
||||
for line in f:
|
||||
if name_count >= 0:
|
||||
if reading:
|
||||
if line.startswith(" "):
|
||||
g.write("\t\"" + line.strip() + "\",\n")
|
||||
name_count += 1
|
||||
continue
|
||||
if line.startswith("## "):
|
||||
if name_count >= 0:
|
||||
if reading:
|
||||
close_section()
|
||||
name_count = -1
|
||||
reading = False
|
||||
for i in range(len(sections)):
|
||||
if line.strip().endswith(sections[i]):
|
||||
current_section = sections_id[i]
|
||||
name_count = 0
|
||||
reading = True
|
||||
g.write("static const char *" + current_section + "[] = {\n")
|
||||
break
|
||||
|
||||
if name_count >= 0:
|
||||
if reading:
|
||||
close_section()
|
||||
|
||||
g.write("#endif\n")
|
||||
|
||||
def make_donors_header(target, source, env):
|
||||
|
||||
sections = ["Platinum sponsors", "Gold sponsors", "Mini sponsors", "Gold donors", "Silver donors", "Bronze donors"]
|
||||
sections_id = ["donor_s_plat", "donor_s_gold", "donor_s_mini", "donor_gold", "donor_silver", "donor_bronze"]
|
||||
|
||||
src = source[0].srcnode().abspath
|
||||
dst = target[0].srcnode().abspath
|
||||
f = open_utf8(src, "r")
|
||||
g = open_utf8(dst, "w")
|
||||
|
||||
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
|
||||
g.write("#ifndef _EDITOR_DONORS_H\n")
|
||||
g.write("#define _EDITOR_DONORS_H\n")
|
||||
|
||||
current_section = ""
|
||||
reading = False
|
||||
|
||||
def close_section():
|
||||
g.write("\t0\n")
|
||||
g.write("};\n")
|
||||
|
||||
for line in f:
|
||||
if reading >= 0:
|
||||
if line.startswith(" "):
|
||||
g.write("\t\"" + line.strip() + "\",\n")
|
||||
continue
|
||||
if line.startswith("## "):
|
||||
if reading:
|
||||
close_section()
|
||||
reading = False
|
||||
for i in range(len(sections)):
|
||||
if line.strip().endswith(sections[i]):
|
||||
current_section = sections_id[i]
|
||||
reading = True
|
||||
g.write("static const char *" + current_section + "[] = {\n")
|
||||
break
|
||||
|
||||
if reading:
|
||||
close_section()
|
||||
|
||||
g.write("#endif\n")
|
||||
|
@ -393,6 +433,10 @@ if (env["tools"] == "yes"):
|
|||
env.Depends('#editor/authors.gen.h', "../AUTHORS.md")
|
||||
env.Command('#editor/authors.gen.h', "../AUTHORS.md", make_authors_header)
|
||||
|
||||
# Donors
|
||||
env.Depends('#editor/donors.gen.h', "../DONORS.md")
|
||||
env.Command('#editor/donors.gen.h', "../DONORS.md", make_donors_header)
|
||||
|
||||
# License
|
||||
env.Depends('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"])
|
||||
env.Command('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], make_license_header)
|
||||
|
|
|
@ -634,6 +634,9 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> &
|
|||
|
||||
ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT);
|
||||
method.return_type = parser->get_attribute_value("type");
|
||||
if (parser->has_attribute("enum")) {
|
||||
method.return_enum = parser->get_attribute_value("enum");
|
||||
}
|
||||
} else if (name == "argument") {
|
||||
|
||||
DocData::ArgumentDoc argument;
|
||||
|
@ -916,7 +919,11 @@ Error DocData::save(const String &p_path) {
|
|||
|
||||
if (m.return_type != "") {
|
||||
|
||||
_write_string(f, 3, "<return type=\"" + m.return_type + "\">");
|
||||
String enum_text;
|
||||
if (m.return_enum != String()) {
|
||||
enum_text = " enum=\"" + m.return_enum + "\"";
|
||||
}
|
||||
_write_string(f, 3, "<return type=\"" + m.return_type + "\"" + enum_text + ">");
|
||||
_write_string(f, 3, "</return>");
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "editor_about.h"
|
||||
|
||||
#include "authors.gen.h"
|
||||
#include "donors.gen.h"
|
||||
#include "license.gen.h"
|
||||
#include "version.h"
|
||||
#include "version_hash.gen.h"
|
||||
|
@ -51,6 +52,47 @@ TextureRect *EditorAbout::get_logo() const {
|
|||
return _logo;
|
||||
}
|
||||
|
||||
ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<String> &p_sections, const char **p_src[]) {
|
||||
|
||||
ScrollContainer *sc = memnew(ScrollContainer);
|
||||
sc->set_name(p_name);
|
||||
sc->set_v_size_flags(Control::SIZE_EXPAND);
|
||||
|
||||
VBoxContainer *vbc = memnew(VBoxContainer);
|
||||
vbc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
sc->add_child(vbc);
|
||||
|
||||
for (int i = 0; i < p_sections.size(); i++) {
|
||||
|
||||
const char **names_ptr = p_src[i];
|
||||
if (*names_ptr) {
|
||||
|
||||
Label *lbl = memnew(Label);
|
||||
lbl->set_text(p_sections[i]);
|
||||
vbc->add_child(lbl);
|
||||
|
||||
ItemList *il = memnew(ItemList);
|
||||
il->set_max_columns(16);
|
||||
il->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
il->set_same_column_width(true);
|
||||
il->set_auto_height(true);
|
||||
while (*names_ptr) {
|
||||
il->add_item(String::utf8(*names_ptr++), NULL, false);
|
||||
}
|
||||
vbc->add_child(il);
|
||||
if (il->get_item_count() == 2) {
|
||||
il->set_fixed_column_width(200 * EDSCALE);
|
||||
}
|
||||
|
||||
HSeparator *hs = memnew(HSeparator);
|
||||
hs->set_modulate(Color(0, 0, 0, 0));
|
||||
vbc->add_child(hs);
|
||||
}
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
EditorAbout::EditorAbout() {
|
||||
|
||||
set_title(TTR("Thanks from the Godot community!"));
|
||||
|
@ -84,43 +126,29 @@ EditorAbout::EditorAbout() {
|
|||
tc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
vbc->add_child(tc);
|
||||
|
||||
ScrollContainer *dev_base = memnew(ScrollContainer);
|
||||
dev_base->set_name(TTR("Authors"));
|
||||
dev_base->set_v_size_flags(Control::SIZE_EXPAND);
|
||||
tc->add_child(dev_base);
|
||||
|
||||
VBoxContainer *dev_vbc = memnew(VBoxContainer);
|
||||
dev_vbc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
dev_base->add_child(dev_vbc);
|
||||
// Authors
|
||||
|
||||
List<String> dev_sections;
|
||||
dev_sections.push_back(TTR("Project Founders"));
|
||||
dev_sections.push_back(TTR("Lead Developer"));
|
||||
dev_sections.push_back(TTR("Project Manager"));
|
||||
dev_sections.push_back(TTR("Developers"));
|
||||
|
||||
const char **dev_src[] = { dev_founders, dev_lead, dev_manager, dev_names };
|
||||
tc->add_child(_populate_list(TTR("Authors"), dev_sections, dev_src));
|
||||
|
||||
for (int i = 0; i < dev_sections.size(); i++) {
|
||||
// Donors
|
||||
|
||||
Label *lbl = memnew(Label);
|
||||
lbl->set_text(dev_sections[i]);
|
||||
dev_vbc->add_child(lbl);
|
||||
List<String> donor_sections;
|
||||
donor_sections.push_back(TTR("Platinum Sponsors"));
|
||||
donor_sections.push_back(TTR("Gold Sponsors"));
|
||||
donor_sections.push_back(TTR("Mini Sponsors"));
|
||||
donor_sections.push_back(TTR("Gold Donors"));
|
||||
donor_sections.push_back(TTR("Silver Donors"));
|
||||
donor_sections.push_back(TTR("Bronze Donors"));
|
||||
const char **donor_src[] = { donor_s_plat, donor_s_gold, donor_s_mini, donor_gold, donor_silver, donor_bronze };
|
||||
tc->add_child(_populate_list(TTR("Donors"), donor_sections, donor_src));
|
||||
|
||||
ItemList *il = memnew(ItemList);
|
||||
il->set_max_columns(16);
|
||||
il->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
il->set_fixed_column_width(230 * EDSCALE);
|
||||
il->set_auto_height(true);
|
||||
const char **dev_names_ptr = dev_src[i];
|
||||
while (*dev_names_ptr)
|
||||
il->add_item(String::utf8(*dev_names_ptr++), NULL, false);
|
||||
dev_vbc->add_child(il);
|
||||
|
||||
HSeparator *hs = memnew(HSeparator);
|
||||
hs->set_modulate(Color(0, 0, 0, 0));
|
||||
dev_vbc->add_child(hs);
|
||||
}
|
||||
// License
|
||||
|
||||
TextEdit *license = memnew(TextEdit);
|
||||
license->set_name(TTR("License"));
|
||||
|
@ -131,6 +159,8 @@ EditorAbout::EditorAbout() {
|
|||
license->set_text(String::utf8(about_license));
|
||||
tc->add_child(license);
|
||||
|
||||
// Thirdparty License
|
||||
|
||||
VBoxContainer *license_thirdparty = memnew(VBoxContainer);
|
||||
license_thirdparty->set_name(TTR("Thirdparty License"));
|
||||
license_thirdparty->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
|
|
|
@ -52,6 +52,7 @@ class EditorAbout : public AcceptDialog {
|
|||
|
||||
private:
|
||||
void _license_tree_selected();
|
||||
ScrollContainer *_populate_list(const String &p_name, const List<String> &p_sections, const char **p_src[]);
|
||||
|
||||
Tree *_tpl_tree;
|
||||
TextEdit *_tpl_text;
|
||||
|
|
|
@ -31,50 +31,40 @@
|
|||
|
||||
#include "editor/editor_file_system.h"
|
||||
#include "editor/editor_settings.h"
|
||||
#include "editor_scale.h"
|
||||
#include "os/keyboard.h"
|
||||
#include "os/os.h"
|
||||
|
||||
void EditorDirDialog::_update_dir(TreeItem *p_item) {
|
||||
void EditorDirDialog::_update_dir(TreeItem *p_item, EditorFileSystemDirectory *p_dir, const String &p_select_path) {
|
||||
|
||||
updating = true;
|
||||
p_item->clear_children();
|
||||
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||
String cdir = p_item->get_metadata(0);
|
||||
|
||||
da->change_dir(cdir);
|
||||
da->list_dir_begin();
|
||||
String p = da->get_next();
|
||||
String path = p_dir->get_path();
|
||||
|
||||
List<String> dirs;
|
||||
bool ishidden;
|
||||
bool show_hidden = EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files");
|
||||
p_item->set_metadata(0, p_dir->get_path());
|
||||
p_item->set_icon(0, get_icon("Folder", "EditorIcons"));
|
||||
|
||||
while (p != "") {
|
||||
if (!p_item->get_parent()) {
|
||||
p_item->set_text(0, "res://");
|
||||
} else {
|
||||
|
||||
ishidden = da->current_is_hidden();
|
||||
|
||||
if (show_hidden || !ishidden) {
|
||||
if (da->current_is_dir() && !p.begins_with(".")) {
|
||||
dirs.push_back(p);
|
||||
}
|
||||
if (!opened_paths.has(path) && (p_select_path == String() || !p_select_path.begins_with(path))) {
|
||||
p_item->set_collapsed(true);
|
||||
}
|
||||
p = da->get_next();
|
||||
|
||||
p_item->set_text(0, p_dir->get_name());
|
||||
}
|
||||
|
||||
dirs.sort();
|
||||
|
||||
for (List<String>::Element *E = dirs.front(); E; E = E->next()) {
|
||||
TreeItem *ti = tree->create_item(p_item);
|
||||
ti->set_text(0, E->get());
|
||||
ti->set_icon(0, get_icon("Folder", "EditorIcons"));
|
||||
ti->set_collapsed(true);
|
||||
}
|
||||
|
||||
memdelete(da);
|
||||
//this should be handled by EditorFileSystem already
|
||||
//bool show_hidden = EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files");
|
||||
updating = false;
|
||||
for (int i = 0; i < p_dir->get_subdir_count(); i++) {
|
||||
|
||||
TreeItem *ti = tree->create_item(p_item);
|
||||
_update_dir(ti, p_dir->get_subdir(i));
|
||||
}
|
||||
}
|
||||
|
||||
void EditorDirDialog::reload() {
|
||||
void EditorDirDialog::reload(const String &p_with_path) {
|
||||
|
||||
if (!is_visible_in_tree()) {
|
||||
must_reload = true;
|
||||
|
@ -83,10 +73,7 @@ void EditorDirDialog::reload() {
|
|||
|
||||
tree->clear();
|
||||
TreeItem *root = tree->create_item();
|
||||
root->set_metadata(0, "res://");
|
||||
root->set_icon(0, get_icon("Folder", "EditorIcons"));
|
||||
root->set_text(0, "/");
|
||||
_update_dir(root);
|
||||
_update_dir(root, EditorFileSystem::get_singleton()->get_filesystem(), p_with_path);
|
||||
_item_collapsed(root);
|
||||
must_reload = false;
|
||||
}
|
||||
|
@ -94,6 +81,7 @@ void EditorDirDialog::reload() {
|
|||
void EditorDirDialog::_notification(int p_what) {
|
||||
|
||||
if (p_what == NOTIFICATION_ENTER_TREE) {
|
||||
EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "reload");
|
||||
reload();
|
||||
|
||||
if (!tree->is_connected("item_collapsed", this, "_item_collapsed")) {
|
||||
|
@ -105,6 +93,10 @@ void EditorDirDialog::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
if (p_what == NOTIFICATION_EXIT_TREE) {
|
||||
EditorFileSystem::get_singleton()->disconnect("filesystem_changed", this, "reload");
|
||||
}
|
||||
|
||||
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
|
||||
if (must_reload && is_visible_in_tree()) {
|
||||
reload();
|
||||
|
@ -116,57 +108,13 @@ void EditorDirDialog::_item_collapsed(Object *p_item) {
|
|||
|
||||
TreeItem *item = Object::cast_to<TreeItem>(p_item);
|
||||
|
||||
if (updating || item->is_collapsed())
|
||||
if (updating)
|
||||
return;
|
||||
|
||||
TreeItem *ci = item->get_children();
|
||||
while (ci) {
|
||||
|
||||
String p = ci->get_metadata(0);
|
||||
if (p == "") {
|
||||
String pp = item->get_metadata(0);
|
||||
ci->set_metadata(0, pp.plus_file(ci->get_text(0)));
|
||||
_update_dir(ci);
|
||||
}
|
||||
ci = ci->get_next();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorDirDialog::set_current_path(const String &p_path) {
|
||||
|
||||
reload();
|
||||
String p = p_path;
|
||||
if (p.begins_with("res://"))
|
||||
p = p.replace_first("res://", "");
|
||||
|
||||
Vector<String> dirs = p.split("/", false);
|
||||
|
||||
TreeItem *r = tree->get_root();
|
||||
for (int i = 0; i < dirs.size(); i++) {
|
||||
|
||||
String d = dirs[i];
|
||||
TreeItem *p = r->get_children();
|
||||
while (p) {
|
||||
|
||||
if (p->get_text(0) == d)
|
||||
break;
|
||||
p = p->get_next();
|
||||
}
|
||||
|
||||
ERR_FAIL_COND(!p);
|
||||
String pp = p->get_metadata(0);
|
||||
if (pp == "") {
|
||||
p->set_metadata(0, String(r->get_metadata(0)).plus_file(d));
|
||||
_update_dir(p);
|
||||
}
|
||||
updating = true;
|
||||
p->set_collapsed(false);
|
||||
updating = false;
|
||||
_item_collapsed(p);
|
||||
r = p;
|
||||
}
|
||||
|
||||
r->select(0);
|
||||
if (item->is_collapsed())
|
||||
opened_paths.erase(item->get_metadata(0));
|
||||
else
|
||||
opened_paths.insert(item->get_metadata(0));
|
||||
}
|
||||
|
||||
void EditorDirDialog::ok_pressed() {
|
||||
|
@ -201,14 +149,16 @@ void EditorDirDialog::_make_dir_confirm() {
|
|||
|
||||
String dir = ti->get_metadata(0);
|
||||
|
||||
DirAccess *d = DirAccess::open(dir);
|
||||
DirAccessRef d = DirAccess::open(dir);
|
||||
ERR_FAIL_COND(!d);
|
||||
Error err = d->make_dir(makedirname->get_text());
|
||||
|
||||
if (err != OK) {
|
||||
mkdirerr->popup_centered_minsize(Size2(250, 80));
|
||||
mkdirerr->popup_centered_minsize(Size2(250, 80) * EDSCALE);
|
||||
} else {
|
||||
set_current_path(dir.plus_file(makedirname->get_text()));
|
||||
opened_paths.insert(dir);
|
||||
//reload(dir.plus_file(makedirname->get_text()));
|
||||
EditorFileSystem::get_singleton()->scan_changes(); //we created a dir, so rescan changes
|
||||
}
|
||||
makedirname->set_text(""); // reset label
|
||||
}
|
||||
|
@ -218,7 +168,7 @@ void EditorDirDialog::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("_item_collapsed"), &EditorDirDialog::_item_collapsed);
|
||||
ClassDB::bind_method(D_METHOD("_make_dir"), &EditorDirDialog::_make_dir);
|
||||
ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &EditorDirDialog::_make_dir_confirm);
|
||||
ClassDB::bind_method(D_METHOD("reload"), &EditorDirDialog::reload);
|
||||
ClassDB::bind_method(D_METHOD("reload"), &EditorDirDialog::reload, DEFVAL(""));
|
||||
|
||||
ADD_SIGNAL(MethodInfo("dir_selected", PropertyInfo(Variant::STRING, "dir")));
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#ifndef EDITOR_DIR_DIALOG_H
|
||||
#define EDITOR_DIR_DIALOG_H
|
||||
|
||||
#include "editor/editor_file_system.h"
|
||||
#include "os/dir_access.h"
|
||||
#include "scene/gui/dialogs.h"
|
||||
#include "scene/gui/tree.h"
|
||||
|
@ -42,12 +43,13 @@ class EditorDirDialog : public ConfirmationDialog {
|
|||
AcceptDialog *mkdirerr;
|
||||
|
||||
Button *makedir;
|
||||
Set<String> opened_paths;
|
||||
|
||||
Tree *tree;
|
||||
bool updating;
|
||||
|
||||
void _item_collapsed(Object *p_item);
|
||||
void _update_dir(TreeItem *p_item);
|
||||
void _update_dir(TreeItem *p_item, EditorFileSystemDirectory *p_dir, const String &p_select_path = String());
|
||||
|
||||
void _make_dir();
|
||||
void _make_dir_confirm();
|
||||
|
@ -61,8 +63,7 @@ protected:
|
|||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_current_path(const String &p_path);
|
||||
void reload();
|
||||
void reload(const String &p_path = "");
|
||||
EditorDirDialog();
|
||||
};
|
||||
|
||||
|
|
|
@ -72,11 +72,14 @@ static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_valign, int p
|
|||
m_name->add_fallback(FontJapanese); \
|
||||
m_name->add_fallback(FontFallback);
|
||||
|
||||
#define MAKE_DEFAULT_FONT(m_name, m_size) \
|
||||
Ref<DynamicFont> m_name; \
|
||||
m_name.instance(); \
|
||||
m_name->set_size(m_size); \
|
||||
m_name->set_font_data(DefaultFont); \
|
||||
// the custom spacings might only work with Noto Sans
|
||||
#define MAKE_DEFAULT_FONT(m_name, m_size) \
|
||||
Ref<DynamicFont> m_name; \
|
||||
m_name.instance(); \
|
||||
m_name->set_size(m_size); \
|
||||
m_name->set_font_data(DefaultFont); \
|
||||
m_name->set_spacing(DynamicFont::SPACING_TOP, -1); \
|
||||
m_name->set_spacing(DynamicFont::SPACING_BOTTOM, -1); \
|
||||
MAKE_FALLBACKS(m_name);
|
||||
|
||||
void editor_register_fonts(Ref<Theme> p_theme) {
|
||||
|
|
|
@ -1712,9 +1712,8 @@ void EditorHelp::_notification(int p_what) {
|
|||
} break;
|
||||
|
||||
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
|
||||
Ref<StyleBoxFlat> style(memnew(StyleBoxFlat));
|
||||
style->set_bg_color(EditorSettings::get_singleton()->get("text_editor/highlighting/background_color"));
|
||||
background_panel->add_style_override("panel", style);
|
||||
|
||||
class_desc->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1)));
|
||||
} break;
|
||||
|
||||
default: break;
|
||||
|
@ -1786,14 +1785,12 @@ EditorHelp::EditorHelp() {
|
|||
|
||||
{
|
||||
background_panel = memnew(Panel);
|
||||
Ref<StyleBoxFlat> style(memnew(StyleBoxFlat));
|
||||
style->set_bg_color(EditorSettings::get_singleton()->get("text_editor/highlighting/background_color"));
|
||||
background_panel->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
background_panel->add_style_override("panel", style); //get_stylebox("normal","TextEdit"));
|
||||
vbc->add_child(background_panel);
|
||||
class_desc = memnew(RichTextLabel);
|
||||
background_panel->add_child(class_desc);
|
||||
class_desc->set_area_as_parent_rect(8);
|
||||
class_desc->set_area_as_parent_rect();
|
||||
class_desc->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1)));
|
||||
class_desc->connect("meta_clicked", this, "_class_desc_select");
|
||||
class_desc->connect("gui_input", this, "_class_desc_input");
|
||||
}
|
||||
|
@ -1882,8 +1879,13 @@ void EditorHelpBit::_bind_methods() {
|
|||
|
||||
void EditorHelpBit::_notification(int p_what) {
|
||||
|
||||
if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
|
||||
add_style_override("panel", get_stylebox("ScriptPanel", "EditorStyles"));
|
||||
switch (p_what) {
|
||||
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
|
||||
|
||||
rich_text->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1)));
|
||||
} break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1897,8 +1899,8 @@ EditorHelpBit::EditorHelpBit() {
|
|||
|
||||
rich_text = memnew(RichTextLabel);
|
||||
add_child(rich_text);
|
||||
rich_text->set_area_as_parent_rect(8 * EDSCALE);
|
||||
rich_text->set_area_as_parent_rect();
|
||||
rich_text->connect("meta_clicked", this, "_meta_clicked");
|
||||
rich_text->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1)));
|
||||
set_custom_minimum_size(Size2(0, 70 * EDSCALE));
|
||||
add_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles"));
|
||||
}
|
||||
|
|
|
@ -59,7 +59,6 @@ void EditorLog::_notification(int p_what) {
|
|||
|
||||
if (p_what == NOTIFICATION_ENTER_TREE) {
|
||||
|
||||
log->add_color_override("default_color", get_color("font_color", "Tree"));
|
||||
//button->set_icon(get_icon("Console","EditorIcons"));
|
||||
}
|
||||
if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
|
||||
|
@ -91,7 +90,7 @@ void EditorLog::add_message(const String &p_msg, bool p_error) {
|
|||
|
||||
log->add_newline();
|
||||
if (p_error) {
|
||||
log->push_color(get_color("fg_error", "Editor"));
|
||||
log->push_color(get_color("error_color", "Editor"));
|
||||
Ref<Texture> icon = get_icon("Error", "EditorIcons");
|
||||
log->add_image(icon);
|
||||
//button->set_icon(icon);
|
||||
|
|
|
@ -283,13 +283,22 @@ void EditorNode::_notification(int p_what) {
|
|||
scene_tabs->set_tab_close_display_policy((bool(EDITOR_DEF("interface/always_show_close_button_in_scene_tabs", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY));
|
||||
property_editor->set_enable_capitalize_paths(bool(EDITOR_DEF("interface/capitalize_properties", true)));
|
||||
Ref<Theme> theme = create_editor_theme(theme_base->get_theme());
|
||||
|
||||
theme_base->set_theme(theme);
|
||||
|
||||
gui_base->add_style_override("panel", gui_base->get_stylebox("Background", "EditorStyles"));
|
||||
play_button_panel->add_style_override("panel", gui_base->get_stylebox("PlayButtonPanel", "EditorStyles"));
|
||||
scene_root_parent->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles"));
|
||||
bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer"));
|
||||
scene_tabs->add_style_override("tab_fg", gui_base->get_stylebox("SceneTabFG", "EditorStyles"));
|
||||
scene_tabs->add_style_override("tab_bg", gui_base->get_stylebox("SceneTabBG", "EditorStyles"));
|
||||
|
||||
file_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
|
||||
project_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
|
||||
debug_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
|
||||
settings_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
|
||||
help_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
|
||||
|
||||
if (bool(EDITOR_DEF("interface/scene_tabs/resize_if_many_tabs", true))) {
|
||||
scene_tabs->set_min_width(int(EDITOR_DEF("interface/scene_tabs/minimum_width", 50)) * EDSCALE);
|
||||
} else {
|
||||
|
@ -1368,6 +1377,16 @@ void EditorNode::_set_editing_top_editors(Object *p_current_object) {
|
|||
editor_plugins_over->edit(p_current_object);
|
||||
}
|
||||
|
||||
static bool overrides_external_editor(Object *p_object) {
|
||||
|
||||
Script *script = Object::cast_to<Script>(p_object);
|
||||
|
||||
if (!script)
|
||||
return false;
|
||||
|
||||
return script->get_language()->overrides_external_editor();
|
||||
}
|
||||
|
||||
void EditorNode::_edit_current() {
|
||||
|
||||
uint32_t current = editor_history.get_current();
|
||||
|
@ -1434,7 +1453,7 @@ void EditorNode::_edit_current() {
|
|||
if (main_plugin) {
|
||||
|
||||
// special case if use of external editor is true
|
||||
if (main_plugin->get_name() == "Script" && bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) {
|
||||
if (main_plugin->get_name() == "Script" && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) {
|
||||
main_plugin->edit(current_obj);
|
||||
}
|
||||
|
||||
|
@ -1442,6 +1461,7 @@ void EditorNode::_edit_current() {
|
|||
// update screen main_plugin
|
||||
|
||||
if (!changing_scene) {
|
||||
|
||||
if (editor_plugin_screen)
|
||||
editor_plugin_screen->make_visible(false);
|
||||
editor_plugin_screen = main_plugin;
|
||||
|
@ -2721,6 +2741,14 @@ Dictionary EditorNode::_get_main_scene_state() {
|
|||
state["property_edit_offset"] = get_property_editor()->get_scene_tree()->get_vscroll_bar()->get_value();
|
||||
state["saved_version"] = saved_version;
|
||||
state["node_filter"] = scene_tree_dock->get_filter();
|
||||
int current = -1;
|
||||
for (int i = 0; i < editor_table.size(); i++) {
|
||||
if (editor_plugin_screen == editor_table[i]) {
|
||||
current = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
state["editor_index"] = current;
|
||||
return state;
|
||||
}
|
||||
|
||||
|
@ -2731,8 +2759,9 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) {
|
|||
|
||||
changing_scene = false;
|
||||
|
||||
if (get_edited_scene()) {
|
||||
if (p_state.has("editor_index")) {
|
||||
|
||||
int index = p_state["editor_index"];
|
||||
int current = -1;
|
||||
for (int i = 0; i < editor_table.size(); i++) {
|
||||
if (editor_plugin_screen == editor_table[i]) {
|
||||
|
@ -2741,15 +2770,18 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) {
|
|||
}
|
||||
}
|
||||
|
||||
if (current < 2) {
|
||||
//use heuristic instead
|
||||
|
||||
int n2d = 0, n3d = 0;
|
||||
_find_node_types(get_edited_scene(), n2d, n3d);
|
||||
if (n2d > n3d) {
|
||||
_editor_select(EDITOR_2D);
|
||||
} else if (n3d > n2d) {
|
||||
_editor_select(EDITOR_3D);
|
||||
if (current < 2) { //if currently in spatial/2d, only switch to spatial/2d. if curently in script, stay there
|
||||
if (index < 2 || !get_edited_scene()) {
|
||||
_editor_select(index);
|
||||
} else {
|
||||
//use heuristic instead
|
||||
int n2d = 0, n3d = 0;
|
||||
_find_node_types(get_edited_scene(), n2d, n3d);
|
||||
if (n2d > n3d) {
|
||||
_editor_select(EDITOR_2D);
|
||||
} else if (n3d > n2d) {
|
||||
_editor_select(EDITOR_3D);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4818,9 +4850,10 @@ EditorNode::EditorNode() {
|
|||
}
|
||||
|
||||
file_menu = memnew(MenuButton);
|
||||
file_menu->set_flat(false);
|
||||
file_menu->set_text(TTR("Scene"));
|
||||
left_menu_hb->add_child(file_menu);
|
||||
file_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
|
||||
left_menu_hb->add_child(file_menu);
|
||||
|
||||
prev_scene = memnew(ToolButton);
|
||||
prev_scene->set_icon(gui_base->get_icon("PrevScene", "EditorIcons"));
|
||||
|
@ -4908,6 +4941,7 @@ EditorNode::EditorNode() {
|
|||
p->add_item(TTR("Quit"), FILE_QUIT, KEY_MASK_CMD + KEY_Q);
|
||||
|
||||
project_menu = memnew(MenuButton);
|
||||
project_menu->set_flat(false);
|
||||
project_menu->set_tooltip(TTR("Miscellaneous project or scene-wide tools."));
|
||||
project_menu->set_text(TTR("Project"));
|
||||
project_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
|
||||
|
@ -4941,9 +4975,11 @@ EditorNode::EditorNode() {
|
|||
menu_hb->add_child(editor_region);
|
||||
|
||||
debug_menu = memnew(MenuButton);
|
||||
debug_menu->set_flat(false);
|
||||
debug_menu->set_text(TTR("Debug"));
|
||||
debug_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
|
||||
left_menu_hb->add_child(debug_menu);
|
||||
|
||||
p = debug_menu->get_popup();
|
||||
p->set_hide_on_item_selection(false);
|
||||
p->add_check_item(TTR("Deploy with Remote Debug"), RUN_DEPLOY_REMOTE_DEBUG);
|
||||
|
@ -4965,9 +5001,10 @@ EditorNode::EditorNode() {
|
|||
menu_hb->add_spacer();
|
||||
|
||||
settings_menu = memnew(MenuButton);
|
||||
left_menu_hb->add_child(settings_menu);
|
||||
settings_menu->set_flat(false);
|
||||
settings_menu->set_text(TTR("Editor"));
|
||||
settings_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
|
||||
left_menu_hb->add_child(settings_menu);
|
||||
p = settings_menu->get_popup();
|
||||
|
||||
p->add_item(TTR("Editor Settings"), SETTINGS_PREFERENCES);
|
||||
|
@ -4982,10 +5019,12 @@ EditorNode::EditorNode() {
|
|||
p->add_item(TTR("Manage Export Templates"), SETTINGS_MANAGE_EXPORT_TEMPLATES);
|
||||
|
||||
// Help Menu
|
||||
MenuButton *help_menu = memnew(MenuButton);
|
||||
left_menu_hb->add_child(help_menu);
|
||||
help_menu = memnew(MenuButton);
|
||||
help_menu->set_flat(false);
|
||||
help_menu->set_text(TTR("Help"));
|
||||
help_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
|
||||
left_menu_hb->add_child(help_menu);
|
||||
|
||||
p = help_menu->get_popup();
|
||||
p->connect("id_pressed", this, "_menu_option");
|
||||
p->add_icon_item(gui_base->get_icon("ClassList", "EditorIcons"), TTR("Classes"), HELP_CLASSES);
|
||||
|
|
|
@ -236,11 +236,12 @@ private:
|
|||
MenuButton *file_menu;
|
||||
MenuButton *project_menu;
|
||||
MenuButton *debug_menu;
|
||||
MenuButton *settings_menu;
|
||||
MenuButton *help_menu;
|
||||
PopupMenu *tool_menu;
|
||||
ToolButton *export_button;
|
||||
ToolButton *prev_scene;
|
||||
MenuButton *object_menu;
|
||||
MenuButton *settings_menu;
|
||||
ToolButton *play_button;
|
||||
MenuButton *native_play_button;
|
||||
ToolButton *pause_button;
|
||||
|
|
|
@ -603,7 +603,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
|
|||
hints["text_editor/theme/color_theme"] = PropertyInfo(Variant::STRING, "text_editor/theme/color_theme", PROPERTY_HINT_ENUM, "Default");
|
||||
|
||||
set("text_editor/theme/line_spacing", 4);
|
||||
set("text_editor/theme/adapted_code_editor_background_color", true);
|
||||
|
||||
_load_default_text_editor_theme();
|
||||
|
||||
|
|
|
@ -198,6 +198,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
|||
bool highlight_tabs = EDITOR_DEF("interface/theme/highlight_tabs", false);
|
||||
int border_size = EDITOR_DEF("interface/theme/border_size", 1);
|
||||
|
||||
Color script_bg_color = EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0));
|
||||
|
||||
switch (preset) {
|
||||
case 0: { // Default
|
||||
highlight_color = Color::html("#699ce8");
|
||||
|
@ -235,8 +237,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
|||
Color dark_color_2 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 1.5);
|
||||
Color dark_color_3 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 2);
|
||||
|
||||
Color contrast_color_1 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), 0.3);
|
||||
Color contrast_color_2 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), 0.5);
|
||||
Color contrast_color_1 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), MAX(contrast, default_contrast));
|
||||
Color contrast_color_2 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), MAX(contrast * 1.5, default_contrast * 1.5));
|
||||
|
||||
Color font_color = dark_theme ? Color(1, 1, 1) : Color(0, 0, 0);
|
||||
Color font_color_disabled = dark_theme ? Color(0.6, 0.6, 0.6) : Color(0.45, 0.45, 0.45);
|
||||
|
@ -279,8 +281,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
|||
editor_register_fonts(theme);
|
||||
|
||||
// Editor background
|
||||
Ref<StyleBoxFlat> style_panel = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
|
||||
theme->set_stylebox("Background", "EditorStyles", style_panel);
|
||||
theme->set_stylebox("Background", "EditorStyles", make_flat_stylebox(dark_color_2, 4, 4, 4, 4));
|
||||
|
||||
// Focus
|
||||
Ref<StyleBoxFlat> focus_sbt = make_flat_stylebox(contrast_color_1, 4, 4, 4, 4);
|
||||
|
@ -302,12 +303,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
|||
Ref<StyleBoxFlat> style_menu_hover_bg = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
|
||||
|
||||
style_menu_hover_border->set_draw_center(false);
|
||||
style_menu_hover_border->set_border_width(MARGIN_BOTTOM, border_width);
|
||||
style_menu_hover_border->set_border_width(MARGIN_BOTTOM, 2 * EDSCALE);
|
||||
style_menu_hover_border->set_border_color_all(highlight_color);
|
||||
style_menu_hover_border->set_expand_margin_size(MARGIN_BOTTOM, border_width);
|
||||
|
||||
theme->set_stylebox("normal", "MenuButton", style_menu);
|
||||
theme->set_stylebox("hover", "MenuButton", style_menu_hover_border);
|
||||
theme->set_stylebox("hover", "MenuButton", style_menu);
|
||||
theme->set_stylebox("pressed", "MenuButton", style_menu);
|
||||
theme->set_stylebox("focus", "MenuButton", style_menu);
|
||||
theme->set_stylebox("disabled", "MenuButton", style_menu);
|
||||
|
@ -333,10 +333,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
|||
theme->set_stylebox("MenuHover", "EditorStyles", style_menu_hover_border);
|
||||
|
||||
// Content of each tab
|
||||
Ref<StyleBoxFlat> style_content_panel = make_flat_stylebox(base_color, 4, 5, 4, 4);
|
||||
Ref<StyleBoxFlat> style_content_panel = make_flat_stylebox(base_color, 4, 4, 4, 4);
|
||||
style_content_panel->set_border_color_all(base_color);
|
||||
style_content_panel->set_border_width_all(border_width);
|
||||
Ref<StyleBoxFlat> style_content_panel_vp = make_flat_stylebox(base_color, border_width, 5, border_width, border_width);
|
||||
Ref<StyleBoxFlat> style_content_panel_vp = make_flat_stylebox(base_color, border_width, 4, border_width, border_width);
|
||||
style_content_panel_vp->set_border_color_all(base_color);
|
||||
style_content_panel_vp->set_border_width_all(border_width);
|
||||
theme->set_stylebox("panel", "TabContainer", style_content_panel);
|
||||
|
@ -357,6 +357,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
|||
theme->set_stylebox("pressed", "Button", change_border_color(style_button_type, highlight_color));
|
||||
theme->set_stylebox("focus", "Button", change_border_color(style_button_type, highlight_color));
|
||||
theme->set_stylebox("disabled", "Button", style_button_type_disabled);
|
||||
|
||||
theme->set_color("font_color", "Button", button_font_color);
|
||||
theme->set_color("font_color_hover", "Button", HIGHLIGHT_COLOR_FONT);
|
||||
theme->set_color("font_color_pressed", "Button", highlight_color);
|
||||
|
@ -366,13 +367,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
|||
theme->set_color("icon_color_pressed", "Button", Color(highlight_color.r * 1.15, highlight_color.g * 1.15, highlight_color.b * 1.15, highlight_color.a));
|
||||
|
||||
// OptionButton
|
||||
Ref<StyleBoxFlat> style_option_button = make_flat_stylebox(dark_color_1, 4, 4, 4, 4);
|
||||
style_option_button->set_border_width_all(border_width);
|
||||
theme->set_stylebox("normal", "OptionButton", style_button_type);
|
||||
theme->set_stylebox("hover", "OptionButton", change_border_color(style_button_type, contrast_color_1));
|
||||
theme->set_stylebox("pressed", "OptionButton", change_border_color(style_button_type, HIGHLIGHT_COLOR_FONT));
|
||||
theme->set_stylebox("focus", "OptionButton", change_border_color(style_button_type, highlight_color));
|
||||
theme->set_stylebox("disabled", "OptionButton", style_button_type_disabled);
|
||||
theme->set_stylebox("normal", "OptionButton", style_button_type);
|
||||
|
||||
theme->set_color("font_color", "OptionButton", button_font_color);
|
||||
theme->set_color("font_color_hover", "OptionButton", HIGHLIGHT_COLOR_FONT);
|
||||
theme->set_color("font_color_pressed", "OptionButton", highlight_color);
|
||||
|
@ -385,6 +385,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
|||
// CheckButton
|
||||
theme->set_icon("on", "CheckButton", theme->get_icon("GuiToggleOn", "EditorIcons"));
|
||||
theme->set_icon("off", "CheckButton", theme->get_icon("GuiToggleOff", "EditorIcons"));
|
||||
|
||||
theme->set_color("font_color", "CheckButton", button_font_color);
|
||||
theme->set_color("font_color_hover", "CheckButton", HIGHLIGHT_COLOR_FONT);
|
||||
theme->set_color("font_color_pressed", "CheckButton", highlight_color);
|
||||
|
@ -424,12 +425,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
|||
style_tree_bg->set_border_color_all(dark_color_3);
|
||||
theme->set_stylebox("bg", "Tree", style_tree_bg);
|
||||
|
||||
// Script background
|
||||
Ref<StyleBoxFlat> style_script_bg = make_flat_stylebox(dark_color_1, 0, 0, 0, 0);
|
||||
style_script_bg->set_border_width_all(border_width);
|
||||
style_script_bg->set_border_color_all(dark_color_3);
|
||||
theme->set_stylebox("ScriptPanel", "EditorStyles", style_script_bg);
|
||||
|
||||
// Tree
|
||||
theme->set_icon("checked", "Tree", theme->get_icon("GuiChecked", "EditorIcons"));
|
||||
theme->set_icon("unchecked", "Tree", theme->get_icon("GuiUnchecked", "EditorIcons"));
|
||||
|
@ -441,7 +436,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
|||
theme->set_stylebox("custom_button_pressed", "Tree", make_empty_stylebox());
|
||||
theme->set_stylebox("custom_button_hover", "Tree", style_button_type);
|
||||
theme->set_color("custom_button_font_highlight", "Tree", HIGHLIGHT_COLOR_FONT);
|
||||
theme->set_color("font_color", "Tree", font_color_disabled);
|
||||
theme->set_color("font_color", "Tree", font_color);
|
||||
theme->set_color("font_color_selected", "Tree", font_color);
|
||||
|
||||
Ref<StyleBox> style_tree_btn = make_flat_stylebox(contrast_color_1, 2, 4, 2, 4);
|
||||
|
@ -471,8 +466,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
|||
theme->set_color("prop_category", "Editor", prop_category_color);
|
||||
theme->set_color("prop_section", "Editor", prop_section_color);
|
||||
theme->set_color("prop_subsection", "Editor", prop_subsection_color);
|
||||
theme->set_color("fg_selected", "Editor", HIGHLIGHT_COLOR_BG);
|
||||
theme->set_color("fg_error", "Editor", error_color);
|
||||
theme->set_color("drop_position_color", "Tree", highlight_color);
|
||||
|
||||
// ItemList
|
||||
|
@ -531,6 +524,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
|||
|
||||
// LineEdit
|
||||
Ref<StyleBoxFlat> style_line_edit = make_flat_stylebox(dark_color_1, 6, 4, 6, 4);
|
||||
style_line_edit->set_border_width_all(border_width);
|
||||
style_line_edit = change_border_color(style_line_edit, contrast_color_1);
|
||||
Ref<StyleBoxFlat> style_line_edit_disabled = change_border_color(style_line_edit, dark_color_1);
|
||||
style_line_edit_disabled->set_bg_color(Color(0, 0, 0, .1));
|
||||
|
@ -614,11 +608,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
|||
theme->set_icon("grabber_highlight", "VSlider", theme->get_icon("GuiSliderGrabberHl", "EditorIcons"));
|
||||
|
||||
//RichTextLabel
|
||||
theme->set_color("font_color", "RichTextLabel", font_color);
|
||||
Color rtl_combined_bg_color = dark_color_1.linear_interpolate(script_bg_color, script_bg_color.a);
|
||||
Color rtl_font_color = (rtl_combined_bg_color.r + rtl_combined_bg_color.g + rtl_combined_bg_color.b > 0.5 * 3) ? Color(0, 0, 0) : Color(1, 1, 1);
|
||||
theme->set_color("default_color", "RichTextLabel", rtl_font_color);
|
||||
theme->set_stylebox("focus", "RichTextLabel", make_empty_stylebox());
|
||||
theme->set_stylebox("normal", "RichTextLabel", make_flat_stylebox(script_bg_color, 6, 6, 6, 6));
|
||||
|
||||
// Panel
|
||||
theme->set_stylebox("panel", "Panel", style_panel);
|
||||
theme->set_stylebox("panel", "Panel", make_flat_stylebox(dark_color_1, 6, 4, 6, 4));
|
||||
|
||||
// Label
|
||||
theme->set_color("font_color", "Label", font_color);
|
||||
|
|
|
@ -828,7 +828,12 @@ void FileSystemDock::_move_operation(const String &p_to_path) {
|
|||
//make list of remaps
|
||||
Map<String, String> renames;
|
||||
String repfrom = path == "res://" ? path : String(path + "/");
|
||||
String repto = p_to_path == "res://" ? p_to_path : String(p_to_path + "/");
|
||||
String repto = p_to_path;
|
||||
if (!repto.ends_with("/")) {
|
||||
repto += "/";
|
||||
}
|
||||
|
||||
print_line("reprfrom: " + repfrom + " repto " + repto);
|
||||
|
||||
for (int i = 0; i < move_files.size(); i++) {
|
||||
renames[move_files[i]] = move_files[i].replace_first(repfrom, repto);
|
||||
|
@ -868,6 +873,13 @@ void FileSystemDock::_move_operation(const String &p_to_path) {
|
|||
if (err != OK) {
|
||||
EditorNode::get_singleton()->add_io_error(TTR("Error moving file:\n") + move_files[i] + "\n");
|
||||
}
|
||||
if (FileAccess::exists(move_files[i] + ".import")) { //move imported files too
|
||||
//@todo should remove the files in .import folder
|
||||
err = da->rename(move_files[i] + ".import", to + ".import");
|
||||
if (err != OK) {
|
||||
EditorNode::get_singleton()->add_io_error(TTR("Error moving file:\n") + move_files[i] + ".import\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < move_dirs.size(); i++) {
|
||||
|
@ -1827,7 +1839,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
|
|||
|
||||
path = "res://";
|
||||
|
||||
add_constant_override("separation", 3);
|
||||
add_constant_override("separation", 4);
|
||||
}
|
||||
|
||||
FileSystemDock::~FileSystemDock() {
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "io/config_file.h"
|
||||
#include "io/image_loader.h"
|
||||
#include "scene/resources/texture.h"
|
||||
|
||||
#include "editor/editor_node.h"
|
||||
void ResourceImporterTexture::_texture_reimport_srgb(const Ref<StreamTexture> &p_tex) {
|
||||
|
||||
singleton->mutex->lock();
|
||||
|
@ -411,10 +411,14 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
|
|||
if (compress_mode == COMPRESS_VIDEO_RAM) {
|
||||
//must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc).
|
||||
//Android, GLES 2.x
|
||||
|
||||
bool ok_on_pc=false;
|
||||
|
||||
if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc")) {
|
||||
|
||||
_save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
|
||||
r_platform_variants->push_back("s3tc");
|
||||
ok_on_pc=true;
|
||||
}
|
||||
|
||||
if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) {
|
||||
|
@ -434,6 +438,9 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
|
|||
r_platform_variants->push_back("pvrtc");
|
||||
}
|
||||
|
||||
if (!ok_on_pc) {
|
||||
EditorNode::add_io_error("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correcly on PC.");
|
||||
}
|
||||
} else {
|
||||
//import normally
|
||||
_save_stex(image, p_save_path + ".stex", compress_mode, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
|
||||
|
|
|
@ -1019,6 +1019,51 @@ void CanvasItemEditor::_list_select(const Ref<InputEventMouseButton> &b) {
|
|||
}
|
||||
}
|
||||
|
||||
void CanvasItemEditor::_update_cursor() {
|
||||
|
||||
CursorShape c = CURSOR_ARROW;
|
||||
switch (drag) {
|
||||
case DRAG_NONE:
|
||||
if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_MIDDLE) || Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
|
||||
c = CURSOR_DRAG;
|
||||
} else {
|
||||
switch (tool) {
|
||||
case TOOL_MOVE:
|
||||
c = CURSOR_MOVE;
|
||||
break;
|
||||
case TOOL_EDIT_PIVOT:
|
||||
c = CURSOR_CROSS;
|
||||
break;
|
||||
case TOOL_PAN:
|
||||
c = CURSOR_DRAG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DRAG_LEFT:
|
||||
case DRAG_RIGHT:
|
||||
c = CURSOR_HSIZE;
|
||||
break;
|
||||
case DRAG_TOP:
|
||||
case DRAG_BOTTOM:
|
||||
c = CURSOR_VSIZE;
|
||||
break;
|
||||
case DRAG_TOP_LEFT:
|
||||
case DRAG_BOTTOM_RIGHT:
|
||||
c = CURSOR_FDIAGSIZE;
|
||||
break;
|
||||
case DRAG_TOP_RIGHT:
|
||||
case DRAG_BOTTOM_LEFT:
|
||||
c = CURSOR_BDIAGSIZE;
|
||||
break;
|
||||
case DRAG_ALL:
|
||||
case DRAG_NODE_2D:
|
||||
c = CURSOR_MOVE;
|
||||
break;
|
||||
}
|
||||
viewport->set_default_cursor_shape(c);
|
||||
}
|
||||
|
||||
void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
|
||||
|
||||
{
|
||||
|
@ -1457,6 +1502,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
|
|||
Ref<InputEventMouseMotion> m = p_event;
|
||||
if (m.is_valid()) {
|
||||
// Mouse motion event
|
||||
_update_cursor();
|
||||
|
||||
if (!viewport->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field()))
|
||||
viewport->call_deferred("grab_focus");
|
||||
|
@ -2223,6 +2269,9 @@ void CanvasItemEditor::_notification(int p_what) {
|
|||
|
||||
if (p_what == NOTIFICATION_FIXED_PROCESS) {
|
||||
|
||||
|
||||
EditorNode::get_singleton()->get_scene_root()->set_snap_controls_to_pixels(GLOBAL_GET("gui/common/snap_controls_to_pixels"));
|
||||
|
||||
List<Node *> &selection = editor_selection->get_selected_node_list();
|
||||
|
||||
bool all_control = true;
|
||||
|
@ -3562,29 +3611,31 @@ void CanvasItemEditorViewport::_create_preview(const Vector<String> &files) cons
|
|||
Sprite *sprite = memnew(Sprite);
|
||||
sprite->set_texture(texture);
|
||||
sprite->set_modulate(Color(1, 1, 1, 0.7f));
|
||||
preview->add_child(sprite);
|
||||
preview_node->add_child(sprite);
|
||||
label->show();
|
||||
label_desc->show();
|
||||
} else {
|
||||
if (scene.is_valid()) {
|
||||
Node *instance = scene->instance();
|
||||
if (instance) {
|
||||
preview->add_child(instance);
|
||||
preview_node->add_child(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
editor->get_scene_root()->add_child(preview);
|
||||
editor->get_scene_root()->add_child(preview_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasItemEditorViewport::_remove_preview() {
|
||||
if (preview->get_parent()) {
|
||||
editor->get_scene_root()->remove_child(preview);
|
||||
for (int i = preview->get_child_count() - 1; i >= 0; i--) {
|
||||
Node *node = preview->get_child(i);
|
||||
memdelete(node);
|
||||
if (preview_node->get_parent()) {
|
||||
for (int i = preview_node->get_child_count() - 1; i >= 0; i--) {
|
||||
Node *node = preview_node->get_child(i);
|
||||
node->queue_delete();
|
||||
preview_node->remove_child(node);
|
||||
}
|
||||
editor->get_scene_root()->remove_child(preview_node);
|
||||
|
||||
label->hide();
|
||||
label_desc->hide();
|
||||
}
|
||||
|
@ -3794,11 +3845,11 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian
|
|||
break;
|
||||
}
|
||||
if (can_instance) {
|
||||
if (!preview->get_parent()) { // create preview only once
|
||||
if (!preview_node->get_parent()) { // create preview only once
|
||||
_create_preview(files);
|
||||
}
|
||||
Transform2D trans = canvas->get_canvas_transform();
|
||||
preview->set_position((p_point - trans.get_origin()) / trans.get_scale().x);
|
||||
preview_node->set_position((p_point - trans.get_origin()) / trans.get_scale().x);
|
||||
label->set_text(vformat(TTR("Adding %s..."), default_type));
|
||||
}
|
||||
return can_instance;
|
||||
|
@ -3820,11 +3871,16 @@ void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p
|
|||
|
||||
List<Node *> list = editor->get_editor_selection()->get_selected_node_list();
|
||||
if (list.size() == 0) {
|
||||
accept->get_ok()->set_text(TTR("OK :("));
|
||||
accept->set_text(TTR("No parent to instance a child at."));
|
||||
accept->popup_centered_minsize();
|
||||
_remove_preview();
|
||||
return;
|
||||
Node *root_node = editor->get_edited_scene();
|
||||
if (root_node) {
|
||||
list.push_back(root_node);
|
||||
} else {
|
||||
accept->get_ok()->set_text(TTR("OK :("));
|
||||
accept->set_text(TTR("No parent to instance a child at."));
|
||||
accept->popup_centered_minsize();
|
||||
_remove_preview();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (list.size() != 1) {
|
||||
accept->get_ok()->set_text(TTR("I see.."));
|
||||
|
@ -3891,7 +3947,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
|
|||
editor = p_node;
|
||||
editor_data = editor->get_scene_tree_dock()->get_editor_data();
|
||||
canvas = p_canvas;
|
||||
preview = memnew(Node2D);
|
||||
preview_node = memnew(Node2D);
|
||||
accept = memnew(AcceptDialog);
|
||||
editor->get_gui_base()->add_child(accept);
|
||||
|
||||
|
@ -3945,5 +4001,5 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
|
|||
}
|
||||
|
||||
CanvasItemEditorViewport::~CanvasItemEditorViewport() {
|
||||
memdelete(preview);
|
||||
memdelete(preview_node);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include "editor/editor_plugin.h"
|
||||
#include "scene/2d/canvas_item.h"
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/button_group.h"
|
||||
#include "scene/gui/check_box.h"
|
||||
#include "scene/gui/label.h"
|
||||
#include "scene/gui/panel_container.h"
|
||||
|
@ -324,6 +323,7 @@ class CanvasItemEditor : public VBoxContainer {
|
|||
bool updating_scroll;
|
||||
void _update_scroll(float);
|
||||
void _update_scrollbars();
|
||||
void _update_cursor();
|
||||
void incbeg(float &beg, float &end, float inc, float minsize, bool p_symmetric);
|
||||
void incend(float &beg, float &end, float inc, float minsize, bool p_symmetric);
|
||||
|
||||
|
@ -459,7 +459,7 @@ class CanvasItemEditorViewport : public Control {
|
|||
EditorNode *editor;
|
||||
EditorData *editor_data;
|
||||
CanvasItemEditor *canvas;
|
||||
Node2D *preview;
|
||||
Node2D *preview_node;
|
||||
AcceptDialog *accept;
|
||||
WindowDialog *selector;
|
||||
Label *selector_label;
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_plugin.h"
|
||||
#include "scene/2d/collision_polygon_2d.h"
|
||||
#include "scene/gui/button_group.h"
|
||||
#include "scene/gui/tool_button.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include "scene/3d/collision_polygon.h"
|
||||
#include "scene/3d/immediate_geometry.h"
|
||||
#include "scene/3d/mesh_instance.h"
|
||||
#include "scene/gui/button_group.h"
|
||||
#include "scene/gui/tool_button.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -88,7 +88,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
|
|||
if (mesh.is_null())
|
||||
continue;
|
||||
|
||||
int id = p_library->find_item_name(mi->get_name());
|
||||
int id = p_library->find_item_by_name(mi->get_name());
|
||||
if (id < 0) {
|
||||
|
||||
id = p_library->get_last_unused_item_id();
|
||||
|
@ -111,7 +111,8 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
|
|||
sb->get_shape_owners(&shapes);
|
||||
|
||||
for (List<uint32_t>::Element *E = shapes.front(); E; E = E->next()) {
|
||||
if (sb->is_shape_owner_disabled(E->get())) continue;
|
||||
if (sb->is_shape_owner_disabled(E->get()))
|
||||
continue;
|
||||
|
||||
//Transform shape_transform = sb->shape_owner_get_transform(E->get());
|
||||
|
||||
|
@ -120,7 +121,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
|
|||
for (int k = 0; k < sb->shape_owner_get_shape_count(E->get()); k++) {
|
||||
|
||||
Ref<Shape> collision = sb->shape_owner_get_shape(E->get(), k);
|
||||
if (collision.is_valid())
|
||||
if (!collision.is_valid())
|
||||
continue;
|
||||
MeshLibrary::ShapeData shape_data;
|
||||
shape_data.shape = collision;
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_plugin.h"
|
||||
#include "scene/2d/light_occluder_2d.h"
|
||||
#include "scene/gui/button_group.h"
|
||||
#include "scene/gui/tool_button.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include "editor/editor_plugin.h"
|
||||
#include "scene/2d/line_2d.h"
|
||||
#include "scene/2d/path_2d.h"
|
||||
#include "scene/gui/button_group.h"
|
||||
#include "scene/gui/tool_button.h"
|
||||
|
||||
class CanvasItemEditor;
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_plugin.h"
|
||||
#include "scene/2d/navigation_polygon.h"
|
||||
#include "scene/gui/button_group.h"
|
||||
#include "scene/gui/tool_button.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_plugin.h"
|
||||
#include "scene/2d/path_2d.h"
|
||||
#include "scene/gui/button_group.h"
|
||||
#include "scene/gui/tool_button.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_plugin.h"
|
||||
#include "scene/2d/polygon_2d.h"
|
||||
#include "scene/gui/button_group.h"
|
||||
#include "scene/gui/tool_button.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -972,6 +972,14 @@ void ScriptEditor::_menu_option(int p_option) {
|
|||
EditorNode::get_singleton()->show_warning("Can't obtain the script for running");
|
||||
break;
|
||||
}
|
||||
|
||||
current->apply_code();
|
||||
Error err = scr->reload(false); //hard reload script before running always
|
||||
|
||||
if (err != OK) {
|
||||
EditorNode::get_singleton()->show_warning("Script failed reloading, check console for errors.");
|
||||
return;
|
||||
}
|
||||
if (!scr->is_tool()) {
|
||||
|
||||
EditorNode::get_singleton()->show_warning("Script is not in tool mode, will not be able to run");
|
||||
|
@ -1149,8 +1157,6 @@ void ScriptEditor::_notification(int p_what) {
|
|||
|
||||
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
|
||||
|
||||
tab_container->add_style_override("panel", editor->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles"));
|
||||
|
||||
help_search->set_icon(get_icon("HelpSearch", "EditorIcons"));
|
||||
site_search->set_icon(get_icon("Instance", "EditorIcons"));
|
||||
class_search->set_icon(get_icon("ClassList", "EditorIcons"));
|
||||
|
@ -1417,7 +1423,7 @@ void ScriptEditor::_update_script_colors() {
|
|||
int non_zero_hist_size = (hist_size == 0) ? 1 : hist_size;
|
||||
float v = Math::ease((edit_pass - pass) / float(non_zero_hist_size), 0.4);
|
||||
|
||||
script_list->set_item_custom_bg_color(i, hot_color.linear_interpolate(cold_color, v));
|
||||
script_list->set_item_custom_fg_color(i, hot_color.linear_interpolate(cold_color, v));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1539,8 +1545,14 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
|
|||
|
||||
bool open_dominant = EditorSettings::get_singleton()->get("text_editor/files/open_dominant_script_on_scene_change");
|
||||
|
||||
if (p_script->get_language()->overrides_external_editor()) {
|
||||
Error err = p_script->get_language()->open_in_external_editor(p_script, p_line >= 0 ? p_line : 0, p_col);
|
||||
if (err != OK)
|
||||
ERR_PRINT("Couldn't open script in the overridden external text editor");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((debugger->get_dump_stack_script() != p_script || debugger->get_debug_with_external_editor()) &&
|
||||
p_script->get_language()->open_in_external_editor(p_script, p_line >= 0 ? p_line : 0, p_col) == OK &&
|
||||
p_script->get_path().is_resource_file() &&
|
||||
bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) {
|
||||
|
||||
|
@ -2210,7 +2222,6 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
|
|||
members_overview->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
tab_container = memnew(TabContainer);
|
||||
tab_container->add_style_override("panel", p_editor->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles"));
|
||||
tab_container->set_tabs_visible(false);
|
||||
script_split->add_child(tab_container);
|
||||
|
||||
|
@ -2506,9 +2517,9 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
|
|||
EDITOR_DEF("text_editor/open_scripts/script_temperature_enabled", true);
|
||||
EDITOR_DEF("text_editor/open_scripts/highlight_current_script", true);
|
||||
EDITOR_DEF("text_editor/open_scripts/script_temperature_history_size", 15);
|
||||
EDITOR_DEF("text_editor/open_scripts/script_temperature_hot_color", Color(1, 0, 0, 0.3));
|
||||
EDITOR_DEF("text_editor/open_scripts/script_temperature_cold_color", Color(0, 0, 1, 0.3));
|
||||
EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(0.81, 0.81, 0.14, 0.63));
|
||||
EDITOR_DEF("text_editor/open_scripts/script_temperature_hot_color", Color::html("ed5e5e"));
|
||||
EDITOR_DEF("text_editor/open_scripts/script_temperature_cold_color", Color(1, 1, 1, 0.3));
|
||||
EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(1, 1, 1, 0.5));
|
||||
EDITOR_DEF("text_editor/open_scripts/group_help_pages", true);
|
||||
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "text_editor/open_scripts/sort_scripts_by", PROPERTY_HINT_ENUM, "Name,Path"));
|
||||
EDITOR_DEF("text_editor/open_scripts/sort_scripts_by", 0);
|
||||
|
|
|
@ -75,14 +75,9 @@ void ScriptTextEditor::_load_theme_settings() {
|
|||
|
||||
text_edit->clear_colors();
|
||||
|
||||
/* color from color_theme or from editor color */
|
||||
|
||||
Color background_color = EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0));
|
||||
if (EDITOR_DEF("text_editor/theme/adapted_code_editor_background_color", false))
|
||||
background_color = get_color("dark_color_1", "Editor");
|
||||
|
||||
/* keyword color */
|
||||
text_edit->add_color_override("background_color", background_color);
|
||||
|
||||
text_edit->add_color_override("background_color", EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0)));
|
||||
text_edit->add_color_override("completion_background_color", EDITOR_DEF("text_editor/highlighting/completion_background_color", Color(0, 0, 0, 0)));
|
||||
text_edit->add_color_override("completion_selected_color", EDITOR_DEF("text_editor/highlighting/completion_selected_color", Color::html("434244")));
|
||||
text_edit->add_color_override("completion_existing_color", EDITOR_DEF("text_editor/highlighting/completion_existing_color", Color::html("21dfdfdf")));
|
||||
|
|
|
@ -289,6 +289,8 @@ void ShaderEditor::_editor_settings_changed() {
|
|||
shader_editor->get_text_edit()->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed"));
|
||||
shader_editor->get_text_edit()->add_constant_override("line_spacing", EditorSettings::get_singleton()->get("text_editor/theme/line_spacing"));
|
||||
shader_editor->get_text_edit()->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret"));
|
||||
shader_editor->get_text_edit()->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/open_scripts/smooth_scrolling"));
|
||||
shader_editor->get_text_edit()->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/open_scripts/v_scroll_speed"));
|
||||
}
|
||||
|
||||
void ShaderEditor::_bind_methods() {
|
||||
|
|
|
@ -35,12 +35,15 @@
|
|||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_settings.h"
|
||||
#include "editor/plugins/animation_player_editor_plugin.h"
|
||||
#include "editor/plugins/script_editor_plugin.h"
|
||||
#include "editor/script_editor_debugger.h"
|
||||
#include "editor/spatial_editor_gizmos.h"
|
||||
#include "os/keyboard.h"
|
||||
#include "print_string.h"
|
||||
#include "project_settings.h"
|
||||
#include "scene/3d/camera.h"
|
||||
#include "scene/3d/visual_instance.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
#include "sort.h"
|
||||
|
||||
|
@ -77,7 +80,7 @@ void SpatialEditorViewport::_update_camera(float p_interp_delta) {
|
|||
Transform old_transform = camera->get_global_transform();
|
||||
Transform transform;
|
||||
|
||||
bool disable_interp = (Input::get_singleton()->get_mouse_button_mask() & (2 | 4)) || Input::get_singleton()->is_key_pressed(KEY_SHIFT) || Input::get_singleton()->is_key_pressed(KEY_ALT) || Input::get_singleton()->is_key_pressed(KEY_CONTROL);
|
||||
bool disable_interp = orthogonal || (Input::get_singleton()->get_mouse_button_mask() & (2 | 4)) || Input::get_singleton()->is_key_pressed(KEY_SHIFT) || Input::get_singleton()->is_key_pressed(KEY_ALT) || Input::get_singleton()->is_key_pressed(KEY_CONTROL);
|
||||
|
||||
if (p_interp_delta && !disable_interp) {
|
||||
//interpolate
|
||||
|
@ -228,7 +231,7 @@ Vector3 SpatialEditorViewport::_get_camera_normal() const {
|
|||
return -_get_camera_transform().basis.get_axis(2);
|
||||
}
|
||||
|
||||
Vector3 SpatialEditorViewport::_get_ray(const Vector2 &p_pos) {
|
||||
Vector3 SpatialEditorViewport::_get_ray(const Vector2 &p_pos) const {
|
||||
|
||||
return camera->project_ray_normal(p_pos);
|
||||
}
|
||||
|
@ -700,6 +703,11 @@ void SpatialEditorViewport::_smouseenter() {
|
|||
surface->grab_focus();
|
||||
}
|
||||
|
||||
void SpatialEditorViewport::_smouseexit() {
|
||||
|
||||
_remove_preview();
|
||||
}
|
||||
|
||||
void SpatialEditorViewport::_list_select(Ref<InputEventMouseButton> b) {
|
||||
|
||||
_find_items_at_pos(b->get_position(), clicked_includes_current, selection_results, b->get_shift());
|
||||
|
@ -1895,6 +1903,7 @@ void SpatialEditorViewport::_notification(int p_what) {
|
|||
surface->connect("draw", this, "_draw");
|
||||
surface->connect("gui_input", this, "_sinput");
|
||||
surface->connect("mouse_entered", this, "_smouseenter");
|
||||
surface->connect("mouse_exited", this, "_smouseexit");
|
||||
info->add_style_override("panel", get_stylebox("panel", "Panel"));
|
||||
preview_camera->set_icon(get_icon("Camera", "EditorIcons"));
|
||||
_init_gizmo_instance(index);
|
||||
|
@ -2425,6 +2434,7 @@ void SpatialEditorViewport::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("_draw"), &SpatialEditorViewport::_draw);
|
||||
ClassDB::bind_method(D_METHOD("_smouseenter"), &SpatialEditorViewport::_smouseenter);
|
||||
ClassDB::bind_method(D_METHOD("_smouseexit"), &SpatialEditorViewport::_smouseexit);
|
||||
ClassDB::bind_method(D_METHOD("_sinput"), &SpatialEditorViewport::_sinput);
|
||||
ClassDB::bind_method(D_METHOD("_menu_option"), &SpatialEditorViewport::_menu_option);
|
||||
ClassDB::bind_method(D_METHOD("_toggle_camera_preview"), &SpatialEditorViewport::_toggle_camera_preview);
|
||||
|
@ -2432,6 +2442,8 @@ void SpatialEditorViewport::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("update_transform_gizmo_view"), &SpatialEditorViewport::update_transform_gizmo_view);
|
||||
ClassDB::bind_method(D_METHOD("_selection_result_pressed"), &SpatialEditorViewport::_selection_result_pressed);
|
||||
ClassDB::bind_method(D_METHOD("_selection_menu_hide"), &SpatialEditorViewport::_selection_menu_hide);
|
||||
ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SpatialEditorViewport::can_drop_data_fw);
|
||||
ClassDB::bind_method(D_METHOD("drop_data_fw"), &SpatialEditorViewport::drop_data_fw);
|
||||
|
||||
ADD_SIGNAL(MethodInfo("toggle_maximize_view", PropertyInfo(Variant::OBJECT, "viewport")));
|
||||
}
|
||||
|
@ -2481,6 +2493,293 @@ void SpatialEditorViewport::focus_selection() {
|
|||
cursor.pos = center;
|
||||
}
|
||||
|
||||
void SpatialEditorViewport::assign_pending_data_pointers(Spatial *p_preview_node, Rect3 *p_preview_bounds, AcceptDialog *p_accept) {
|
||||
preview_node = p_preview_node;
|
||||
preview_bounds = p_preview_bounds;
|
||||
accept = p_accept;
|
||||
}
|
||||
|
||||
Vector3 SpatialEditorViewport::_get_instance_position(const Point2 &p_pos) const {
|
||||
const float MAX_DISTANCE = 10;
|
||||
|
||||
Vector3 world_ray = _get_ray(p_pos);
|
||||
Vector3 world_pos = _get_ray_pos(p_pos);
|
||||
|
||||
Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_ray(world_pos, world_ray, get_tree()->get_root()->get_world()->get_scenario());
|
||||
Set<Ref<SpatialEditorGizmo> > found_gizmos;
|
||||
|
||||
float closest_dist = MAX_DISTANCE;
|
||||
|
||||
Vector3 point = world_pos + world_ray * MAX_DISTANCE;
|
||||
Vector3 normal = Vector3(0.0, 0.0, 0.0);
|
||||
|
||||
for (int i = 0; i < instances.size(); i++) {
|
||||
|
||||
MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(ObjectDB::get_instance(instances[i]));
|
||||
|
||||
if (!mesh_instance)
|
||||
continue;
|
||||
|
||||
Ref<SpatialEditorGizmo> seg = mesh_instance->get_gizmo();
|
||||
|
||||
if ((!seg.is_valid()) || found_gizmos.has(seg)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
found_gizmos.insert(seg);
|
||||
|
||||
int handle = -1;
|
||||
Vector3 hit_point;
|
||||
Vector3 hit_normal;
|
||||
bool inters = seg->intersect_ray(camera, p_pos, hit_point, hit_normal, NULL, false);
|
||||
|
||||
if (!inters)
|
||||
continue;
|
||||
|
||||
float dist = world_pos.distance_to(hit_point);
|
||||
|
||||
if (dist < 0)
|
||||
continue;
|
||||
|
||||
if (dist < closest_dist) {
|
||||
closest_dist = dist;
|
||||
point = hit_point;
|
||||
normal = hit_normal;
|
||||
}
|
||||
}
|
||||
Vector3 center = preview_bounds->get_size() * 0.5;
|
||||
return point + (center * normal);
|
||||
}
|
||||
|
||||
Rect3 SpatialEditorViewport::_calculate_spatial_bounds(const Spatial *p_parent, const Rect3 p_bounds) {
|
||||
Rect3 bounds = p_bounds;
|
||||
for (int i = 0; i < p_parent->get_child_count(); i++) {
|
||||
Spatial *child = Object::cast_to<Spatial>(p_parent->get_child(i));
|
||||
if (child) {
|
||||
MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(child);
|
||||
if (mesh_instance) {
|
||||
Rect3 mesh_instance_bounds = mesh_instance->get_aabb();
|
||||
mesh_instance_bounds.position += mesh_instance->get_global_transform().origin - p_parent->get_global_transform().origin;
|
||||
bounds.merge_with(mesh_instance_bounds);
|
||||
}
|
||||
bounds = _calculate_spatial_bounds(child, bounds);
|
||||
}
|
||||
}
|
||||
return bounds;
|
||||
}
|
||||
|
||||
void SpatialEditorViewport::_create_preview(const Vector<String> &files) const {
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
String path = files[i];
|
||||
RES res = ResourceLoader::load(path);
|
||||
Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res));
|
||||
if (scene != NULL) {
|
||||
if (scene.is_valid()) {
|
||||
Node *instance = scene->instance();
|
||||
if (instance) {
|
||||
preview_node->add_child(instance);
|
||||
}
|
||||
}
|
||||
editor->get_scene_root()->add_child(preview_node);
|
||||
}
|
||||
}
|
||||
*preview_bounds = _calculate_spatial_bounds(preview_node, Rect3());
|
||||
}
|
||||
|
||||
void SpatialEditorViewport::_remove_preview() {
|
||||
if (preview_node->get_parent()) {
|
||||
for (int i = preview_node->get_child_count() - 1; i >= 0; i--) {
|
||||
Node *node = preview_node->get_child(i);
|
||||
node->queue_delete();
|
||||
preview_node->remove_child(node);
|
||||
}
|
||||
editor->get_scene_root()->remove_child(preview_node);
|
||||
}
|
||||
}
|
||||
|
||||
bool SpatialEditorViewport::_cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node) {
|
||||
if (p_desired_node->get_filename() == p_target_scene_path) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int childCount = p_desired_node->get_child_count();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
Node *child = p_desired_node->get_child(i);
|
||||
if (_cyclical_dependency_exists(p_target_scene_path, child)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SpatialEditorViewport::_create_instance(Node *parent, String &path, const Point2 &p_point) {
|
||||
Ref<PackedScene> sdata = ResourceLoader::load(path);
|
||||
if (!sdata.is_valid()) { // invalid scene
|
||||
return false;
|
||||
}
|
||||
|
||||
Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
|
||||
if (!instanced_scene) { // error on instancing
|
||||
return false;
|
||||
}
|
||||
|
||||
if (editor->get_edited_scene()->get_filename() != "") { // cyclical instancing
|
||||
if (_cyclical_dependency_exists(editor->get_edited_scene()->get_filename(), instanced_scene)) {
|
||||
memdelete(instanced_scene);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
instanced_scene->set_filename(ProjectSettings::get_singleton()->localize_path(path));
|
||||
|
||||
editor_data->get_undo_redo().add_do_method(parent, "add_child", instanced_scene);
|
||||
editor_data->get_undo_redo().add_do_method(instanced_scene, "set_owner", editor->get_edited_scene());
|
||||
editor_data->get_undo_redo().add_do_reference(instanced_scene);
|
||||
editor_data->get_undo_redo().add_undo_method(parent, "remove_child", instanced_scene);
|
||||
|
||||
String new_name = parent->validate_child_name(instanced_scene);
|
||||
ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
|
||||
editor_data->get_undo_redo().add_do_method(sed, "live_debug_instance_node", editor->get_edited_scene()->get_path_to(parent), path, new_name);
|
||||
editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(editor->get_edited_scene()->get_path_to(parent)) + "/" + new_name));
|
||||
|
||||
Transform global_transform;
|
||||
Spatial *parent_spatial = Object::cast_to<Spatial>(parent);
|
||||
if (parent_spatial)
|
||||
global_transform = parent_spatial->get_global_transform();
|
||||
|
||||
global_transform.origin = _get_instance_position(p_point);
|
||||
|
||||
editor_data->get_undo_redo().add_do_method(instanced_scene, "set_global_transform", global_transform);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SpatialEditorViewport::_perform_drop_data() {
|
||||
_remove_preview();
|
||||
|
||||
Vector<String> error_files;
|
||||
|
||||
editor_data->get_undo_redo().create_action(TTR("Create Node"));
|
||||
|
||||
for (int i = 0; i < selected_files.size(); i++) {
|
||||
String path = selected_files[i];
|
||||
RES res = ResourceLoader::load(path);
|
||||
if (res.is_null()) {
|
||||
continue;
|
||||
}
|
||||
Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res));
|
||||
if (scene != NULL) {
|
||||
bool success = _create_instance(target_node, path, drop_pos);
|
||||
if (!success) {
|
||||
error_files.push_back(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editor_data->get_undo_redo().commit_action();
|
||||
|
||||
if (error_files.size() > 0) {
|
||||
String files_str;
|
||||
for (int i = 0; i < error_files.size(); i++) {
|
||||
files_str += error_files[i].get_file().get_basename() + ",";
|
||||
}
|
||||
files_str = files_str.substr(0, files_str.length() - 1);
|
||||
accept->get_ok()->set_text(TTR("Ugh"));
|
||||
accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str()));
|
||||
accept->popup_centered_minsize();
|
||||
}
|
||||
}
|
||||
|
||||
bool SpatialEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
|
||||
|
||||
bool can_instance = false;
|
||||
|
||||
if (!preview_node->is_inside_tree()) {
|
||||
Dictionary d = p_data;
|
||||
if (d.has("type") && (String(d["type"]) == "files")) {
|
||||
Vector<String> files = d["files"];
|
||||
|
||||
List<String> scene_extensions;
|
||||
ResourceLoader::get_recognized_extensions_for_type("PackedScene", &scene_extensions);
|
||||
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
if (scene_extensions.find(files[i].get_extension())) {
|
||||
RES res = ResourceLoader::load(files[i]);
|
||||
if (res.is_null()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String type = res->get_class();
|
||||
if (type == "PackedScene") {
|
||||
Ref<PackedScene> sdata = ResourceLoader::load(files[i]);
|
||||
Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
|
||||
if (!instanced_scene) {
|
||||
continue;
|
||||
}
|
||||
memdelete(instanced_scene);
|
||||
}
|
||||
can_instance = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (can_instance) {
|
||||
_create_preview(files);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
can_instance = true;
|
||||
}
|
||||
|
||||
if (can_instance) {
|
||||
Transform global_transform = Transform(Basis(), _get_instance_position(p_point));
|
||||
preview_node->set_global_transform(global_transform);
|
||||
}
|
||||
|
||||
return can_instance;
|
||||
}
|
||||
|
||||
void SpatialEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
|
||||
if (!can_drop_data_fw(p_point, p_data, p_from))
|
||||
return;
|
||||
|
||||
bool is_shift = Input::get_singleton()->is_key_pressed(KEY_SHIFT);
|
||||
|
||||
selected_files.clear();
|
||||
Dictionary d = p_data;
|
||||
if (d.has("type") && String(d["type"]) == "files") {
|
||||
selected_files = d["files"];
|
||||
}
|
||||
|
||||
List<Node *> list = editor->get_editor_selection()->get_selected_node_list();
|
||||
if (list.size() == 0) {
|
||||
Node *root_node = editor->get_edited_scene();
|
||||
if (root_node) {
|
||||
list.push_back(root_node);
|
||||
} else {
|
||||
accept->get_ok()->set_text(TTR("OK :("));
|
||||
accept->set_text(TTR("No parent to instance a child at."));
|
||||
accept->popup_centered_minsize();
|
||||
_remove_preview();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (list.size() != 1) {
|
||||
accept->get_ok()->set_text(TTR("I see.."));
|
||||
accept->set_text(TTR("This operation requires a single selected node."));
|
||||
accept->popup_centered_minsize();
|
||||
_remove_preview();
|
||||
return;
|
||||
}
|
||||
|
||||
target_node = list[0];
|
||||
if (is_shift && target_node != editor->get_edited_scene()) {
|
||||
target_node = target_node->get_parent();
|
||||
}
|
||||
drop_pos = p_point;
|
||||
|
||||
_perform_drop_data();
|
||||
}
|
||||
|
||||
SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index) {
|
||||
|
||||
_edit.mode = TRANSFORM_NONE;
|
||||
|
@ -2491,6 +2790,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
|
|||
|
||||
index = p_index;
|
||||
editor = p_editor;
|
||||
editor_data = editor->get_scene_tree_dock()->get_editor_data();
|
||||
editor_selection = editor->get_editor_selection();
|
||||
undo_redo = editor->get_undo_redo();
|
||||
clicked = 0;
|
||||
|
@ -2509,6 +2809,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
|
|||
|
||||
c->add_child(viewport);
|
||||
surface = memnew(Control);
|
||||
surface->set_drag_forwarding(this);
|
||||
add_child(surface);
|
||||
surface->set_area_as_parent_rect();
|
||||
surface->set_clip_contents(true);
|
||||
|
@ -2573,9 +2874,10 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
|
|||
preview_camera->hide();
|
||||
preview_camera->connect("toggled", this, "_toggle_camera_preview");
|
||||
previewing = NULL;
|
||||
preview = NULL;
|
||||
gizmo_scale = 1.0;
|
||||
|
||||
preview_node = NULL;
|
||||
|
||||
info = memnew(PanelContainer);
|
||||
info->set_self_modulate(Color(1, 1, 1, 0.4));
|
||||
surface->add_child(info);
|
||||
|
@ -2583,6 +2885,8 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
|
|||
info->add_child(info_label);
|
||||
info->hide();
|
||||
|
||||
accept = NULL;
|
||||
|
||||
freelook_active = false;
|
||||
|
||||
selection_menu = memnew(PopupMenu);
|
||||
|
@ -4000,6 +4304,10 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
|
|||
vs = memnew(VSeparator);
|
||||
hbc_menu->add_child(vs);
|
||||
|
||||
// Drag and drop support;
|
||||
preview_node = memnew(Spatial);
|
||||
preview_bounds = Rect3();
|
||||
|
||||
ED_SHORTCUT("spatial_editor/bottom_view", TTR("Bottom View"), KEY_MASK_ALT + KEY_KP_7);
|
||||
ED_SHORTCUT("spatial_editor/top_view", TTR("Top View"), KEY_KP_7);
|
||||
ED_SHORTCUT("spatial_editor/rear_view", TTR("Rear View"), KEY_MASK_ALT + KEY_KP_1);
|
||||
|
@ -4044,6 +4352,9 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
|
|||
|
||||
p = view_menu->get_popup();
|
||||
|
||||
accept = memnew(AcceptDialog);
|
||||
editor->get_gui_base()->add_child(accept);
|
||||
|
||||
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/1_viewport", TTR("1 Viewport"), KEY_MASK_CMD + KEY_1), MENU_VIEW_USE_1_VIEWPORT);
|
||||
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports", TTR("2 Viewports"), KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS);
|
||||
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports_alt", TTR("2 Viewports (Alt)"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS_ALT);
|
||||
|
@ -4078,6 +4389,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
|
|||
|
||||
viewports[i] = memnew(SpatialEditorViewport(this, editor, i));
|
||||
viewports[i]->connect("toggle_maximize_view", this, "_toggle_maximize_view");
|
||||
viewports[i]->assign_pending_data_pointers(preview_node, &preview_bounds, accept);
|
||||
viewport_base->add_child(viewports[i]);
|
||||
}
|
||||
//vbc->add_child(viewport_base);
|
||||
|
@ -4212,6 +4524,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
|
|||
}
|
||||
|
||||
SpatialEditor::~SpatialEditor() {
|
||||
memdelete(preview_node);
|
||||
}
|
||||
|
||||
void SpatialEditorPlugin::make_visible(bool p_visible) {
|
||||
|
|
|
@ -106,7 +106,16 @@ private:
|
|||
void _menu_option(int p_option);
|
||||
Size2 prev_size;
|
||||
|
||||
Spatial *preview_node;
|
||||
Rect3 *preview_bounds;
|
||||
Vector<String> selected_files;
|
||||
AcceptDialog *accept;
|
||||
|
||||
Node *target_node;
|
||||
Point2 drop_pos;
|
||||
|
||||
EditorNode *editor;
|
||||
EditorData *editor_data;
|
||||
EditorSelection *editor_selection;
|
||||
UndoRedo *undo_redo;
|
||||
|
||||
|
@ -143,7 +152,7 @@ private:
|
|||
ObjectID _select_ray(const Point2 &p_pos, bool p_append, bool &r_includes_current, int *r_gizmo_handle = NULL, bool p_alt_select = false);
|
||||
void _find_items_at_pos(const Point2 &p_pos, bool &r_includes_current, Vector<_RayResult> &results, bool p_alt_select = false);
|
||||
Vector3 _get_ray_pos(const Vector2 &p_pos) const;
|
||||
Vector3 _get_ray(const Vector2 &p_pos);
|
||||
Vector3 _get_ray(const Vector2 &p_pos) const;
|
||||
Point2 _point_to_screen(const Vector3 &p_point);
|
||||
Transform _get_camera_transform() const;
|
||||
int get_selected_count() const;
|
||||
|
@ -250,6 +259,7 @@ private:
|
|||
void _draw();
|
||||
|
||||
void _smouseenter();
|
||||
void _smouseexit();
|
||||
void _sinput(const Ref<InputEvent> &p_event);
|
||||
void _update_freelook(real_t delta);
|
||||
SpatialEditor *spatial_editor;
|
||||
|
@ -266,6 +276,17 @@ private:
|
|||
void _list_select(Ref<InputEventMouseButton> b);
|
||||
Point2i _get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const;
|
||||
|
||||
Vector3 _get_instance_position(const Point2 &p_pos) const;
|
||||
static Rect3 _calculate_spatial_bounds(const Spatial *p_parent, const Rect3 p_bounds);
|
||||
void _create_preview(const Vector<String> &files) const;
|
||||
void _remove_preview();
|
||||
bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node);
|
||||
bool _create_instance(Node *parent, String &path, const Point2 &p_point);
|
||||
void _perform_drop_data();
|
||||
|
||||
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
|
||||
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
@ -281,6 +302,11 @@ public:
|
|||
|
||||
void focus_selection();
|
||||
|
||||
void assign_pending_data_pointers(
|
||||
Spatial *p_preview_node,
|
||||
Rect3 *p_preview_bounds,
|
||||
AcceptDialog *p_accept);
|
||||
|
||||
Viewport *get_viewport_node() { return viewport; }
|
||||
|
||||
SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index);
|
||||
|
@ -396,6 +422,10 @@ private:
|
|||
Ref<SpatialMaterial> indicator_mat;
|
||||
Ref<SpatialMaterial> cursor_material;
|
||||
|
||||
// Scene drag and drop support
|
||||
Spatial *preview_node;
|
||||
Rect3 preview_bounds;
|
||||
|
||||
/*
|
||||
struct Selected {
|
||||
AABB aabb;
|
||||
|
@ -442,6 +472,8 @@ private:
|
|||
MenuButton *transform_menu;
|
||||
MenuButton *view_menu;
|
||||
|
||||
AcceptDialog *accept;
|
||||
|
||||
ConfirmationDialog *snap_dialog;
|
||||
ConfirmationDialog *xform_dialog;
|
||||
ConfirmationDialog *settings_dialog;
|
||||
|
@ -559,6 +591,7 @@ public:
|
|||
Camera *get_camera() { return NULL; }
|
||||
void edit(Spatial *p_spatial);
|
||||
void clear();
|
||||
|
||||
SpatialEditor(EditorNode *p_editor);
|
||||
~SpatialEditor();
|
||||
};
|
||||
|
|
|
@ -244,8 +244,22 @@ void SpriteFramesEditor::_down_pressed() {
|
|||
|
||||
void SpriteFramesEditor::_delete_pressed() {
|
||||
|
||||
ERR_FAIL_COND(!frames->has_animation(edited_anim));
|
||||
|
||||
if (tree->get_current() < 0)
|
||||
return;
|
||||
|
||||
int to_delete = tree->get_current();
|
||||
if (to_delete < 0 || to_delete >= frames->get_frame_count(edited_anim)) {
|
||||
return;
|
||||
}
|
||||
|
||||
undo_redo->create_action(TTR("Delete Resource"));
|
||||
undo_redo->add_do_method(frames, "remove_frame", edited_anim, to_delete);
|
||||
undo_redo->add_undo_method(frames, "add_frame", edited_anim, frames->get_frame(edited_anim, to_delete), to_delete);
|
||||
undo_redo->add_do_method(this, "_update_library");
|
||||
undo_redo->add_undo_method(this, "_update_library");
|
||||
undo_redo->commit_action();
|
||||
}
|
||||
|
||||
void SpriteFramesEditor::_animation_select() {
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#ifndef THEME_EDITOR_PLUGIN_H
|
||||
#define THEME_EDITOR_PLUGIN_H
|
||||
|
||||
#include "scene/gui/button_group.h"
|
||||
#include "scene/gui/check_box.h"
|
||||
#include "scene/gui/file_dialog.h"
|
||||
#include "scene/gui/option_button.h"
|
||||
|
|
|
@ -182,8 +182,8 @@ void ProjectSettingsEditor::_device_input_add() {
|
|||
Ref<InputEvent> ie;
|
||||
String name = add_at;
|
||||
int idx = edit_idx;
|
||||
Variant old_val = ProjectSettings::get_singleton()->get(name);
|
||||
Array arr = old_val;
|
||||
Array old_val = ProjectSettings::get_singleton()->get(name);
|
||||
Array arr = old_val.duplicate();
|
||||
|
||||
switch (add_type) {
|
||||
|
||||
|
@ -285,8 +285,8 @@ void ProjectSettingsEditor::_press_a_key_confirm() {
|
|||
String name = add_at;
|
||||
int idx = edit_idx;
|
||||
|
||||
Variant old_val = ProjectSettings::get_singleton()->get(name);
|
||||
Array arr = old_val;
|
||||
Array old_val = ProjectSettings::get_singleton()->get(name);
|
||||
Array arr = old_val.duplicate();
|
||||
|
||||
for (int i = 0; i < arr.size(); i++) {
|
||||
|
||||
|
@ -700,6 +700,8 @@ void ProjectSettingsEditor::_update_actions() {
|
|||
action->set_meta("__input", ie);
|
||||
}
|
||||
}
|
||||
|
||||
_action_check(action_name->get_text());
|
||||
}
|
||||
|
||||
void ProjectSettingsEditor::popup_project_settings() {
|
||||
|
@ -809,28 +811,41 @@ void ProjectSettingsEditor::_item_del() {
|
|||
undo_redo->commit_action();
|
||||
}
|
||||
|
||||
void ProjectSettingsEditor::_action_check(String p_action) {
|
||||
|
||||
if (p_action == "") {
|
||||
|
||||
action_add->set_disabled(true);
|
||||
} else {
|
||||
|
||||
if (p_action.find("/") != -1 || p_action.find(":") != -1) {
|
||||
action_add->set_text(TTR("Can't contain '/' or ':'"));
|
||||
action_add->set_disabled(true);
|
||||
return;
|
||||
}
|
||||
if (ProjectSettings::get_singleton()->has("input/" + p_action)) {
|
||||
action_add->set_text(TTR("Already existing"));
|
||||
action_add->set_disabled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
action_add->set_disabled(false);
|
||||
}
|
||||
|
||||
action_add->set_text(TTR("Add"));
|
||||
}
|
||||
|
||||
void ProjectSettingsEditor::_action_adds(String) {
|
||||
|
||||
_action_add();
|
||||
if (!action_add->is_disabled()) {
|
||||
_action_add();
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectSettingsEditor::_action_add() {
|
||||
|
||||
String action = action_name->get_text();
|
||||
if (action.find("/") != -1 || action.find(":") != -1 || action == "") {
|
||||
message->set_text(TTR("Invalid action (anything goes but '/' or ':')."));
|
||||
message->popup_centered(Size2(300, 100) * EDSCALE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ProjectSettings::get_singleton()->has("input/" + action)) {
|
||||
message->set_text(vformat(TTR("Action '%s' already exists!"), action));
|
||||
message->popup_centered(Size2(300, 100) * EDSCALE);
|
||||
return;
|
||||
}
|
||||
|
||||
Array va;
|
||||
String name = "input/" + action;
|
||||
String name = "input/" + action_name->get_text();
|
||||
undo_redo->create_action(TTR("Add Input Action Event"));
|
||||
undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, va);
|
||||
undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", name);
|
||||
|
@ -854,6 +869,7 @@ void ProjectSettingsEditor::_action_add() {
|
|||
return;
|
||||
r->select(0);
|
||||
input_editor->ensure_cursor_is_visible();
|
||||
action_add->set_text(TTR("Add"));
|
||||
}
|
||||
|
||||
void ProjectSettingsEditor::_item_checked(const String &p_item, bool p_check) {
|
||||
|
@ -1321,6 +1337,11 @@ void ProjectSettingsEditor::set_plugins_page() {
|
|||
tab_container->set_current_tab(plugin_settings->get_index());
|
||||
}
|
||||
|
||||
TabContainer *ProjectSettingsEditor::get_tabs() {
|
||||
|
||||
return tab_container;
|
||||
}
|
||||
|
||||
void ProjectSettingsEditor::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_item_selected"), &ProjectSettingsEditor::_item_selected);
|
||||
|
@ -1331,6 +1352,7 @@ void ProjectSettingsEditor::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("_save"), &ProjectSettingsEditor::_save);
|
||||
ClassDB::bind_method(D_METHOD("_action_add"), &ProjectSettingsEditor::_action_add);
|
||||
ClassDB::bind_method(D_METHOD("_action_adds"), &ProjectSettingsEditor::_action_adds);
|
||||
ClassDB::bind_method(D_METHOD("_action_check"), &ProjectSettingsEditor::_action_check);
|
||||
ClassDB::bind_method(D_METHOD("_action_selected"), &ProjectSettingsEditor::_action_selected);
|
||||
ClassDB::bind_method(D_METHOD("_action_edited"), &ProjectSettingsEditor::_action_edited);
|
||||
ClassDB::bind_method(D_METHOD("_action_activated"), &ProjectSettingsEditor::_action_activated);
|
||||
|
@ -1361,6 +1383,8 @@ void ProjectSettingsEditor::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("_toggle_search_bar"), &ProjectSettingsEditor::_toggle_search_bar);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_copy_to_platform_about_to_show"), &ProjectSettingsEditor::_copy_to_platform_about_to_show);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_tabs"), &ProjectSettingsEditor::get_tabs);
|
||||
}
|
||||
|
||||
ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
|
||||
|
@ -1475,9 +1499,8 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
|
|||
get_ok()->set_text(TTR("Close"));
|
||||
set_hide_on_ok(true);
|
||||
|
||||
message = memnew(ConfirmationDialog);
|
||||
message = memnew(AcceptDialog);
|
||||
add_child(message);
|
||||
message->set_hide_on_ok(true);
|
||||
|
||||
Control *input_base = memnew(Control);
|
||||
input_base->set_name(TTR("Input Map"));
|
||||
|
@ -1493,7 +1516,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
|
|||
|
||||
l = memnew(Label);
|
||||
vbc->add_child(l);
|
||||
l->set_position(Point2(6, 5) * EDSCALE);
|
||||
l->set_text(TTR("Action:"));
|
||||
|
||||
hbc = memnew(HBoxContainer);
|
||||
|
@ -1503,12 +1525,15 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
|
|||
action_name->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
hbc->add_child(action_name);
|
||||
action_name->connect("text_entered", this, "_action_adds");
|
||||
action_name->connect("text_changed", this, "_action_check");
|
||||
|
||||
add = memnew(Button);
|
||||
hbc->add_child(add);
|
||||
add->set_custom_minimum_size(Size2(150, 0) * EDSCALE);
|
||||
add->set_text(TTR("Add"));
|
||||
add->set_disabled(true);
|
||||
add->connect("pressed", this, "_action_add");
|
||||
action_add = add;
|
||||
|
||||
input_editor = memnew(Tree);
|
||||
vbc->add_child(input_editor);
|
||||
|
|
|
@ -66,7 +66,7 @@ class ProjectSettingsEditor : public AcceptDialog {
|
|||
ToolButton *clear_button;
|
||||
|
||||
HBoxContainer *add_prop_bar;
|
||||
ConfirmationDialog *message;
|
||||
AcceptDialog *message;
|
||||
LineEdit *category;
|
||||
LineEdit *property;
|
||||
OptionButton *type;
|
||||
|
@ -80,6 +80,7 @@ class ProjectSettingsEditor : public AcceptDialog {
|
|||
MenuButton *popup_copy_to_feature;
|
||||
|
||||
LineEdit *action_name;
|
||||
Button *action_add;
|
||||
Tree *input_editor;
|
||||
bool setting;
|
||||
bool updating_translations;
|
||||
|
@ -108,6 +109,7 @@ class ProjectSettingsEditor : public AcceptDialog {
|
|||
void _add_item(int p_item, Ref<InputEvent> p_exiting_event = NULL);
|
||||
void _edit_item(Ref<InputEvent> p_exiting_event);
|
||||
|
||||
void _action_check(String p_action);
|
||||
void _action_adds(String);
|
||||
void _action_add();
|
||||
void _device_input_add();
|
||||
|
@ -159,6 +161,8 @@ public:
|
|||
void popup_project_settings();
|
||||
void set_plugins_page();
|
||||
|
||||
TabContainer *get_tabs();
|
||||
|
||||
void queue_save();
|
||||
|
||||
ProjectSettingsEditor(EditorData *p_data);
|
||||
|
|
|
@ -171,24 +171,7 @@ void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<Str
|
|||
Pair<String, Ref<Texture> > pair;
|
||||
pair.first = file;
|
||||
pair.second = get_icon((has_icon(efsd->get_file_type(i), ei) ? efsd->get_file_type(i) : ot), ei);
|
||||
|
||||
if (search_text != String() && list.size() > 0) {
|
||||
|
||||
float this_sim = _path_cmp(search_text, file);
|
||||
float other_sim = _path_cmp(list[0].first, file);
|
||||
int pos = 1;
|
||||
|
||||
while (pos < list.size() && this_sim <= other_sim) {
|
||||
other_sim = _path_cmp(list[pos++].first, file);
|
||||
}
|
||||
|
||||
pos = this_sim >= other_sim ? pos - 1 : pos;
|
||||
list.insert(pos, pair);
|
||||
|
||||
} else {
|
||||
|
||||
list.push_back(pair);
|
||||
}
|
||||
list.push_back(pair);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,6 +183,40 @@ void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<Str
|
|||
}
|
||||
}
|
||||
|
||||
Vector<Pair<String, Ref<Texture> > > EditorQuickOpen::_sort_fs(Vector<Pair<String, Ref<Texture> > > &list) {
|
||||
|
||||
String search_text = search_box->get_text();
|
||||
Vector<Pair<String, Ref<Texture> > > sorted_list;
|
||||
|
||||
if (search_text == String() || list.size() == 0)
|
||||
return sorted_list;
|
||||
|
||||
Vector<float> scores;
|
||||
scores.resize(list.size());
|
||||
for (int i = 0; i < list.size(); i++)
|
||||
scores[i] = _path_cmp(search_text, list[i].first);
|
||||
|
||||
while (list.size() > 0) {
|
||||
|
||||
float best_score = 0.0f;
|
||||
int best_idx = 0;
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
float current_score = scores[i];
|
||||
if (current_score > best_score) {
|
||||
best_score = current_score;
|
||||
best_idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
sorted_list.push_back(list[best_idx]);
|
||||
list.remove(best_idx);
|
||||
scores.remove(best_idx);
|
||||
}
|
||||
|
||||
return sorted_list;
|
||||
}
|
||||
|
||||
void EditorQuickOpen::_update_search() {
|
||||
|
||||
search_options->clear();
|
||||
|
@ -208,6 +225,7 @@ void EditorQuickOpen::_update_search() {
|
|||
Vector<Pair<String, Ref<Texture> > > list;
|
||||
|
||||
_parse_fs(efsd, list);
|
||||
list = _sort_fs(list);
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
TreeItem *ti = search_options->create_item(root);
|
||||
|
|
|
@ -49,6 +49,7 @@ class EditorQuickOpen : public ConfirmationDialog {
|
|||
|
||||
void _sbox_input(const Ref<InputEvent> &p_ie);
|
||||
void _parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<String, Ref<Texture> > > &list);
|
||||
Vector<Pair<String, Ref<Texture> > > _sort_fs(Vector<Pair<String, Ref<Texture> > > &list);
|
||||
float _path_cmp(String search, String path) const;
|
||||
|
||||
void _confirmed();
|
||||
|
|
|
@ -165,7 +165,7 @@ void EditorSettingsDialog::_update_shortcuts() {
|
|||
section->set_custom_bg_color(1, get_color("prop_subsection", "Editor"));
|
||||
}
|
||||
|
||||
if (shortcut_filter.is_subsequence_ofi(sc->get_name())) {
|
||||
if (shortcut_filter.is_subsequence_ofi(sc->get_name()) || shortcut_filter.is_subsequence_ofi(sc->get_as_text())) {
|
||||
TreeItem *item = shortcuts->create_item(section);
|
||||
|
||||
item->set_text(0, sc->get_name());
|
||||
|
|
|
@ -1325,6 +1325,7 @@ bool Main::start() {
|
|||
int shadow_atlas_q2_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_2_subdiv");
|
||||
int shadow_atlas_q3_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_3_subdiv");
|
||||
|
||||
|
||||
sml->get_root()->set_shadow_atlas_size(shadow_atlas_size);
|
||||
sml->get_root()->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q0_subdiv));
|
||||
sml->get_root()->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q1_subdiv));
|
||||
|
@ -1333,6 +1334,9 @@ bool Main::start() {
|
|||
Viewport::Usage usage = Viewport::Usage(int(GLOBAL_GET("rendering/quality/intended_usage/framebuffer_allocation")));
|
||||
sml->get_root()->set_usage(usage);
|
||||
|
||||
bool snap_controls = GLOBAL_DEF("gui/common/snap_controls_to_pixels", true);
|
||||
sml->get_root()->set_snap_controls_to_pixels(snap_controls);
|
||||
|
||||
} else {
|
||||
GLOBAL_DEF("display/window/stretch/mode", "disabled");
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode", PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,2d,viewport"));
|
||||
|
@ -1342,6 +1346,8 @@ bool Main::start() {
|
|||
ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/shrink", PropertyInfo(Variant::STRING, "display/window/stretch/shrink", PROPERTY_HINT_RANGE, "1,8,1"));
|
||||
sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true));
|
||||
sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true));
|
||||
GLOBAL_DEF("gui/common/snap_controls_to_pixels", true);
|
||||
|
||||
}
|
||||
|
||||
String local_game_path;
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
|
||||
static Image::Format _get_etc2_mode(Image::DetectChannels format) {
|
||||
switch (format) {
|
||||
case Image::DETECTED_L:
|
||||
case Image::DETECTED_R:
|
||||
return Image::FORMAT_ETC2_R11;
|
||||
|
||||
|
@ -47,7 +46,7 @@ static Image::Format _get_etc2_mode(Image::DetectChannels format) {
|
|||
case Image::DETECTED_RGB:
|
||||
return Image::FORMAT_ETC2_RGB8;
|
||||
|
||||
case Image::DETECTED_RGBA:
|
||||
default:
|
||||
return Image::FORMAT_ETC2_RGBA8;
|
||||
|
||||
// TODO: would be nice if we could use FORMAT_ETC2_RGB8A1 for FORMAT_RGBA5551
|
||||
|
|
|
@ -2,12 +2,16 @@
|
|||
|
||||
Import('env')
|
||||
|
||||
env.add_source_files(env.modules_sources, "*.cpp")
|
||||
env.add_source_files(env.modules_sources, "godot/*.cpp")
|
||||
gdn_env = env.Clone()
|
||||
|
||||
env.Append(CPPFLAGS=['-DGDAPI_BUILT_IN'])
|
||||
env.Append(CPPPATH=['#modules/gdnative/'])
|
||||
gdn_env.add_source_files(env.modules_sources, "*.cpp")
|
||||
gdn_env.add_source_files(env.modules_sources, "gdnative/*.cpp")
|
||||
gdn_env.add_source_files(env.modules_sources, "nativescript/*.cpp")
|
||||
|
||||
gdn_env.Append(CPPFLAGS=['-DGDAPI_BUILT_IN'])
|
||||
gdn_env.Append(CPPPATH=['#modules/gdnative/include/'])
|
||||
|
||||
if "platform" in env and env["platform"] == "x11": # there has to be a better solution?
|
||||
env.Append(LINKFLAGS=["-rdynamic"])
|
||||
|
||||
env.use_ptrcall = True
|
||||
|
|
|
@ -100,6 +100,11 @@ GDNativeLibrary::~GDNativeLibrary() {
|
|||
void GDNativeLibrary::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_library_path", "platform", "path"), &GDNativeLibrary::set_library_path);
|
||||
ClassDB::bind_method(D_METHOD("get_library_path", "platform"), &GDNativeLibrary::get_library_path);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_singleton_gdnative"), &GDNativeLibrary::is_singleton_gdnative);
|
||||
ClassDB::bind_method(D_METHOD("set_singleton_gdnative", "singleton"), &GDNativeLibrary::set_singleton_gdnative);
|
||||
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "singleton_gdnative"), "set_singleton_gdnative", "is_singleton_gdnative");
|
||||
}
|
||||
|
||||
bool GDNativeLibrary::_set(const StringName &p_name, const Variant &p_value) {
|
||||
|
@ -175,7 +180,6 @@ GDNative::GDNative() {
|
|||
}
|
||||
|
||||
GDNative::~GDNative() {
|
||||
// TODO(karroffel): implement ALL the things!
|
||||
}
|
||||
|
||||
extern "C" void _api_anchor();
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "os/thread_safe.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include <godot/gdnative.h>
|
||||
#include "gdnative/gdnative.h"
|
||||
|
||||
class GDNativeLibrary : public Resource {
|
||||
GDCLASS(GDNativeLibrary, Resource)
|
||||
|
@ -77,6 +77,8 @@ class GDNativeLibrary : public Resource {
|
|||
|
||||
String library_paths[NUM_PLATFORMS];
|
||||
|
||||
bool singleton_gdnative = false;
|
||||
|
||||
protected:
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
|
@ -92,6 +94,9 @@ public:
|
|||
String get_library_path(StringName p_platform) const;
|
||||
|
||||
String get_active_library_path() const;
|
||||
|
||||
_FORCE_INLINE_ bool is_singleton_gdnative() const { return singleton_gdnative; }
|
||||
_FORCE_INLINE_ void set_singleton_gdnative(bool p_singleton) { singleton_gdnative = p_singleton; }
|
||||
};
|
||||
|
||||
typedef godot_variant (*native_call_cb)(void *, godot_string *, godot_array *);
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/array.h>
|
||||
#include "gdnative/array.h"
|
||||
|
||||
#include "core/array.h"
|
||||
#include "core/os/memory.h"
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/basis.h>
|
||||
#include "gdnative/basis.h"
|
||||
|
||||
#include "core/math/matrix3.h"
|
||||
#include "core/variant.h"
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/color.h>
|
||||
#include "gdnative/color.h"
|
||||
|
||||
#include "core/color.h"
|
||||
#include "core/variant.h"
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/dictionary.h>
|
||||
#include "gdnative/dictionary.h"
|
||||
|
||||
#include "core/variant.h"
|
||||
// core/variant.h before to avoid compile errors with MSVC
|
|
@ -27,11 +27,10 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/gdnative.h>
|
||||
#include "gdnative/gdnative.h"
|
||||
|
||||
#include "class_db.h"
|
||||
#include "error_macros.h"
|
||||
#include "gdnative.h"
|
||||
#include "global_constants.h"
|
||||
#include "os/os.h"
|
||||
#include "project_settings.h"
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/node_path.h>
|
||||
#include "gdnative/node_path.h"
|
||||
|
||||
#include "core/node_path.h"
|
||||
#include "core/variant.h"
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/plane.h>
|
||||
#include "gdnative/plane.h"
|
||||
|
||||
#include "core/math/plane.h"
|
||||
#include "core/variant.h"
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/pool_arrays.h>
|
||||
#include "gdnative/pool_arrays.h"
|
||||
|
||||
#include "array.h"
|
||||
#include "core/variant.h"
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/quat.h>
|
||||
#include "gdnative/quat.h"
|
||||
|
||||
#include "core/math/quat.h"
|
||||
#include "core/variant.h"
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/rect2.h>
|
||||
#include "gdnative/rect2.h"
|
||||
|
||||
#include "core/math/math_2d.h"
|
||||
#include "core/variant.h"
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/rect3.h>
|
||||
#include "gdnative/rect3.h"
|
||||
|
||||
#include "core/math/rect3.h"
|
||||
#include "core/variant.h"
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/rid.h>
|
||||
#include "gdnative/rid.h"
|
||||
|
||||
#include "core/resource.h"
|
||||
#include "core/rid.h"
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/string.h>
|
||||
#include "gdnative/string.h"
|
||||
|
||||
#include "core/variant.h"
|
||||
#include "string_db.h"
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/transform.h>
|
||||
#include "gdnative/transform.h"
|
||||
|
||||
#include "core/math/transform.h"
|
||||
#include "core/variant.h"
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/transform2d.h>
|
||||
#include "gdnative/transform2d.h"
|
||||
|
||||
#include "core/math/math_2d.h"
|
||||
#include "core/variant.h"
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/variant.h>
|
||||
#include "gdnative/variant.h"
|
||||
|
||||
#include "core/variant.h"
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/vector2.h>
|
||||
#include "gdnative/vector2.h"
|
||||
|
||||
#include "core/math/math_2d.h"
|
||||
#include "core/variant.h"
|
|
@ -27,7 +27,7 @@
|
|||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include <godot/vector3.h>
|
||||
#include "gdnative/vector3.h"
|
||||
|
||||
#include "core/variant.h"
|
||||
#include "core/vector.h"
|
|
@ -1,23 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon.png-aa47d037a37fb38b3b7e7828e4eec407.stex"
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
|
@ -46,10 +46,10 @@ typedef struct {
|
|||
} godot_array;
|
||||
#endif
|
||||
|
||||
#include <godot/pool_arrays.h>
|
||||
#include <godot/variant.h>
|
||||
#include <gdnative/pool_arrays.h>
|
||||
#include <gdnative/variant.h>
|
||||
|
||||
#include <godot/gdnative.h>
|
||||
#include <gdnative/gdnative.h>
|
||||
|
||||
void GDAPI godot_array_new(godot_array *r_dest);
|
||||
void GDAPI godot_array_new_copy(godot_array *r_dest, const godot_array *p_src);
|
|
@ -45,9 +45,9 @@ typedef struct {
|
|||
} godot_basis;
|
||||
#endif
|
||||
|
||||
#include <godot/gdnative.h>
|
||||
#include <godot/quat.h>
|
||||
#include <godot/vector3.h>
|
||||
#include <gdnative/gdnative.h>
|
||||
#include <gdnative/quat.h>
|
||||
#include <gdnative/vector3.h>
|
||||
|
||||
void GDAPI godot_basis_new_with_rows(godot_basis *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis);
|
||||
void GDAPI godot_basis_new_with_axis_and_angle(godot_basis *r_dest, const godot_vector3 *p_axis, const godot_real p_phi);
|
|
@ -45,8 +45,8 @@ typedef struct {
|
|||
} godot_color;
|
||||
#endif
|
||||
|
||||
#include <godot/gdnative.h>
|
||||
#include <godot/string.h>
|
||||
#include <gdnative/gdnative.h>
|
||||
#include <gdnative/string.h>
|
||||
|
||||
void GDAPI godot_color_new_rgba(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b, const godot_real p_a);
|
||||
void GDAPI godot_color_new_rgb(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b);
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue