summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/config/project_settings.cpp1
-rw-r--r--core/core_constants.cpp1
-rw-r--r--core/io/image.cpp43
-rw-r--r--core/io/image.h12
-rw-r--r--core/math/triangle_mesh.cpp16
-rw-r--r--core/math/triangle_mesh.h7
-rw-r--r--core/object/object.h1
-rw-r--r--core/os/os.cpp4
-rw-r--r--core/os/os.h1
9 files changed, 79 insertions, 7 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index c65a2a5bc6..7145e628c1 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -41,7 +41,6 @@
#include "core/os/keyboard.h"
#include "core/variant/variant_parser.h"
#include "core/version.h"
-
#include "modules/modules_enabled.gen.h" // For mono.
const String ProjectSettings::PROJECT_DATA_DIR_NAME_SUFFIX = "godot";
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index 4e0845e625..1f46223a1d 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -607,6 +607,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_OBJECT_TOO_BIG);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NODE_PATH_VALID_TYPES);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_SAVE_FILE);
+ BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_GLOBAL_SAVE_FILE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_INT_IS_OBJECTID);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_INT_IS_POINTER);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ARRAY_TYPE);
diff --git a/core/io/image.cpp b/core/io/image.cpp
index dfba45c4e9..a945d3e6cd 100644
--- a/core/io/image.cpp
+++ b/core/io/image.cpp
@@ -81,9 +81,14 @@ const char *Image::format_names[Image::FORMAT_MAX] = {
};
SavePNGFunc Image::save_png_func = nullptr;
+SaveJPGFunc Image::save_jpg_func = nullptr;
SaveEXRFunc Image::save_exr_func = nullptr;
SavePNGBufferFunc Image::save_png_buffer_func = nullptr;
+SaveJPGBufferFunc Image::save_jpg_buffer_func = nullptr;
+
+SaveWebPFunc Image::save_webp_func = nullptr;
+SaveWebPBufferFunc Image::save_webp_buffer_func = nullptr;
void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixel_size, uint8_t *p_data, const uint8_t *p_pixel) {
uint32_t ofs = (p_y * width + p_x) * p_pixel_size;
@@ -2286,6 +2291,14 @@ Error Image::save_png(const String &p_path) const {
return save_png_func(p_path, Ref<Image>((Image *)this));
}
+Error Image::save_jpg(const String &p_path, float p_quality) const {
+ if (save_jpg_func == nullptr) {
+ return ERR_UNAVAILABLE;
+ }
+
+ return save_jpg_func(p_path, Ref<Image>((Image *)this), p_quality);
+}
+
Vector<uint8_t> Image::save_png_to_buffer() const {
if (save_png_buffer_func == nullptr) {
return Vector<uint8_t>();
@@ -2294,6 +2307,14 @@ Vector<uint8_t> Image::save_png_to_buffer() const {
return save_png_buffer_func(Ref<Image>((Image *)this));
}
+Vector<uint8_t> Image::save_jpg_to_buffer(float p_quality) const {
+ if (save_jpg_buffer_func == nullptr) {
+ return Vector<uint8_t>();
+ }
+
+ return save_jpg_buffer_func(Ref<Image>((Image *)this), p_quality);
+}
+
Error Image::save_exr(const String &p_path, bool p_grayscale) const {
if (save_exr_func == nullptr) {
return ERR_UNAVAILABLE;
@@ -2302,6 +2323,24 @@ Error Image::save_exr(const String &p_path, bool p_grayscale) const {
return save_exr_func(p_path, Ref<Image>((Image *)this), p_grayscale);
}
+Error Image::save_webp(const String &p_path, const bool p_lossy, const float p_quality) const {
+ if (save_webp_func == nullptr) {
+ return ERR_UNAVAILABLE;
+ }
+ ERR_FAIL_COND_V_MSG(p_lossy && !(0.0f <= p_quality && p_quality <= 1.0f), ERR_INVALID_PARAMETER, "The WebP lossy quality was set to " + rtos(p_quality) + ", which is not valid. WebP lossy quality must be between 0.0 and 1.0 (inclusive).");
+
+ return save_webp_func(p_path, Ref<Image>((Image *)this), p_lossy, p_quality);
+}
+
+Vector<uint8_t> Image::save_webp_to_buffer(const bool p_lossy, const float p_quality) const {
+ if (save_webp_buffer_func == nullptr) {
+ return Vector<uint8_t>();
+ }
+ ERR_FAIL_COND_V_MSG(p_lossy && !(0.0f <= p_quality && p_quality <= 1.0f), Vector<uint8_t>(), "The WebP lossy quality was set to " + rtos(p_quality) + ", which is not valid. WebP lossy quality must be between 0.0 and 1.0 (inclusive).");
+
+ return save_webp_buffer_func(Ref<Image>((Image *)this), p_lossy, p_quality);
+}
+
int Image::get_image_data_size(int p_width, int p_height, Format p_format, bool p_mipmaps) {
int mm;
return _get_dst_image_size(p_width, p_height, p_format, mm, p_mipmaps ? -1 : 0);
@@ -3138,7 +3177,11 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("load", "path"), &Image::load);
ClassDB::bind_method(D_METHOD("save_png", "path"), &Image::save_png);
ClassDB::bind_method(D_METHOD("save_png_to_buffer"), &Image::save_png_to_buffer);
+ ClassDB::bind_method(D_METHOD("save_jpg", "path", "quality"), &Image::save_jpg, DEFVAL(0.75));
+ ClassDB::bind_method(D_METHOD("save_jpg_to_buffer", "quality"), &Image::save_jpg_to_buffer, DEFVAL(0.75));
ClassDB::bind_method(D_METHOD("save_exr", "path", "grayscale"), &Image::save_exr, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("save_webp", "path", "lossy", "quality"), &Image::save_webp, DEFVAL(false), DEFVAL(0.75f));
+ ClassDB::bind_method(D_METHOD("save_webp_to_buffer", "lossy", "quality"), &Image::save_webp_to_buffer, DEFVAL(false), DEFVAL(0.75f));
ClassDB::bind_method(D_METHOD("detect_alpha"), &Image::detect_alpha);
ClassDB::bind_method(D_METHOD("is_invisible"), &Image::is_invisible);
diff --git a/core/io/image.h b/core/io/image.h
index 1025554d51..229103f792 100644
--- a/core/io/image.h
+++ b/core/io/image.h
@@ -45,7 +45,11 @@ class Image;
typedef Error (*SavePNGFunc)(const String &p_path, const Ref<Image> &p_img);
typedef Vector<uint8_t> (*SavePNGBufferFunc)(const Ref<Image> &p_img);
+typedef Error (*SaveJPGFunc)(const String &p_path, const Ref<Image> &p_img, float p_quality);
+typedef Vector<uint8_t> (*SaveJPGBufferFunc)(const Ref<Image> &p_img, float p_quality);
typedef Ref<Image> (*ImageMemLoadFunc)(const uint8_t *p_png, int p_size);
+typedef Error (*SaveWebPFunc)(const String &p_path, const Ref<Image> &p_img, const bool p_lossy, const float p_quality);
+typedef Vector<uint8_t> (*SaveWebPBufferFunc)(const Ref<Image> &p_img, const bool p_lossy, const float p_quality);
typedef Error (*SaveEXRFunc)(const String &p_path, const Ref<Image> &p_img, bool p_grayscale);
@@ -54,8 +58,12 @@ class Image : public Resource {
public:
static SavePNGFunc save_png_func;
+ static SaveJPGFunc save_jpg_func;
static SaveEXRFunc save_exr_func;
static SavePNGBufferFunc save_png_buffer_func;
+ static SaveJPGBufferFunc save_jpg_buffer_func;
+ static SaveWebPFunc save_webp_func;
+ static SaveWebPBufferFunc save_webp_buffer_func;
enum {
MAX_WIDTH = (1 << 24), // force a limit somehow
@@ -281,8 +289,12 @@ public:
Error load(const String &p_path);
Error save_png(const String &p_path) const;
+ Error save_jpg(const String &p_path, float p_quality = 0.75) const;
Vector<uint8_t> save_png_to_buffer() const;
+ Vector<uint8_t> save_jpg_to_buffer(float p_quality = 0.75) const;
Error save_exr(const String &p_path, bool p_grayscale) const;
+ Error save_webp(const String &p_path, const bool p_lossy = false, const float p_quality = 0.75f) const;
+ Vector<uint8_t> save_webp_to_buffer(const bool p_lossy = false, const float p_quality = 0.75f) const;
void create_empty(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
create(p_width, p_height, p_use_mipmaps, p_format);
diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp
index 54461bf70f..4433559e6d 100644
--- a/core/math/triangle_mesh.cpp
+++ b/core/math/triangle_mesh.cpp
@@ -104,9 +104,11 @@ void TriangleMesh::get_indices(Vector<int> *r_triangles_indices) const {
}
}
-void TriangleMesh::create(const Vector<Vector3> &p_faces) {
+void TriangleMesh::create(const Vector<Vector3> &p_faces, const Vector<int32_t> &p_surface_indices) {
valid = false;
+ ERR_FAIL_COND(p_surface_indices.size() && p_surface_indices.size() != p_faces.size());
+
int fc = p_faces.size();
ERR_FAIL_COND(!fc || ((fc % 3) != 0));
fc /= 3;
@@ -121,6 +123,7 @@ void TriangleMesh::create(const Vector<Vector3> &p_faces) {
//goes in-place.
const Vector3 *r = p_faces.ptr();
+ const int32_t *si = p_surface_indices.ptr();
Triangle *w = triangles.ptrw();
HashMap<Vector3, int> db;
@@ -148,6 +151,7 @@ void TriangleMesh::create(const Vector<Vector3> &p_faces) {
}
f.normal = Face3(r[i * 3 + 0], r[i * 3 + 1], r[i * 3 + 2]).get_plane().get_normal();
+ f.surface_index = si ? si[i] : 0;
bw[i].left = -1;
bw[i].right = -1;
@@ -264,7 +268,7 @@ Vector3 TriangleMesh::get_area_normal(const AABB &p_aabb) const {
return n;
}
-bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const {
+bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index) const {
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth);
enum {
@@ -317,6 +321,9 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en
d = nd;
r_point = res;
r_normal = f3.get_plane().get_normal();
+ if (r_surf_index) {
+ *r_surf_index = s.surface_index;
+ }
inters = true;
}
}
@@ -366,7 +373,7 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en
return inters;
}
-bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal) const {
+bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index) const {
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth);
enum {
@@ -417,6 +424,9 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V
d = nd;
r_point = res;
r_normal = f3.get_plane().get_normal();
+ if (r_surf_index) {
+ *r_surf_index = s.surface_index;
+ }
inters = true;
}
}
diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h
index 1b99945698..166b4adb7a 100644
--- a/core/math/triangle_mesh.h
+++ b/core/math/triangle_mesh.h
@@ -41,6 +41,7 @@ public:
struct Triangle {
Vector3 normal;
int indices[3];
+ int32_t surface_index;
};
private:
@@ -81,8 +82,8 @@ private:
public:
bool is_valid() const;
- bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const;
- bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal) const;
+ bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const;
+ bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const;
bool intersect_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count) const;
bool inside_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, Vector3 p_scale = Vector3(1, 1, 1)) const;
Vector3 get_area_normal(const AABB &p_aabb) const;
@@ -92,7 +93,7 @@ public:
const Vector<Vector3> &get_vertices() const { return vertices; }
void get_indices(Vector<int> *r_triangles_indices) const;
- void create(const Vector<Vector3> &p_faces);
+ void create(const Vector<Vector3> &p_faces, const Vector<int32_t> &p_surface_indices = Vector<int32_t>());
TriangleMesh();
};
diff --git a/core/object/object.h b/core/object/object.h
index 8117783fae..02dd875acf 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -85,6 +85,7 @@ enum PropertyHint {
PROPERTY_HINT_OBJECT_TOO_BIG, ///< object is too big to send
PROPERTY_HINT_NODE_PATH_VALID_TYPES,
PROPERTY_HINT_SAVE_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog
+ PROPERTY_HINT_GLOBAL_SAVE_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog
PROPERTY_HINT_INT_IS_OBJECTID,
PROPERTY_HINT_ARRAY_TYPE,
PROPERTY_HINT_INT_IS_POINTER,
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 327f1c95f2..93477f4288 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -388,6 +388,10 @@ bool OS::has_feature(const String &p_feature) {
return true;
}
+ if (p_feature == "movie") {
+ return _writing_movie;
+ }
+
#ifdef DEBUG_ENABLED
if (p_feature == "debug") {
return true;
diff --git a/core/os/os.h b/core/os/os.h
index 157b8ab992..c6ea9d869a 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -58,6 +58,7 @@ class OS {
bool _allow_layered = false;
bool _stdout_enabled = true;
bool _stderr_enabled = true;
+ bool _writing_movie = false;
CompositeLogger *_logger = nullptr;