summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--core/io/file_access_zip.cpp3
-rw-r--r--core/io/pck_packer.cpp1
-rw-r--r--core/math/a_star.cpp25
-rw-r--r--core/math/a_star.h3
-rw-r--r--core/math/math_2d.cpp22
-rw-r--r--core/math/math_2d.h2
-rw-r--r--core/math/transform.h23
-rw-r--r--core/math/vector3.h20
-rw-r--r--core/os/os.h4
-rw-r--r--core/script_language.h2
-rw-r--r--core/variant_call.cpp12
-rw-r--r--core/variant_parser.cpp2
-rw-r--r--doc/base/classes.xml37
-rwxr-xr-xdoc/tools/doc_status.py2
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp6
-rw-r--r--drivers/gles2/rasterizer_gles2.h6
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp28
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp156
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h1
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp268
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h58
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp76
-rw-r--r--drivers/gles3/shader_compiler_gles3.h1
-rw-r--r--drivers/gles3/shaders/particles.glsl115
-rw-r--r--drivers/gles3/shaders/scene.glsl79
-rw-r--r--drivers/unix/os_unix.cpp31
-rw-r--r--drivers/unix/os_unix.h4
-rw-r--r--editor/editor_file_system.cpp2
-rw-r--r--editor/editor_node.cpp10
-rw-r--r--editor/filesystem_dock.cpp2
-rw-r--r--editor/import/editor_import_collada.cpp34
-rw-r--r--editor/import/resource_importer_scene.cpp34
-rw-r--r--editor/io_plugins/editor_scene_import_plugin.cpp30
-rw-r--r--editor/io_plugins/editor_scene_importer_fbxconv.cpp24
-rw-r--r--editor/plugins/baked_light_baker.cpp10
-rw-r--r--editor/plugins/collision_polygon_editor_plugin.cpp20
-rw-r--r--editor/plugins/collision_polygon_editor_plugin.h4
-rw-r--r--editor/plugins/curve_editor_plugin.cpp519
-rw-r--r--editor/plugins/curve_editor_plugin.h66
-rw-r--r--editor/plugins/gradient_texture_editor_plugin.cpp504
-rw-r--r--editor/plugins/gradient_texture_editor_plugin.h69
-rw-r--r--editor/plugins/particles_editor_plugin.cpp352
-rw-r--r--editor/plugins/particles_editor_plugin.h22
-rw-r--r--editor/plugins/path_editor_plugin.cpp12
-rw-r--r--editor/plugins/path_editor_plugin.h4
-rw-r--r--editor/plugins/shader_editor_plugin.cpp29
-rw-r--r--editor/plugins/shader_editor_plugin.h2
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp50
-rw-r--r--editor/plugins/spatial_editor_plugin.h10
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp2
-rw-r--r--editor/property_editor.cpp2
-rw-r--r--editor/scene_tree_editor.cpp1
-rw-r--r--editor/script_create_dialog.cpp18
-rw-r--r--editor/spatial_editor_gizmos.cpp179
-rw-r--r--editor/spatial_editor_gizmos.h67
-rw-r--r--main/input_default.cpp17
-rw-r--r--main/tests/test_shader_lang.cpp4
-rw-r--r--modules/cscript/SCsub7
-rw-r--r--modules/cscript/godot_c.cpp29
-rw-r--r--modules/cscript/godot_c.h567
-rw-r--r--modules/dlscript/SCsub14
-rw-r--r--modules/dlscript/api_generator.cpp394
-rw-r--r--modules/dlscript/api_generator.h9
-rw-r--r--modules/dlscript/config.py (renamed from modules/cscript/config.py)2
-rw-r--r--modules/dlscript/dl_script.cpp1120
-rw-r--r--modules/dlscript/dl_script.h404
-rw-r--r--modules/dlscript/godot.cpp198
-rw-r--r--modules/dlscript/godot.h389
-rw-r--r--modules/dlscript/godot/godot_array.cpp271
-rw-r--r--modules/dlscript/godot/godot_array.h88
-rw-r--r--modules/dlscript/godot/godot_basis.cpp58
-rw-r--r--modules/dlscript/godot/godot_basis.h34
-rw-r--r--modules/dlscript/godot/godot_color.cpp34
-rw-r--r--modules/dlscript/godot/godot_color.h29
-rw-r--r--modules/dlscript/godot/godot_dictionary.cpp109
-rw-r--r--modules/dlscript/godot/godot_dictionary.h51
-rw-r--r--modules/dlscript/godot/godot_image.cpp85
-rw-r--r--modules/dlscript/godot/godot_image.h95
-rw-r--r--modules/dlscript/godot/godot_input_event.cpp280
-rw-r--r--modules/dlscript/godot/godot_input_event.h206
-rw-r--r--modules/dlscript/godot/godot_node_path.cpp91
-rw-r--r--modules/dlscript/godot/godot_node_path.h39
-rw-r--r--modules/dlscript/godot/godot_plane.cpp48
-rw-r--r--modules/dlscript/godot/godot_plane.h37
-rw-r--r--modules/dlscript/godot/godot_pool_arrays.cpp558
-rw-r--r--modules/dlscript/godot/godot_pool_arrays.h256
-rw-r--r--modules/dlscript/godot/godot_quat.cpp77
-rw-r--r--modules/dlscript/godot/godot_quat.h33
-rw-r--r--modules/dlscript/godot/godot_rect2.cpp48
-rw-r--r--modules/dlscript/godot/godot_rect2.h31
-rw-r--r--modules/dlscript/godot/godot_rect3.cpp48
-rw-r--r--modules/dlscript/godot/godot_rect3.h31
-rw-r--r--modules/dlscript/godot/godot_rid.cpp36
-rw-r--r--modules/dlscript/godot/godot_rid.h28
-rw-r--r--modules/dlscript/godot/godot_string.cpp83
-rw-r--r--modules/dlscript/godot/godot_string.h42
-rw-r--r--modules/dlscript/godot/godot_transform.cpp42
-rw-r--r--modules/dlscript/godot/godot_transform.h29
-rw-r--r--modules/dlscript/godot/godot_transform2d.cpp59
-rw-r--r--modules/dlscript/godot/godot_transform2d.h48
-rw-r--r--modules/dlscript/godot/godot_variant.cpp476
-rw-r--r--modules/dlscript/godot/godot_variant.h150
-rw-r--r--modules/dlscript/godot/godot_vector2.cpp124
-rw-r--r--modules/dlscript/godot/godot_vector2.h78
-rw-r--r--modules/dlscript/godot/godot_vector3.cpp150
-rw-r--r--modules/dlscript/godot/godot_vector3.h82
-rw-r--r--modules/dlscript/register_types.cpp (renamed from modules/cscript/register_types.cpp)39
-rw-r--r--modules/dlscript/register_types.h (renamed from modules/cscript/register_types.h)4
-rw-r--r--modules/gdscript/gd_parser.cpp2
-rw-r--r--modules/gdscript/gd_tokenizer.cpp1
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp18
-rw-r--r--modules/gridmap/grid_map_editor_plugin.h6
-rw-r--r--platform/android/detect.py2
-rw-r--r--platform/iphone/rasterizer_iphone.cpp16
-rw-r--r--platform/iphone/rasterizer_iphone.h20
-rw-r--r--platform/windows/export/export.cpp29
-rw-r--r--platform/windows/os_windows.cpp29
-rw-r--r--platform/windows/os_windows.h4
-rw-r--r--platform/x11/os_x11.cpp9
-rw-r--r--scene/2d/canvas_item.cpp134
-rw-r--r--scene/2d/canvas_item.h38
-rw-r--r--scene/2d/node_2d.cpp22
-rw-r--r--scene/2d/physics_body_2d.cpp13
-rw-r--r--scene/2d/physics_body_2d.h2
-rw-r--r--scene/2d/screen_button.cpp31
-rw-r--r--scene/2d/screen_button.h4
-rw-r--r--scene/2d/tile_map.cpp4
-rw-r--r--scene/3d/baked_light_instance.cpp14
-rw-r--r--scene/3d/gi_probe.cpp14
-rw-r--r--scene/3d/particles.cpp1547
-rw-r--r--scene/3d/particles.h374
-rw-r--r--scene/3d/spatial.cpp23
-rw-r--r--scene/3d/spatial.h6
-rw-r--r--scene/3d/visual_instance.cpp6
-rw-r--r--scene/3d/visual_instance.h3
-rw-r--r--scene/gui/control.cpp14
-rw-r--r--scene/gui/dialogs.cpp13
-rw-r--r--scene/gui/patch_9_rect.cpp34
-rw-r--r--scene/gui/range.cpp10
-rw-r--r--scene/gui/split_container.cpp2
-rw-r--r--scene/gui/text_edit.cpp22
-rw-r--r--scene/gui/text_edit.h2
-rw-r--r--scene/main/scene_main_loop.cpp35
-rw-r--r--scene/main/scene_main_loop.h1
-rwxr-xr-xscene/main/timer.cpp6
-rw-r--r--scene/register_scene_types.cpp29
-rw-r--r--scene/resources/default_theme/default_theme.cpp4
-rw-r--r--scene/resources/material.cpp549
-rw-r--r--scene/resources/material.h88
-rw-r--r--scene/resources/mesh.cpp74
-rw-r--r--scene/resources/mesh.h16
-rw-r--r--scene/resources/shader.cpp19
-rw-r--r--scene/resources/shader.h29
-rw-r--r--scene/resources/style_box.cpp14
-rw-r--r--scene/resources/texture.cpp468
-rw-r--r--scene/resources/texture.h141
-rw-r--r--scene/resources/tile_set.cpp12
-rw-r--r--scene/resources/tile_set.h6
-rw-r--r--scene/scene_string_names.cpp3
-rw-r--r--scene/scene_string_names.h3
-rw-r--r--servers/visual/rasterizer.cpp98
-rw-r--r--servers/visual/rasterizer.h75
-rw-r--r--servers/visual/shader_language.cpp354
-rw-r--r--servers/visual/shader_language.h21
-rw-r--r--servers/visual/shader_types.cpp23
-rw-r--r--servers/visual/shader_types.h3
-rw-r--r--servers/visual/visual_server_raster.cpp34
-rw-r--r--servers/visual/visual_server_raster.h19
-rw-r--r--servers/visual/visual_server_scene.cpp36
-rw-r--r--servers/visual_server.h31
171 files changed, 12401 insertions, 2588 deletions
diff --git a/README.md b/README.md
index 935170479d..701982da11 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,7 @@ Official binaries for the Godot editor and the export templates can be found
#### Compiling from source
-[See the official docs](http://docs.godotengine.org/en/latest/reference/_compiling.html)
+[See the official docs](http://docs.godotengine.org/en/latest/development/compiling/)
for compilation instructions for every supported platform.
### Community
@@ -52,7 +52,7 @@ on Freenode.
The official documentation is hosted on [ReadTheDocs](http://docs.godotengine.org).
It is maintained by the Godot community in its own [GitHub repository](https://github.com/godotengine/godot-docs).
-The [class reference](http://docs.godotengine.org/en/latest/classes/_classes.html)
+The [class reference](http://docs.godotengine.org/en/latest/classes/)
is also accessible from within the engine.
The official demos are maintained in their own [GitHub repository](https://github.com/godotengine/godot-demo-projects)
diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp
index 4cc2edd1c3..47432b1e97 100644
--- a/core/io/file_access_zip.cpp
+++ b/core/io/file_access_zip.cpp
@@ -149,8 +149,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
unzFile pkg = unzOpen2(packages[file.package].filename.utf8().get_data(), &io);
ERR_FAIL_COND_V(!pkg, NULL);
int unz_err = unzGoToFilePos(pkg, &file.file_pos);
- ERR_FAIL_COND_V(unz_err != UNZ_OK, NULL);
- if (unzOpenCurrentFile(pkg) != UNZ_OK) {
+ if (unz_err != UNZ_OK || unzOpenCurrentFile(pkg) != UNZ_OK) {
unzClose(pkg);
ERR_FAIL_V(NULL);
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index 9dd9b044a2..974ed64267 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -172,6 +172,7 @@ Error PCKPacker::flush(bool p_verbose) {
printf("\n");
file->close();
+ memdelete(buf);
return OK;
};
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index 110185c2d2..c82a40f30d 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -28,6 +28,8 @@
/*************************************************************************/
#include "a_star.h"
#include "geometry.h"
+#include "scene/scene_string_names.h"
+#include "script_language.h"
int AStar::get_available_point_id() const {
@@ -187,7 +189,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
Point *n = begin_point->neighbours[i];
n->prev_point = begin_point;
- n->distance = n->pos.distance_to(begin_point->pos);
+ n->distance = _compute_cost(n->id, begin_point->id);
n->distance *= n->weight_scale;
n->last_pass = pass;
open_list.add(&n->list);
@@ -215,7 +217,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
Point *p = E->self();
real_t cost = p->distance;
- cost += p->pos.distance_to(end_point->pos);
+ cost += _estimate_cost(p->id, end_point->id);
cost *= p->weight_scale;
if (cost < least_cost) {
@@ -233,7 +235,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
Point *e = p->neighbours[i];
- real_t distance = p->pos.distance_to(e->pos) + p->distance;
+ real_t distance = _compute_cost(p->id, e->id) + p->distance;
distance *= e->weight_scale;
if (e->last_pass == pass) {
@@ -274,6 +276,20 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
return found_route;
}
+float AStar::_estimate_cost(int p_from_id, int p_to_id) {
+ if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost))
+ return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id);
+
+ return points[p_from_id]->pos.distance_to(points[p_to_id]->pos);
+}
+
+float AStar::_compute_cost(int p_from_id, int p_to_id) {
+ if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost))
+ return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id);
+
+ return points[p_from_id]->pos.distance_to(points[p_to_id]->pos);
+}
+
PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
ERR_FAIL_COND_V(!points.has(p_from_id), PoolVector<Vector3>());
@@ -395,6 +411,9 @@ void AStar::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_point_path", "from_id", "to_id"), &AStar::get_point_path);
ClassDB::bind_method(D_METHOD("get_id_path", "from_id", "to_id"), &AStar::get_id_path);
+
+ BIND_VMETHOD(MethodInfo("_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
+ BIND_VMETHOD(MethodInfo("_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
}
AStar::AStar() {
diff --git a/core/math/a_star.h b/core/math/a_star.h
index 2ac855737c..43c9c4457a 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -93,6 +93,9 @@ class AStar : public Reference {
protected:
static void _bind_methods();
+ virtual float _estimate_cost(int p_from_id, int p_to_id);
+ virtual float _compute_cost(int p_from_id, int p_to_id);
+
public:
int get_available_point_id() const;
diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp
index 8f942c423f..77cff6a052 100644
--- a/core/math/math_2d.cpp
+++ b/core/math/math_2d.cpp
@@ -61,6 +61,10 @@ Vector2 Vector2::normalized() const {
return v;
}
+bool Vector2::is_normalized() const {
+ return Math::isequal_approx(length(), (real_t)1.0);
+}
+
real_t Vector2::distance_to(const Vector2 &p_vector2) const {
return Math::sqrt((x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y));
@@ -274,13 +278,23 @@ Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, c
*/
}
-Vector2 Vector2::slide(const Vector2 &p_vec) const {
+// slide returns the component of the vector along the given plane, specified by its normal vector.
+Vector2 Vector2::slide(const Vector2 &p_n) const {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND_V(p_n.is_normalized() == false, Vector2());
+#endif
+ return *this - p_n * this->dot(p_n);
+}
- return p_vec - *this * this->dot(p_vec);
+Vector2 Vector2::bounce(const Vector2 &p_n) const {
+ return -reflect(p_n);
}
-Vector2 Vector2::reflect(const Vector2 &p_vec) const {
- return p_vec - *this * this->dot(p_vec) * 2.0;
+Vector2 Vector2::reflect(const Vector2 &p_n) const {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND_V(p_n.is_normalized() == false, Vector2());
+#endif
+ return 2.0 * p_n * this->dot(p_n) - *this;
}
bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const {
diff --git a/core/math/math_2d.h b/core/math/math_2d.h
index af6437d7f1..50ebcb845f 100644
--- a/core/math/math_2d.h
+++ b/core/math/math_2d.h
@@ -82,6 +82,7 @@ struct Vector2 {
void normalize();
Vector2 normalized() const;
+ bool is_normalized() const;
real_t length() const;
real_t length_squared() const;
@@ -106,6 +107,7 @@ struct Vector2 {
Vector2 cubic_interpolate_soft(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const;
Vector2 slide(const Vector2 &p_vec) const;
+ Vector2 bounce(const Vector2 &p_vec) const;
Vector2 reflect(const Vector2 &p_vec) const;
Vector2 operator+(const Vector2 &p_v) const;
diff --git a/core/math/transform.h b/core/math/transform.h
index e307aba129..64b4b23aa0 100644
--- a/core/math/transform.h
+++ b/core/math/transform.h
@@ -229,27 +229,4 @@ _FORCE_INLINE_ Rect3 Transform::xform_inv(const Rect3 &p_aabb) const {
return ret;
}
-#ifdef OPTIMIZED_TRANSFORM_IMPL_OVERRIDE
-
-#else
-
-struct OptimizedTransform {
-
- Transform transform;
-
- _FORCE_INLINE_ void invert() { transform.invert(); }
- _FORCE_INLINE_ void affine_invert() { transform.affine_invert(); }
- _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vec) const { return transform.xform(p_vec); };
- _FORCE_INLINE_ Vector3 xform_inv(const Vector3 &p_vec) const { return transform.xform_inv(p_vec); };
- _FORCE_INLINE_ OptimizedTransform operator*(const OptimizedTransform &p_ot) const { return OptimizedTransform(transform * p_ot.transform); }
- _FORCE_INLINE_ Transform get_transform() const { return transform; }
- _FORCE_INLINE_ void set_transform(const Transform &p_transform) { transform = p_transform; }
-
- OptimizedTransform(const Transform &p_transform) {
- transform = p_transform;
- }
-};
-
-#endif
-
#endif
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 951380e898..8550ae7009 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -107,6 +107,7 @@ struct Vector3 {
_FORCE_INLINE_ real_t angle_to(const Vector3 &p_b) const;
_FORCE_INLINE_ Vector3 slide(const Vector3 &p_vec) const;
+ _FORCE_INLINE_ Vector3 bounce(const Vector3 &p_vec) const;
_FORCE_INLINE_ Vector3 reflect(const Vector3 &p_vec) const;
/* Operators */
@@ -400,14 +401,23 @@ void Vector3::zero() {
x = y = z = 0;
}
-Vector3 Vector3::slide(const Vector3 &p_vec) const {
-
- return p_vec - *this * this->dot(p_vec);
+// slide returns the component of the vector along the given plane, specified by its normal vector.
+Vector3 Vector3::slide(const Vector3 &p_n) const {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND_V(p_n.is_normalized() == false, Vector3());
+#endif
+ return *this - p_n * this->dot(p_n);
}
-Vector3 Vector3::reflect(const Vector3 &p_vec) const {
+Vector3 Vector3::bounce(const Vector3 &p_n) const {
+ return -reflect(p_n);
+}
- return p_vec - *this * this->dot(p_vec) * 2.0;
+Vector3 Vector3::reflect(const Vector3 &p_n) const {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND_V(p_n.is_normalized() == false, Vector3());
+#endif
+ return 2.0 * p_n * this->dot(p_n) - *this;
}
#endif
diff --git a/core/os/os.h b/core/os/os.h
index 46e57e5186..0febfb70cf 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -177,6 +177,10 @@ public:
virtual void set_borderless_window(int p_borderless) {}
virtual bool get_borderless_window() { return 0; }
+ virtual Error open_dynamic_library(const String p_path, void *&p_library_handle) { return ERR_UNAVAILABLE; };
+ virtual Error close_dynamic_library(void *p_library_handle) { return ERR_UNAVAILABLE; };
+ virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle) { return ERR_UNAVAILABLE; };
+
virtual void set_keep_screen_on(bool p_enabled);
virtual bool is_keep_screen_on() const;
virtual void set_low_processor_usage_mode(bool p_enabled);
diff --git a/core/script_language.h b/core/script_language.h
index 6c37074639..88584e4ef9 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -43,7 +43,7 @@ typedef void (*ScriptEditRequestFunction)(const String &p_path);
class ScriptServer {
enum {
- MAX_LANGUAGES = 4
+ MAX_LANGUAGES = 16
};
static ScriptLanguage *_languages[MAX_LANGUAGES];
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 758500a873..9c435ea0e5 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -340,6 +340,7 @@ struct _VariantCall {
VCALL_LOCALMEM0R(Vector2, aspect);
VCALL_LOCALMEM1R(Vector2, dot);
VCALL_LOCALMEM1R(Vector2, slide);
+ VCALL_LOCALMEM1R(Vector2, bounce);
VCALL_LOCALMEM1R(Vector2, reflect);
VCALL_LOCALMEM0R(Vector2, angle);
//VCALL_LOCALMEM1R(Vector2,cross);
@@ -377,6 +378,7 @@ struct _VariantCall {
VCALL_LOCALMEM1R(Vector3, distance_squared_to);
VCALL_LOCALMEM1R(Vector3, angle_to);
VCALL_LOCALMEM1R(Vector3, slide);
+ VCALL_LOCALMEM1R(Vector3, bounce);
VCALL_LOCALMEM1R(Vector3, reflect);
VCALL_LOCALMEM0R(Plane, normalized);
@@ -1438,8 +1440,9 @@ void register_variant_methods() {
ADDFUNC1(VECTOR2, VECTOR2, Vector2, snapped, VECTOR2, "by", varray());
ADDFUNC0(VECTOR2, REAL, Vector2, aspect, varray());
ADDFUNC1(VECTOR2, REAL, Vector2, dot, VECTOR2, "with", varray());
- ADDFUNC1(VECTOR2, VECTOR2, Vector2, slide, VECTOR2, "vec", varray());
- ADDFUNC1(VECTOR2, VECTOR2, Vector2, reflect, VECTOR2, "vec", varray());
+ ADDFUNC1(VECTOR2, VECTOR2, Vector2, slide, VECTOR2, "n", varray());
+ ADDFUNC1(VECTOR2, VECTOR2, Vector2, bounce, VECTOR2, "n", varray());
+ ADDFUNC1(VECTOR2, VECTOR2, Vector2, reflect, VECTOR2, "n", varray());
//ADDFUNC1(VECTOR2,REAL,Vector2,cross,VECTOR2,"with",varray());
ADDFUNC0(VECTOR2, VECTOR2, Vector2, abs, varray());
ADDFUNC1(VECTOR2, VECTOR2, Vector2, clamped, REAL, "length", varray());
@@ -1475,8 +1478,9 @@ void register_variant_methods() {
ADDFUNC1(VECTOR3, REAL, Vector3, distance_to, VECTOR3, "b", varray());
ADDFUNC1(VECTOR3, REAL, Vector3, distance_squared_to, VECTOR3, "b", varray());
ADDFUNC1(VECTOR3, REAL, Vector3, angle_to, VECTOR3, "to", varray());
- ADDFUNC1(VECTOR3, VECTOR3, Vector3, slide, VECTOR3, "by", varray());
- ADDFUNC1(VECTOR3, VECTOR3, Vector3, reflect, VECTOR3, "by", varray());
+ ADDFUNC1(VECTOR3, VECTOR3, Vector3, slide, VECTOR3, "n", varray());
+ ADDFUNC1(VECTOR3, VECTOR3, Vector3, bounce, VECTOR3, "n", varray());
+ ADDFUNC1(VECTOR3, VECTOR3, Vector3, reflect, VECTOR3, "n", varray());
ADDFUNC0(PLANE, PLANE, Plane, normalized, varray());
ADDFUNC0(PLANE, VECTOR3, Plane, center, varray());
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index 67e4673ad6..733854a15e 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -755,7 +755,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
Image::Format format = Image::FORMAT_MAX;
for (int i = 0; i < Image::FORMAT_MAX; i++) {
- if (Image::get_format_name(format) == sformat) {
+ if (Image::get_format_name(Image::Format(i)) == sformat) {
format = Image::Format(i);
}
}
diff --git a/doc/base/classes.xml b/doc/base/classes.xml
index f3d73deaf0..5bb85aedc1 100644
--- a/doc/base/classes.xml
+++ b/doc/base/classes.xml
@@ -21836,6 +21836,8 @@
</argument>
<argument index="3" name="max_bounces" type="int" default="4">
</argument>
+ <argument index="4" name="floor_max_angle" type="float" default="0.785398">
+ </argument>
<description>
</description>
</method>
@@ -21846,6 +21848,7 @@
</argument>
<description>
Move the body to the given position. This is not a teleport, and the body will stop if there is an obstacle. The returned vector is how much movement was remaining before being stopped.
+ [code]floor_max_angle[/code] is in radians (default is pi/4), and filters which obstacles should be considered as floors/cellings instead of walls.
</description>
</method>
<method name="revert_motion">
@@ -46992,6 +46995,15 @@ do_property].
Returns the ratio of X to Y.
</description>
</method>
+ <method name="bounce">
+ <return type="Vector2">
+ </return>
+ <argument index="0" name="n" type="Vector2">
+ </argument>
+ <description>
+ Bounce returns the vector "bounced off" from the given plane, specified by its normal vector.
+ </description>
+ </method>
<method name="clamped">
<return type="Vector2">
</return>
@@ -47084,10 +47096,10 @@ do_property].
<method name="reflect">
<return type="Vector2">
</return>
- <argument index="0" name="vec" type="Vector2">
+ <argument index="0" name="n" type="Vector2">
</argument>
<description>
- Like "slide", but reflects the Vector instead of continuing along the wall.
+ Reflects the vector along the given plane, specified by its normal vector.
</description>
</method>
<method name="rotated">
@@ -47102,10 +47114,10 @@ do_property].
<method name="slide">
<return type="Vector2">
</return>
- <argument index="0" name="vec" type="Vector2">
+ <argument index="0" name="n" type="Vector2">
</argument>
<description>
- Slides the vector by the other vector.
+ Slide returns the component of the vector along the given plane, specified by its normal vector.
</description>
</method>
<method name="snapped">
@@ -47178,6 +47190,15 @@ do_property].
<description>
</description>
</method>
+ <method name="bounce">
+ <return type="Vector3">
+ </return>
+ <argument index="0" name="n" type="Vector3">
+ </argument>
+ <description>
+ Bounce returns the vector "bounced off" from the given plane, specified by its normal vector.
+ </description>
+ </method>
<method name="ceil">
<return type="Vector3">
</return>
@@ -47308,10 +47329,10 @@ do_property].
<method name="reflect">
<return type="Vector3">
</return>
- <argument index="0" name="by" type="Vector3">
+ <argument index="0" name="n" type="Vector3">
</argument>
<description>
- Like "slide", but reflects the Vector instead of continuing along the wall.
+ Reflects the vector along the given plane, specified by its normal vector.
</description>
</method>
<method name="rotated">
@@ -47328,10 +47349,10 @@ do_property].
<method name="slide">
<return type="Vector3">
</return>
- <argument index="0" name="by" type="Vector3">
+ <argument index="0" name="n" type="Vector3">
</argument>
<description>
- Slides the vector along a wall.
+ Slide returns the component of the vector along the given plane, specified by its normal vector.
</description>
</method>
<method name="snapped">
diff --git a/doc/tools/doc_status.py b/doc/tools/doc_status.py
index 78f39fc7ec..1386e91ce1 100755
--- a/doc/tools/doc_status.py
+++ b/doc/tools/doc_status.py
@@ -206,7 +206,7 @@ class ClassStatus:
output['overall'] = (description_progress + items_progress).to_colored_string('{percent}%', '{pad_percent}{s}')
if self.name.startswith('Total'):
- output['url'] = color('url', 'http://docs.godotengine.org/en/latest/classes/_classes.html')
+ output['url'] = color('url', 'http://docs.godotengine.org/en/latest/classes/')
if flags['s']:
output['comment'] = color('part_good', 'ALL OK')
else:
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 3f54f887da..fcac0a3e05 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -8699,7 +8699,7 @@ void RasterizerGLES2::_canvas_item_render_commands(CanvasItem *p_item, CanvasIte
}
}
-void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItemMaterial *material, Shader *shader) {
+void RasterizerGLES2::_canvas_item_setup_shader_params(ShaderMaterial *material, Shader *shader) {
if (canvas_shader.bind())
rebind_texpixel_size = true;
@@ -8748,7 +8748,7 @@ void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItemMaterial *mater
uses_texpixel_size = shader->uses_texpixel_size;
}
-void RasterizerGLES2::_canvas_item_setup_shader_uniforms(CanvasItemMaterial *material, Shader *shader) {
+void RasterizerGLES2::_canvas_item_setup_shader_uniforms(ShaderMaterial *material, Shader *shader) {
//this can be optimized..
int tex_id = 1;
@@ -8925,7 +8925,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list, int p_z, cons
//begin rect
CanvasItem *material_owner = ci->material_owner ? ci->material_owner : ci;
- CanvasItemMaterial *material = material_owner->material;
+ ShaderMaterial *material = material_owner->material;
if (material != canvas_last_material || rebind_shader) {
diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h
index 9aeb3af61a..f45b51ae57 100644
--- a/drivers/gles2/rasterizer_gles2.h
+++ b/drivers/gles2/rasterizer_gles2.h
@@ -1224,7 +1224,7 @@ class RasterizerGLES2 : public Rasterizer {
bool uses_texpixel_size;
bool rebind_texpixel_size;
Transform canvas_transform;
- CanvasItemMaterial *canvas_last_material;
+ ShaderMaterial *canvas_last_material;
bool canvas_texscreen_used;
Vector2 normal_flip;
_FORCE_INLINE_ void _canvas_normal_set_flip(const Vector2 &p_flip);
@@ -1288,8 +1288,8 @@ class RasterizerGLES2 : public Rasterizer {
template <bool use_normalmap>
_FORCE_INLINE_ void _canvas_item_render_commands(CanvasItem *p_item, CanvasItem *current_clip, bool &reclip);
- _FORCE_INLINE_ void _canvas_item_setup_shader_params(CanvasItemMaterial *material, Shader *p_shader);
- _FORCE_INLINE_ void _canvas_item_setup_shader_uniforms(CanvasItemMaterial *material, Shader *p_shader);
+ _FORCE_INLINE_ void _canvas_item_setup_shader_params(ShaderMaterial *material, Shader *p_shader);
+ _FORCE_INLINE_ void _canvas_item_setup_shader_uniforms(ShaderMaterial *material, Shader *p_shader);
public:
/* TEXTURE API */
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 26d13bad89..43fff5a1b1 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -535,49 +535,49 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
//top left
DSTRECT(np->rect.pos.x, np->rect.pos.y, np->margin[MARGIN_LEFT], np->margin[MARGIN_TOP]);
- SRCRECT(0, 0, np->margin[MARGIN_LEFT], np->margin[MARGIN_TOP]);
+ SRCRECT(np->source.pos.x, np->source.pos.y, np->margin[MARGIN_LEFT], np->margin[MARGIN_TOP]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//top right
- DSTRECT(np->rect.pos.x + np->rect.size.x - np->margin[MARGIN_RIGHT], np->rect.pos.y, np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
- SRCRECT(texture->width - np->margin[MARGIN_RIGHT], 0, np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
+ DSTRECT(np->rect.pos.x + np->rect.size.width - np->margin[MARGIN_RIGHT], np->rect.pos.y, np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
+ SRCRECT(np->source.pos.x + np->source.size.width - np->margin[MARGIN_RIGHT], np->source.pos.y, np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//bottom right
- DSTRECT(np->rect.pos.x + np->rect.size.x - np->margin[MARGIN_RIGHT], np->rect.pos.y + np->rect.size.y - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_RIGHT], np->margin[MARGIN_BOTTOM]);
- SRCRECT(texture->width - np->margin[MARGIN_RIGHT], texture->height - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_RIGHT], np->margin[MARGIN_BOTTOM]);
+ DSTRECT(np->rect.pos.x + np->rect.size.width - np->margin[MARGIN_RIGHT], np->rect.pos.y + np->rect.size.height - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_RIGHT], np->margin[MARGIN_BOTTOM]);
+ SRCRECT(np->source.pos.x + np->source.size.width - np->margin[MARGIN_RIGHT], np->source.pos.y + np->source.size.height - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_RIGHT], np->margin[MARGIN_BOTTOM]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//bottom left
- DSTRECT(np->rect.pos.x, np->rect.pos.y + np->rect.size.y - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_LEFT], np->margin[MARGIN_BOTTOM]);
- SRCRECT(0, texture->height - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_LEFT], np->margin[MARGIN_BOTTOM]);
+ DSTRECT(np->rect.pos.x, np->rect.pos.y + np->rect.size.height - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_LEFT], np->margin[MARGIN_BOTTOM]);
+ SRCRECT(np->source.pos.x, np->source.pos.y + np->source.size.height - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_LEFT], np->margin[MARGIN_BOTTOM]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//top
DSTRECT(np->rect.pos.x + np->margin[MARGIN_LEFT], np->rect.pos.y, np->rect.size.width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
- SRCRECT(np->margin[MARGIN_LEFT], 0, texture->width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
+ SRCRECT(np->source.pos.x + np->margin[MARGIN_LEFT], np->source.pos.y, np->source.size.width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//bottom
- DSTRECT(np->rect.pos.x + np->margin[MARGIN_LEFT], np->rect.pos.y + np->rect.size.y - np->margin[MARGIN_BOTTOM], np->rect.size.width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
- SRCRECT(np->margin[MARGIN_LEFT], texture->height - np->margin[MARGIN_BOTTOM], texture->width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_LEFT], np->margin[MARGIN_TOP]);
+ DSTRECT(np->rect.pos.x + np->margin[MARGIN_LEFT], np->rect.pos.y + np->rect.size.height - np->margin[MARGIN_BOTTOM], np->rect.size.width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
+ SRCRECT(np->source.pos.x + np->margin[MARGIN_LEFT], np->source.pos.y + np->source.size.height - np->margin[MARGIN_BOTTOM], np->source.size.width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_LEFT], np->margin[MARGIN_TOP]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//left
DSTRECT(np->rect.pos.x, np->rect.pos.y + np->margin[MARGIN_TOP], np->margin[MARGIN_LEFT], np->rect.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
- SRCRECT(0, np->margin[MARGIN_TOP], np->margin[MARGIN_LEFT], texture->height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
+ SRCRECT(np->source.pos.x, np->source.pos.y + np->margin[MARGIN_TOP], np->margin[MARGIN_LEFT], np->source.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//right
DSTRECT(np->rect.pos.x + np->rect.size.width - np->margin[MARGIN_RIGHT], np->rect.pos.y + np->margin[MARGIN_TOP], np->margin[MARGIN_RIGHT], np->rect.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
- SRCRECT(texture->width - np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP], np->margin[MARGIN_RIGHT], texture->height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
+ SRCRECT(np->source.pos.x + np->source.size.width - np->margin[MARGIN_RIGHT], np->source.pos.y + np->margin[MARGIN_TOP], np->margin[MARGIN_RIGHT], np->source.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
if (np->draw_center) {
//center
DSTRECT(np->rect.pos.x + np->margin[MARGIN_LEFT], np->rect.pos.y + np->margin[MARGIN_TOP], np->rect.size.x - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->rect.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
- SRCRECT(np->margin[MARGIN_LEFT], np->margin[MARGIN_TOP], texture->width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], texture->height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
+ SRCRECT(np->source.pos.x + np->margin[MARGIN_LEFT], np->source.pos.y + np->margin[MARGIN_TOP], np->source.size.x - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->source.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
@@ -687,7 +687,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
}
#if 0
-void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItemMaterial *material,Shader* shader) {
+void RasterizerGLES2::_canvas_item_setup_shader_params(ShaderMaterial *material,Shader* shader) {
if (canvas_shader.bind())
rebind_texpixel_size=true;
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index d3936801dd..4353d82eec 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1283,6 +1283,35 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e) {
}
} break;
+ case VS::INSTANCE_PARTICLES: {
+
+ RasterizerStorageGLES3::Particles *particles = static_cast<RasterizerStorageGLES3::Particles *>(e->owner);
+ RasterizerStorageGLES3::Surface *s = static_cast<RasterizerStorageGLES3::Surface *>(e->geometry);
+
+ glBindVertexArray(s->instancing_array_id); // use the instancing array ID
+ glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]); //modify the buffer
+
+ int stride = sizeof(float) * 4 * 6;
+
+ //transform
+
+ glEnableVertexAttribArray(8); //xform x
+ glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 3);
+ glVertexAttribDivisor(8, 1);
+ glEnableVertexAttribArray(9); //xform y
+ glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 4);
+ glVertexAttribDivisor(9, 1);
+ glEnableVertexAttribArray(10); //xform z
+ glVertexAttribPointer(10, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 5);
+ glVertexAttribDivisor(10, 1);
+ glEnableVertexAttribArray(11); //color
+ glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + 0);
+ glVertexAttribDivisor(11, 1);
+ glEnableVertexAttribArray(12); //custom
+ glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 2);
+ glVertexAttribDivisor(12, 1);
+
+ } break;
}
}
@@ -1451,6 +1480,30 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
restore_tex = false;
}
} break;
+ case VS::INSTANCE_PARTICLES: {
+
+ RasterizerStorageGLES3::Particles *particles = static_cast<RasterizerStorageGLES3::Particles *>(e->owner);
+ RasterizerStorageGLES3::Surface *s = static_cast<RasterizerStorageGLES3::Surface *>(e->geometry);
+
+ if (!particles->use_local_coords) //not using local coordinates? then clear transform..
+ state.scene_shader.set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, Transform());
+
+ int amount = particles->amount;
+
+ if (s->index_array_len > 0) {
+
+ glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount);
+
+ storage->info.render_vertices_count += s->index_array_len * amount;
+
+ } else {
+
+ glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, amount);
+
+ storage->info.render_vertices_count += s->array_len * amount;
+ }
+
+ } break;
}
}
@@ -1556,61 +1609,6 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform
}
}
-void RasterizerSceneGLES3::_setup_transform(InstanceBase *p_instance, const Transform &p_view_transform, const CameraMatrix &p_projection) {
-
- if (p_instance->billboard || p_instance->billboard_y || p_instance->depth_scale) {
-
- Transform xf = p_instance->transform;
- if (p_instance->depth_scale) {
-
- if (p_projection.matrix[3][3]) {
- //orthogonal matrix, try to do about the same
- //with viewport size
- //real_t w = Math::abs( 1.0/(2.0*(p_projection.matrix[0][0])) );
- real_t h = Math::abs(1.0 / (2.0 * p_projection.matrix[1][1]));
- float sc = (h * 2.0); //consistent with Y-fov
- xf.basis.scale(Vector3(sc, sc, sc));
- } else {
- //just scale by depth
- real_t sc = Plane(p_view_transform.origin, -p_view_transform.get_basis().get_axis(2)).distance_to(xf.origin);
- xf.basis.scale(Vector3(sc, sc, sc));
- }
- }
-
- if (p_instance->billboard && storage->frame.current_rt) {
-
- Vector3 scale = xf.basis.get_scale();
-
- if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) {
- xf.set_look_at(xf.origin, xf.origin + p_view_transform.get_basis().get_axis(2), -p_view_transform.get_basis().get_axis(1));
- } else {
- xf.set_look_at(xf.origin, xf.origin + p_view_transform.get_basis().get_axis(2), p_view_transform.get_basis().get_axis(1));
- }
-
- xf.basis.scale(scale);
- }
-
- if (p_instance->billboard_y && storage->frame.current_rt) {
-
- Vector3 scale = xf.basis.get_scale();
- Vector3 look_at = p_view_transform.get_origin();
- look_at.y = 0.0;
- Vector3 look_at_norm = look_at.normalized();
-
- if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) {
- xf.set_look_at(xf.origin, xf.origin + look_at_norm, Vector3(0.0, -1.0, 0.0));
- } else {
- xf.set_look_at(xf.origin, xf.origin + look_at_norm, Vector3(0.0, 1.0, 0.0));
- }
- xf.basis.scale(scale);
- }
- state.scene_shader.set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, xf);
-
- } else {
- state.scene_shader.set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, p_instance->transform);
- }
-}
-
void RasterizerSceneGLES3::_set_cull(bool p_front, bool p_reverse_cull) {
bool front = p_front;
@@ -1677,6 +1675,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS, true); //by default unshaded (easier to set)
bool first = true;
+ bool prev_use_instancing = false;
storage->info.render_object_count += p_element_count;
@@ -1804,10 +1803,10 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
}
}
+ bool use_instancing = e->instance->base_type == VS::INSTANCE_MULTIMESH || e->instance->base_type == VS::INSTANCE_PARTICLES;
-
- if ((prev_base_type == VS::INSTANCE_MULTIMESH) != (e->instance->base_type == VS::INSTANCE_MULTIMESH)) {
- state.scene_shader.set_conditional(SceneShaderGLES3::USE_INSTANCING, e->instance->base_type == VS::INSTANCE_MULTIMESH);
+ if (use_instancing != prev_use_instancing) {
+ state.scene_shader.set_conditional(SceneShaderGLES3::USE_INSTANCING, use_instancing);
rebind = true;
}
@@ -1820,7 +1819,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
if (skeleton.is_valid()) {
RasterizerStorageGLES3::Skeleton *sk = storage->skeleton_owner.getornull(skeleton);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 6);
- glBindTexture(GL_TEXTURE_2D,sk->texture);
+ glBindTexture(GL_TEXTURE_2D, sk->texture);
}
}
@@ -1835,8 +1834,6 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
}
}
-
-
if (!(e->sort_key & RenderList::SORT_KEY_UNSHADED_FLAG) && !p_directional_add && !p_shadow) {
_setup_light(e, p_view_transform);
}
@@ -1850,8 +1847,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
_set_cull(e->sort_key & RenderList::SORT_KEY_MIRROR_FLAG, p_reverse_cull);
state.scene_shader.set_uniform(SceneShaderGLES3::NORMAL_MULT, e->instance->mirror ? -1.0 : 1.0);
-
- _setup_transform(e->instance, p_view_transform, p_projection);
+ state.scene_shader.set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, e->instance->transform);
_render_geometry(e);
@@ -1861,6 +1857,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
prev_owner = e->owner;
prev_shading = shading;
prev_skeleton = skeleton;
+ prev_use_instancing = use_instancing;
first = false;
}
@@ -1930,7 +1927,7 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
if (has_blend_alpha || (has_base_alpha && m->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))
return; //bye
- if (!m->shader->spatial.uses_vertex && !m->shader->spatial.uses_discard && m->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
+ if (!m->shader->spatial.writes_modelview_or_projection && !m->shader->spatial.uses_vertex && !m->shader->spatial.uses_discard && m->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
//shader does not use discard and does not write a vertex position, use generic material
if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED)
m = storage->material_owner.getptr(default_material_twosided);
@@ -2730,6 +2727,30 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
case VS::INSTANCE_IMMEDIATE: {
} break;
+ case VS::INSTANCE_PARTICLES: {
+
+ RasterizerStorageGLES3::Particles *particles = storage->particles_owner.getptr(inst->base);
+ ERR_CONTINUE(!particles);
+
+ for (int i = 0; i < particles->draw_passes.size(); i++) {
+
+ RID pmesh = particles->draw_passes[i];
+ if (!pmesh.is_valid())
+ continue;
+ RasterizerStorageGLES3::Mesh *mesh = storage->mesh_owner.get(pmesh);
+ if (!mesh)
+ continue; //mesh not assigned
+
+ int ssize = mesh->surfaces.size();
+
+ for (int j = 0; j < ssize; j++) {
+
+ RasterizerStorageGLES3::Surface *s = mesh->surfaces[j];
+ _add_geometry(s, inst, particles, -1, p_shadow);
+ }
+ }
+
+ } break;
}
}
}
@@ -4419,13 +4440,14 @@ void RasterizerSceneGLES3::initialize() {
state.scene_shader.init();
- default_shader = storage->shader_create(VS::SHADER_SPATIAL);
+ default_shader = storage->shader_create();
+ storage->shader_set_code(default_shader, "shader_type spatial;\n");
default_material = storage->material_create();
storage->material_set_shader(default_material, default_shader);
- default_shader_twosided = storage->shader_create(VS::SHADER_SPATIAL);
+ default_shader_twosided = storage->shader_create();
default_material_twosided = storage->material_create();
- storage->shader_set_code(default_shader_twosided, "render_mode cull_disabled;\n");
+ storage->shader_set_code(default_shader_twosided, "shader_type spatial; render_mode cull_disabled;\n");
storage->material_set_shader(default_material_twosided, default_shader_twosided);
glGenBuffers(1, &state.scene_ubo);
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index b27bce726f..68da532824 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -691,7 +691,6 @@ public:
_FORCE_INLINE_ void _set_cull(bool p_front, bool p_reverse_cull);
_FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES3::Material *p_material, bool p_alpha_pass);
- _FORCE_INLINE_ void _setup_transform(InstanceBase *p_instance, const Transform &p_view_transform, const CameraMatrix &p_projection);
_FORCE_INLINE_ void _setup_geometry(RenderList::Element *e);
_FORCE_INLINE_ void _render_geometry(RenderList::Element *e);
_FORCE_INLINE_ void _setup_light(RenderList::Element *e, const Transform &p_view_transform);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 4fcd09ed58..d6c8b3b35b 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1338,12 +1338,12 @@ void RasterizerStorageGLES3::skybox_set_texture(RID p_skybox, RID p_cube_map, in
/* SHADER API */
-RID RasterizerStorageGLES3::shader_create(VS::ShaderMode p_mode) {
+RID RasterizerStorageGLES3::shader_create() {
Shader *shader = memnew(Shader);
- shader->mode = p_mode;
+ shader->mode = VS::SHADER_SPATIAL;
+ shader->shader = &scene->state.scene_shader;
RID rid = shader_owner.make_rid(shader);
- shader_set_mode(rid, p_mode);
_shader_make_dirty(shader);
shader->self = rid;
@@ -1358,22 +1358,30 @@ void RasterizerStorageGLES3::_shader_make_dirty(Shader *p_shader) {
_shader_dirty_list.add(&p_shader->dirty_list);
}
-void RasterizerStorageGLES3::shader_set_mode(RID p_shader, VS::ShaderMode p_mode) {
+void RasterizerStorageGLES3::shader_set_code(RID p_shader, const String &p_code) {
- ERR_FAIL_INDEX(p_mode, VS::SHADER_MAX);
Shader *shader = shader_owner.get(p_shader);
ERR_FAIL_COND(!shader);
- if (shader->custom_code_id && p_mode == shader->mode)
- return;
+ shader->code = p_code;
+
+ String mode_string = ShaderLanguage::get_shader_type(p_code);
+ VS::ShaderMode mode;
- if (shader->custom_code_id) {
+ if (mode_string == "canvas_item")
+ mode = VS::SHADER_CANVAS_ITEM;
+ else if (mode_string == "particles")
+ mode = VS::SHADER_PARTICLES;
+ else
+ mode = VS::SHADER_SPATIAL;
+
+ if (shader->custom_code_id && mode != shader->mode) {
shader->shader->free_custom_shader(shader->custom_code_id);
shader->custom_code_id = 0;
}
- shader->mode = p_mode;
+ shader->mode = mode;
ShaderGLES3 *shaders[VS::SHADER_MAX] = {
&scene->state.scene_shader,
@@ -1382,25 +1390,12 @@ void RasterizerStorageGLES3::shader_set_mode(RID p_shader, VS::ShaderMode p_mode
};
- shader->shader = shaders[p_mode];
-
- shader->custom_code_id = shader->shader->create_custom_shader();
-
- _shader_make_dirty(shader);
-}
-VS::ShaderMode RasterizerStorageGLES3::shader_get_mode(RID p_shader) const {
-
- const Shader *shader = shader_owner.get(p_shader);
- ERR_FAIL_COND_V(!shader, VS::SHADER_MAX);
-
- return shader->mode;
-}
-void RasterizerStorageGLES3::shader_set_code(RID p_shader, const String &p_code) {
+ shader->shader = shaders[mode];
- Shader *shader = shader_owner.get(p_shader);
- ERR_FAIL_COND(!shader);
+ if (shader->custom_code_id == 0) {
+ shader->custom_code_id = shader->shader->create_custom_shader();
+ }
- shader->code = p_code;
_shader_make_dirty(shader);
}
String RasterizerStorageGLES3::shader_get_code(RID p_shader) const {
@@ -1453,6 +1448,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->spatial.ontop = false;
p_shader->spatial.uses_sss = false;
p_shader->spatial.uses_vertex = false;
+ p_shader->spatial.writes_modelview_or_projection = false;
shaders.actions_scene.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_ADD);
shaders.actions_scene.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_MIX);
@@ -1477,6 +1473,9 @@ 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.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;
+
actions = &shaders.actions_scene;
actions->uniforms = &p_shader->uniforms;
@@ -4861,6 +4860,8 @@ void RasterizerStorageGLES3::particles_set_amount(RID p_particles, int p_amount)
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
+ particles->amount = p_amount;
+
int floats = p_amount * 24;
float *data = memnew_arr(float, floats);
@@ -4868,17 +4869,25 @@ void RasterizerStorageGLES3::particles_set_amount(RID p_particles, int p_amount)
data[i] = 0;
}
- glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]);
- glBufferData(GL_ARRAY_BUFFER, floats * sizeof(float), data, GL_DYNAMIC_DRAW);
+ for (int i = 0; i < 2; i++) {
- glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[1]);
- glBufferData(GL_ARRAY_BUFFER, floats * sizeof(float), data, GL_DYNAMIC_DRAW);
+ glBindVertexArray(particles->particle_vaos[i]);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[i]);
+ glBufferData(GL_ARRAY_BUFFER, floats * sizeof(float), data, GL_DYNAMIC_DRAW);
+
+ for (int i = 0; i < 6; i++) {
+ glEnableVertexAttribArray(i);
+ glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4 * 6, ((uint8_t *)0) + (i * 16));
+ }
+ }
+
+ glBindVertexArray(0);
particles->prev_ticks = 0;
particles->phase = 0;
particles->prev_phase = 0;
+ particles->clear = true;
memdelete_arr(data);
}
@@ -4927,41 +4936,29 @@ void RasterizerStorageGLES3::particles_set_use_local_coordinates(RID p_particles
particles->use_local_coords = p_enable;
}
-void RasterizerStorageGLES3::particles_set_process_material(RID p_particles, RID p_material) {
-
- Particles *particles = particles_owner.getornull(p_particles);
- ERR_FAIL_COND(!particles);
- particles->process_material = p_material;
-}
-
-void RasterizerStorageGLES3::particles_set_emission_shape(RID p_particles, VS::ParticlesEmissionShape p_shape) {
+void RasterizerStorageGLES3::particles_set_fixed_fps(RID p_particles, int p_fps) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
- particles->emission_shape = p_shape;
+ particles->fixed_fps = p_fps;
}
-void RasterizerStorageGLES3::particles_set_emission_sphere_radius(RID p_particles, float p_radius) {
- Particles *particles = particles_owner.getornull(p_particles);
- ERR_FAIL_COND(!particles);
-
- particles->emission_sphere_radius = p_radius;
-}
-void RasterizerStorageGLES3::particles_set_emission_box_extents(RID p_particles, const Vector3 &p_extents) {
+void RasterizerStorageGLES3::particles_set_fractional_delta(RID p_particles, bool p_enable) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
- particles->emission_box_extents = p_extents;
+ particles->fractional_delta = p_enable;
}
-void RasterizerStorageGLES3::particles_set_emission_points(RID p_particles, const PoolVector<Vector3> &p_points) {
+
+void RasterizerStorageGLES3::particles_set_process_material(RID p_particles, RID p_material) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
- particles->emission_points = p_points;
+ particles->process_material = p_material;
}
void RasterizerStorageGLES3::particles_set_draw_order(RID p_particles, VS::ParticlesDrawOrder p_order) {
@@ -4972,26 +4969,30 @@ void RasterizerStorageGLES3::particles_set_draw_order(RID p_particles, VS::Parti
particles->draw_order = p_order;
}
-void RasterizerStorageGLES3::particles_set_draw_passes(RID p_particles, int p_count) {
+void RasterizerStorageGLES3::particles_set_draw_passes(RID p_particles, int p_passes) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
- particles->draw_passes.resize(p_count);
+ particles->draw_passes.resize(p_passes);
}
-void RasterizerStorageGLES3::particles_set_draw_pass_material(RID p_particles, int p_pass, RID p_material) {
+
+void RasterizerStorageGLES3::particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
ERR_FAIL_INDEX(p_pass, particles->draw_passes.size());
- particles->draw_passes[p_pass].material = p_material;
+ particles->draw_passes[p_pass] = p_mesh;
}
-void RasterizerStorageGLES3::particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) {
+
+void RasterizerStorageGLES3::particles_request_process(RID p_particles) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
- ERR_FAIL_INDEX(p_pass, particles->draw_passes.size());
- particles->draw_passes[p_pass].mesh = p_mesh;
+
+ if (!particles->particle_element.in_list()) {
+ particle_update_list.add(&particles->particle_element);
+ }
}
Rect3 RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
@@ -5002,10 +5003,86 @@ Rect3 RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
return particles->computed_aabb;
}
+Rect3 RasterizerStorageGLES3::particles_get_aabb(RID p_particles) const {
+
+ const Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, Rect3());
+
+ return Rect3(Vector3(-1, -1, -1), Vector3(2, 2, 2));
+}
+
+void RasterizerStorageGLES3::particles_set_emission_transform(RID p_particles, const Transform &p_transform) {
+
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ particles->emission_transform = p_transform;
+}
+
+void RasterizerStorageGLES3::_particles_process(Particles *particles, float p_delta) {
+
+ float new_phase = Math::fmod((float)particles->phase + (p_delta / particles->lifetime), (float)1.0);
+
+ if (particles->clear) {
+ particles->cycle_number = 0;
+ } else if (new_phase < particles->phase) {
+ particles->cycle_number++;
+ }
+
+ shaders.particles.set_uniform(ParticlesShaderGLES3::SYSTEM_PHASE, new_phase);
+ shaders.particles.set_uniform(ParticlesShaderGLES3::PREV_SYSTEM_PHASE, particles->phase);
+ particles->phase = new_phase;
+
+ shaders.particles.set_uniform(ParticlesShaderGLES3::DELTA, p_delta);
+ shaders.particles.set_uniform(ParticlesShaderGLES3::CLEAR, particles->clear);
+ if (particles->use_local_coords)
+ shaders.particles.set_uniform(ParticlesShaderGLES3::EMISSION_TRANSFORM, Transform());
+ else
+ shaders.particles.set_uniform(ParticlesShaderGLES3::EMISSION_TRANSFORM, particles->emission_transform);
+
+ glUniform1ui(shaders.particles.get_uniform(ParticlesShaderGLES3::CYCLE), particles->cycle_number);
+
+ particles->clear = false;
+
+ glBindVertexArray(particles->particle_vaos[0]);
+
+ glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, particles->particle_buffers[1]);
+
+ // GLint size = 0;
+ // glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
+
+ glBeginTransformFeedback(GL_POINTS);
+ glDrawArrays(GL_POINTS, 0, particles->amount);
+ glEndTransformFeedback();
+
+ SWAP(particles->particle_buffers[0], particles->particle_buffers[1]);
+ SWAP(particles->particle_vaos[0], particles->particle_vaos[1]);
+
+ glBindVertexArray(0);
+ /* //debug particles :D
+ glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]);
+
+ float *data = (float *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, GL_MAP_READ_BIT);
+ for (int i = 0; i < particles->amount; i++) {
+ int ofs = i * 24;
+ print_line(itos(i) + ":");
+ print_line("\tColor: " + Color(data[ofs + 0], data[ofs + 1], data[ofs + 2], data[ofs + 3]));
+ print_line("\tVelocity: " + Vector3(data[ofs + 4], data[ofs + 5], data[ofs + 6]));
+ print_line("\tActive: " + itos(data[ofs + 7]));
+ print_line("\tCustom: " + Color(data[ofs + 8], data[ofs + 9], data[ofs + 10], data[ofs + 11]));
+ print_line("\tXF X: " + Color(data[ofs + 12], data[ofs + 13], data[ofs + 14], data[ofs + 15]));
+ print_line("\tXF Y: " + Color(data[ofs + 16], data[ofs + 17], data[ofs + 18], data[ofs + 19]));
+ print_line("\tXF Z: " + Color(data[ofs + 20], data[ofs + 21], data[ofs + 22], data[ofs + 23]));
+ }
+
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ //*/
+}
+
void RasterizerStorageGLES3::update_particles() {
glEnable(GL_RASTERIZER_DISCARD);
- glBindVertexArray(0);
while (particle_update_list.first()) {
@@ -5068,38 +5145,61 @@ void RasterizerStorageGLES3::update_particles() {
}
}
- shaders.particles.bind();
-
- shaders.particles.set_uniform(ParticlesShaderGLES3::ORIGIN, particles->origin);
-
- float new_phase = Math::fmod((float)particles->phase + (frame.delta / particles->lifetime), (float)1.0);
+ shaders.particles.set_conditional(ParticlesShaderGLES3::USE_FRACTIONAL_DELTA, particles->fractional_delta);
- shaders.particles.set_uniform(ParticlesShaderGLES3::SYSTEM_PHASE, new_phase);
- shaders.particles.set_uniform(ParticlesShaderGLES3::PREV_SYSTEM_PHASE, particles->phase);
- particles->phase = new_phase;
+ shaders.particles.bind();
shaders.particles.set_uniform(ParticlesShaderGLES3::TOTAL_PARTICLES, particles->amount);
- shaders.particles.set_uniform(ParticlesShaderGLES3::TIME, 0.0);
+ shaders.particles.set_uniform(ParticlesShaderGLES3::TIME, Color(frame.time[0], frame.time[1], frame.time[2], frame.time[3]));
shaders.particles.set_uniform(ParticlesShaderGLES3::EXPLOSIVENESS, particles->explosiveness);
- shaders.particles.set_uniform(ParticlesShaderGLES3::DELTA, frame.delta);
+ shaders.particles.set_uniform(ParticlesShaderGLES3::LIFETIME, particles->lifetime);
shaders.particles.set_uniform(ParticlesShaderGLES3::GRAVITY, particles->gravity);
shaders.particles.set_uniform(ParticlesShaderGLES3::ATTRACTOR_COUNT, 0);
+ shaders.particles.set_uniform(ParticlesShaderGLES3::EMITTING, particles->emitting);
+ shaders.particles.set_uniform(ParticlesShaderGLES3::RANDOMNESS, particles->randomness);
- glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]);
- glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, particles->particle_buffers[1]);
+ if (particles->clear && particles->pre_process_time > 0.0) {
- for (int i = 0; i < 6; i++) {
- glEnableVertexAttribArray(i);
- glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4 * 6, ((uint8_t *)0) + (i * 16));
+ float frame_time;
+ if (particles->fixed_fps > 0)
+ frame_time = 1.0 / particles->fixed_fps;
+ else
+ frame_time = 1.0 / 30.0;
+
+ float delta = particles->pre_process_time;
+ if (delta > 0.1) { //avoid recursive stalls if fps goes below 10
+ delta = 0.1;
+ }
+ float todo = delta;
+
+ while (todo >= frame_time) {
+ _particles_process(particles, frame_time);
+ todo -= frame_time;
+ }
}
- glBeginTransformFeedback(GL_POINTS);
- glDrawArrays(GL_POINTS, 0, particles->amount);
- glEndTransformFeedback();
+ if (particles->fixed_fps > 0) {
+ float frame_time = 1.0 / particles->fixed_fps;
+ float delta = frame.delta;
+ if (delta > 0.1) { //avoid recursive stalls if fps goes below 10
+ delta = 0.1;
+ } else if (delta <= 0.0) { //unlikely but..
+ delta = 0.001;
+ }
+ float todo = particles->frame_remainder + delta;
- particle_update_list.remove(particle_update_list.first());
+ while (todo >= frame_time) {
+ _particles_process(particles, frame_time);
+ todo -= frame_time;
+ }
+
+ particles->frame_remainder = todo;
+
+ } else {
+ _particles_process(particles, frame.delta);
+ }
- SWAP(particles->particle_buffers[0], particles->particle_buffers[1]);
+ particle_update_list.remove(particle_update_list.first());
}
glDisable(GL_RASTERIZER_DISCARD);
@@ -5143,6 +5243,10 @@ void RasterizerStorageGLES3::instance_add_dependency(RID p_base, RasterizerScene
inst = immediate_owner.getornull(p_base);
ERR_FAIL_COND(!inst);
} break;
+ case VS::INSTANCE_PARTICLES: {
+ inst = particles_owner.getornull(p_base);
+ ERR_FAIL_COND(!inst);
+ } break;
case VS::INSTANCE_REFLECTION_PROBE: {
inst = reflection_probe_owner.getornull(p_base);
ERR_FAIL_COND(!inst);
@@ -5182,6 +5286,10 @@ void RasterizerStorageGLES3::instance_remove_dependency(RID p_base, RasterizerSc
inst = immediate_owner.getornull(p_base);
ERR_FAIL_COND(!inst);
} break;
+ case VS::INSTANCE_PARTICLES: {
+ inst = particles_owner.getornull(p_base);
+ ERR_FAIL_COND(!inst);
+ } break;
case VS::INSTANCE_REFLECTION_PROBE: {
inst = reflection_probe_owner.getornull(p_base);
ERR_FAIL_COND(!inst);
@@ -5856,6 +5964,10 @@ VS::InstanceType RasterizerStorageGLES3::get_base_type(RID p_rid) const {
return VS::INSTANCE_IMMEDIATE;
}
+ if (particles_owner.owns(p_rid)) {
+ return VS::INSTANCE_PARTICLES;
+ }
+
if (light_owner.owns(p_rid)) {
return VS::INSTANCE_LIGHT;
}
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 50617b8124..e376c2c0bb 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -408,6 +408,7 @@ public:
bool uses_vertex;
bool uses_discard;
bool uses_sss;
+ bool writes_modelview_or_projection;
} spatial;
@@ -433,10 +434,7 @@ public:
mutable RID_Owner<Shader> shader_owner;
- virtual RID shader_create(VS::ShaderMode p_mode = VS::SHADER_SPATIAL);
-
- virtual void shader_set_mode(RID p_shader, VS::ShaderMode p_mode);
- virtual VS::ShaderMode shader_get_mode(RID p_shader) const;
+ virtual RID shader_create();
virtual void shader_set_code(RID p_shader, const String &p_code);
virtual String shader_get_code(RID p_shader) const;
@@ -778,7 +776,7 @@ public:
Skeleton()
: update_list(this) {
- size=0;
+ size = 0;
use_2d = false;
texture = 0;
@@ -987,7 +985,7 @@ public:
/* PARTICLES */
- struct Particles : public Instantiable {
+ struct Particles : public GeometryOwner {
bool emitting;
int amount;
@@ -1000,23 +998,14 @@ public:
bool use_local_coords;
RID process_material;
- VS::ParticlesEmissionShape emission_shape;
- float emission_sphere_radius;
- Vector3 emission_box_extents;
- PoolVector<Vector3> emission_points;
- GLuint emission_point_texture;
-
VS::ParticlesDrawOrder draw_order;
- struct DrawPass {
- RID mesh;
- RID material;
- };
- Vector<DrawPass> draw_passes;
+ Vector<RID> draw_passes;
Rect3 computed_aabb;
GLuint particle_buffers[2];
+ GLuint particle_vaos[2];
SelfList<Particles> particle_element;
@@ -1024,10 +1013,19 @@ public:
float prev_phase;
uint64_t prev_ticks;
- Transform origin;
+ uint32_t cycle_number;
+
+ int fixed_fps = 0;
+ bool fractional_delta;
+ float frame_remainder;
+
+ bool clear;
+
+ Transform emission_transform;
Particles()
: particle_element(this) {
+ cycle_number = 0;
emitting = false;
amount = 0;
lifetime = 1.0;
@@ -1035,23 +1033,26 @@ public:
explosiveness = 0.0;
randomness = 0.0;
use_local_coords = true;
+ fixed_fps = 0;
+ fractional_delta = false;
+ frame_remainder = 0;
draw_order = VS::PARTICLES_DRAW_ORDER_INDEX;
- emission_shape = VS::PARTICLES_EMSSION_POINT;
- emission_sphere_radius = 1.0;
- emission_box_extents = Vector3(1, 1, 1);
- emission_point_texture = 0;
particle_buffers[0] = 0;
particle_buffers[1] = 0;
prev_ticks = 0;
+ clear = true;
+
glGenBuffers(2, particle_buffers);
+ glGenVertexArrays(2, particle_vaos);
}
~Particles() {
glDeleteBuffers(2, particle_buffers);
+ glDeleteVertexArrays(2, particle_vaos);
}
};
@@ -1073,19 +1074,20 @@ public:
virtual void particles_set_gravity(RID p_particles, const Vector3 &p_gravity);
virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable);
virtual void particles_set_process_material(RID p_particles, RID p_material);
-
- virtual void particles_set_emission_shape(RID p_particles, VS::ParticlesEmissionShape p_shape);
- virtual void particles_set_emission_sphere_radius(RID p_particles, float p_radius);
- virtual void particles_set_emission_box_extents(RID p_particles, const Vector3 &p_extents);
- virtual void particles_set_emission_points(RID p_particles, const PoolVector<Vector3> &p_points);
+ virtual void particles_set_fixed_fps(RID p_particles, int p_fps);
+ virtual void particles_set_fractional_delta(RID p_particles, bool p_enable);
virtual void particles_set_draw_order(RID p_particles, VS::ParticlesDrawOrder p_order);
virtual void particles_set_draw_passes(RID p_particles, int p_count);
- virtual void particles_set_draw_pass_material(RID p_particles, int p_pass, RID p_material);
virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh);
+ virtual void particles_request_process(RID p_particles);
virtual Rect3 particles_get_current_aabb(RID p_particles);
+ virtual Rect3 particles_get_aabb(RID p_particles) const;
+
+ virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform);
+ void _particles_process(Particles *p_particles, float p_delta);
/* INSTANCE */
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 48ca86ebe2..b9d50caa10 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -91,6 +91,16 @@ static String _prestr(SL::DataPrecision p_pres) {
return "";
}
+static String _qualstr(SL::ArgumentQualifier p_qual) {
+
+ switch (p_qual) {
+ case SL::ARGUMENT_QUALIFIER_IN: return "";
+ case SL::ARGUMENT_QUALIFIER_OUT: return "out ";
+ case SL::ARGUMENT_QUALIFIER_INOUT: return "inout ";
+ }
+ return "";
+}
+
static String _opstr(SL::Operator p_op) {
return SL::get_operator_text(p_op);
@@ -175,6 +185,21 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
return text;
} break;
+ case SL::TYPE_MAT2:
+ case SL::TYPE_MAT3:
+ case SL::TYPE_MAT4: {
+
+ String text = "mat" + itos(p_type - SL::TYPE_MAT2 + 2) + "(";
+ for (int i = 0; i < p_values.size(); i++) {
+ if (i > 0)
+ text += ",";
+
+ text += f2sp0(p_values[i].real);
+ }
+ text += ")";
+ return text;
+
+ } break;
default: ERR_FAIL_V(String());
}
}
@@ -194,6 +219,7 @@ void ShaderCompilerGLES3::_dump_function_deps(SL::ShaderNode *p_node, const Stri
for (Set<StringName>::Element *E = p_node->functions[fidx].uses_function.front(); E; E = E->next()) {
+ print_line(String(p_node->functions[fidx].name) + " uses function: " + String(E->get()));
if (added.has(E->get())) {
continue; //was added already
}
@@ -219,7 +245,7 @@ void ShaderCompilerGLES3::_dump_function_deps(SL::ShaderNode *p_node, const Stri
if (i > 0)
header += ", ";
- header += _prestr(fnode->arguments[i].precision) + _typestr(fnode->arguments[i].type) + " " + _mkid(fnode->arguments[i].name);
+ header += _qualstr(fnode->arguments[i].qualifier) + _prestr(fnode->arguments[i].precision) + _typestr(fnode->arguments[i].type) + " " + _mkid(fnode->arguments[i].name);
}
header += ")\n";
@@ -383,6 +409,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
if (fnode->name == "vertex") {
+ print_line("vertex uses functions: " + itos(pnode->functions[i].uses_function.size()));
_dump_function_deps(pnode, fnode->name, function_code, r_gen_code.vertex_global, added_vtx);
r_gen_code.vertex = function_code["vertex"];
}
@@ -482,6 +509,12 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
case SL::OP_ASSIGN_BIT_AND:
case SL::OP_ASSIGN_BIT_OR:
case SL::OP_ASSIGN_BIT_XOR:
+ if (onode->arguments[0]->type == SL::Node::TYPE_VARIABLE) {
+ SL::VariableNode *vnode = (SL::VariableNode *)onode->arguments[0];
+ if (p_actions.write_flag_pointers.has(vnode->name)) {
+ *p_actions.write_flag_pointers[vnode->name] = true;
+ }
+ }
code = _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions);
break;
case SL::OP_BIT_INVERT:
@@ -524,6 +557,23 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
}
code += ")";
} break;
+ case SL::OP_INDEX: {
+
+ code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions);
+ code += "[";
+ code += _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions);
+ code += "]";
+
+ } break;
+ case SL::OP_SELECT_IF: {
+
+ code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions);
+ code += "?";
+ code += _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions);
+ code += ":";
+ code += _dump_node_code(onode->arguments[2], p_level, r_gen_code, p_actions, p_default_actions);
+
+ } break;
default: {
code = "(" + _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions) + ")";
@@ -546,10 +596,10 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
} else if (cfnode->flow_op == SL::FLOW_OP_RETURN) {
- if (cfnode->blocks.size()) {
- code = "return " + _dump_node_code(cfnode->blocks[0], p_level, r_gen_code, p_actions, p_default_actions);
+ if (cfnode->expressions.size()) {
+ code = "return " + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions) + ";";
} else {
- code = "return";
+ code = "return;";
}
}
@@ -566,7 +616,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {
- Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode));
+ Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_types());
if (err != OK) {
#if 1
@@ -648,7 +698,9 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["WORLD_MATRIX"] = "world_transform";
actions[VS::SHADER_SPATIAL].renames["INV_CAMERA_MATRIX"] = "camera_inverse_matrix";
+ actions[VS::SHADER_SPATIAL].renames["CAMERA_MATRIX"] = "camera_matrix";
actions[VS::SHADER_SPATIAL].renames["PROJECTION_MATRIX"] = "projection_matrix";
+ actions[VS::SHADER_SPATIAL].renames["MODELVIEW_MATRIX"] = "modelview";
actions[VS::SHADER_SPATIAL].renames["VERTEX"] = "vertex.xyz";
actions[VS::SHADER_SPATIAL].renames["NORMAL"] = "normal";
@@ -686,6 +738,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["DISCARD"] = "_discard";
//actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"]=ShaderLanguage::TYPE_VEC2;
actions[VS::SHADER_SPATIAL].renames["POINT_COORD"] = "gl_PointCoord";
+ actions[VS::SHADER_SPATIAL].renames["INSTANCE_CUSTOM"] = "instance_custom";
actions[VS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["BINORMAL"] = "@TANGENT";
@@ -701,16 +754,17 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP"] = "#define ENABLE_NORMALMAP\n";
actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP";
actions[VS::SHADER_SPATIAL].usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS_MOTION\n";
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength";
- actions[VS::SHADER_SPATIAL].render_mode_defines["skip_transform"] = "#define SKIP_TRANSFORM_USED\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["skip_default_transform"] = "#define SKIP_TRANSFORM_USED\n";
/* PARTICLES SHADER */
- actions[VS::SHADER_PARTICLES].renames["COLOR"] = "color";
+ actions[VS::SHADER_PARTICLES].renames["COLOR"] = "out_color";
actions[VS::SHADER_PARTICLES].renames["VELOCITY"] = "out_velocity_active.xyz";
actions[VS::SHADER_PARTICLES].renames["MASS"] = "mass";
actions[VS::SHADER_PARTICLES].renames["ACTIVE"] = "active";
@@ -719,13 +773,15 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_PARTICLES].renames["TRANSFORM"] = "xform";
actions[VS::SHADER_PARTICLES].renames["TIME"] = "time";
actions[VS::SHADER_PARTICLES].renames["LIFETIME"] = "lifetime";
- actions[VS::SHADER_PARTICLES].renames["DELTA"] = "delta";
- actions[VS::SHADER_PARTICLES].renames["SEED"] = "seed";
- actions[VS::SHADER_PARTICLES].renames["ORIGIN"] = "origin";
+ actions[VS::SHADER_PARTICLES].renames["DELTA"] = "local_delta";
+ actions[VS::SHADER_PARTICLES].renames["NUMBER"] = "particle_number";
actions[VS::SHADER_PARTICLES].renames["INDEX"] = "index";
+ actions[VS::SHADER_PARTICLES].renames["GRAVITY"] = "current_gravity";
+ actions[VS::SHADER_PARTICLES].renames["EMISSION_TRANSFORM"] = "emission_transform";
actions[VS::SHADER_SPATIAL].render_mode_defines["disable_force"] = "#define DISABLE_FORCE\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["disable_velocity"] = "#define DISABLE_VELOCITY\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["keep_data"] = "#define ENABLE_KEEP_DATA\n";
vertex_name = "vertex";
fragment_name = "fragment";
diff --git a/drivers/gles3/shader_compiler_gles3.h b/drivers/gles3/shader_compiler_gles3.h
index 44d6b3a349..17e0eee157 100644
--- a/drivers/gles3/shader_compiler_gles3.h
+++ b/drivers/gles3/shader_compiler_gles3.h
@@ -41,6 +41,7 @@ public:
Map<StringName, Pair<int *, int> > render_mode_values;
Map<StringName, bool *> render_mode_flags;
Map<StringName, bool *> usage_flag_pointers;
+ Map<StringName, bool *> write_flag_pointers;
Map<StringName, ShaderLanguage::ShaderNode::Uniform> *uniforms;
};
diff --git a/drivers/gles3/shaders/particles.glsl b/drivers/gles3/shaders/particles.glsl
index e72f12cc5e..347b15d639 100644
--- a/drivers/gles3/shaders/particles.glsl
+++ b/drivers/gles3/shaders/particles.glsl
@@ -22,16 +22,21 @@ struct Attractor {
#define MAX_ATTRACTORS 64
-uniform mat4 origin;
+uniform bool emitting;
uniform float system_phase;
uniform float prev_system_phase;
-uniform float total_particles;
+uniform int total_particles;
uniform float explosiveness;
+uniform float randomness;
uniform vec4 time;
uniform float delta;
uniform vec3 gravity;
uniform int attractor_count;
uniform Attractor attractors[MAX_ATTRACTORS];
+uniform bool clear;
+uniform uint cycle;
+uniform float lifetime;
+uniform mat4 emission_transform;
out highp vec4 out_color; //tfb:
@@ -53,52 +58,116 @@ MATERIAL_UNIFORMS
#endif
+uint hash(uint x) {
+
+ x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b);
+ x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b);
+ x = (x >> uint(16)) ^ x;
+ return x;
+}
+
+
void main() {
bool apply_forces=true;
bool apply_velocity=true;
+ vec3 current_gravity = gravity;
+ float local_delta=delta;
float mass = 1.0;
- float restart_phase = float(gl_InstanceID)/total_particles;
- restart_phase*= explosiveness;
+ float restart_phase = float(gl_VertexID)/float(total_particles);
+
+ if (randomness>0.0) {
+ uint seed = cycle;
+ if (restart_phase >= system_phase) {
+ seed-=uint(1);
+ }
+ seed*=uint(total_particles);
+ seed+=uint(gl_VertexID);
+ float random = float(hash(seed) % uint(65536)) / 65536.0;
+ restart_phase+=randomness * random * 1.0 / float(total_particles);
+ }
+
+ restart_phase*= (1.0-explosiveness);
bool restart=false;
- bool active = out_velocity_active.a > 0.5;
+ bool active = velocity_active.a > 0.5;
if (system_phase > prev_system_phase) {
- restart = prev_system_phase < restart_phase && system_phase >= restart_phase;
+ if (prev_system_phase < restart_phase && system_phase >= restart_phase) {
+ restart=true;
+#ifdef USE_FRACTIONAL_DELTA
+ local_delta = (system_phase - restart_phase) * lifetime;
+#endif
+ }
+
} else {
- restart = prev_system_phase < restart_phase || system_phase >= restart_phase;
+ if (prev_system_phase < restart_phase) {
+ restart=true;
+#ifdef USE_FRACTIONAL_DELTA
+ local_delta = (1.0 - restart_phase + system_phase) * lifetime;
+#endif
+ } else if (system_phase >= restart_phase) {
+ restart=true;
+#ifdef USE_FRACTIONAL_DELTA
+ local_delta = (system_phase - restart_phase) * lifetime;
+#endif
+ }
}
- if (restart) {
- active=true;
+ uint current_cycle = cycle;
+
+ if (system_phase < restart_phase) {
+ current_cycle-=uint(1);
}
- out_color=color;
- out_velocity_active=velocity_active;
- out_custom=custom;
+ uint particle_number = current_cycle * uint(total_particles) + uint(gl_VertexID);
- mat4 xform = transpose(mat4(xform_1,xform_2,xform_3,vec4(vec3(0.0),1.0)));
+ if (restart) {
+ active=emitting;
+ }
+ mat4 xform;
- out_rot_active=rot_active;
+#if defined(ENABLE_KEEP_DATA)
+ if (clear) {
+#else
+ if (clear || restart) {
+#endif
+ out_color=vec4(1.0);
+ out_velocity_active=vec4(0.0);
+ out_custom=vec4(0.0);
+ if (!restart)
+ active=false;
+
+ xform = mat4(
+ vec4(1.0,0.0,0.0,0.0),
+ vec4(0.0,1.0,0.0,0.0),
+ vec4(0.0,0.0,1.0,0.0),
+ vec4(0.0,0.0,0.0,1.0)
+ );
+ } else {
+ out_color=color;
+ out_velocity_active=velocity_active;
+ out_custom=custom;
+ xform = transpose(mat4(xform_1,xform_2,xform_3,vec4(vec3(0.0),1.0)));
+ }
if (active) {
//execute shader
{
- VERTEX_SHADER_CODE
+VERTEX_SHADER_CODE
}
#if !defined(DISABLE_FORCE)
- {
+ if (true) {
- vec3 force = gravity;
+ vec3 force = current_gravity;
for(int i=0;i<attractor_count;i++) {
- vec3 rel_vec = out_pos_lifetime.xyz - attractors[i].pos;
+ vec3 rel_vec = xform[3].xyz - attractors[i].pos;
float dist = rel_vec.length();
if (attractors[i].radius < dist)
continue;
@@ -119,17 +188,19 @@ void main() {
}
}
- out_velocity_seed.xyz += force * delta;
+ out_velocity_active.xyz += force * local_delta;
}
#endif
#if !defined(DISABLE_VELOCITY)
- {
+ if (true) {
- out_pos_lifetime.xyz += out_velocity_seed.xyz * delta;
+ xform[3].xyz += out_velocity_active.xyz * local_delta;
}
#endif
+ } else {
+ xform=mat4(0.0);
}
xform = transpose(xform);
@@ -162,6 +233,6 @@ MATERIAL_UNIFORMS
void main() {
{
- FRAGMENT_SHADER_CODE
+FRAGMENT_SHADER_CODE
}
}
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index ffc41e611b..43a391631f 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -52,6 +52,10 @@ layout(location=9) in highp vec4 instance_xform1;
layout(location=10) in highp vec4 instance_xform2;
layout(location=11) in lowp vec4 instance_color;
+#if defined(ENABLE_INSTANCE_CUSTOM)
+layout(location=12) in highp vec4 instance_custom_data;
+#endif
+
#endif
layout(std140) uniform SceneData { //ubo:0
@@ -157,9 +161,21 @@ out highp vec4 position_interp;
void main() {
highp vec4 vertex = vertex_attrib; // vec4(vertex_attrib.xyz * data_attrib.x,1.0);
- highp mat4 modelview = camera_inverse_matrix * world_transform;
+
+ mat4 world_matrix = world_transform;
+
+
+#ifdef USE_INSTANCING
+
+ {
+ highp mat4 m=mat4(instance_xform0,instance_xform1,instance_xform2,vec4(0.0,0.0,0.0,1.0));
+ world_matrix = world_matrix * transpose(m);
+ }
+#endif
+
vec3 normal = normal_attrib * normal_mult;
+
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
vec3 tangent = tangent_attrib.xyz;
tangent*=normal_mult;
@@ -168,6 +184,10 @@ void main() {
#if defined(ENABLE_COLOR_INTERP)
color_interp = color_attrib;
+#if defined(USE_INSTANCING)
+ color_interp *= instance_color;
+#endif
+
#endif
#ifdef USE_SKELETON
@@ -215,40 +235,12 @@ void main() {
}
#endif
-#ifdef USE_INSTANCING
-
- {
- highp mat3x4 m=mat3x4(instance_xform0,instance_xform1,instance_xform2);
- vertex.xyz = vertex * m;
- normal = vec4(normal,0.0) * m;
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
- tangent.xyz = vec4(tangent.xyz,0.0) * mn;
-#endif
-#if defined(ENABLE_COLOR_INTERP)
- color_interp*=instance_color;
-#endif
- }
-#endif //USE_INSTANCING
-
-#if !defined(SKIP_TRANSFORM_USED)
-
- vertex = modelview * vertex;
- normal = normalize((modelview * vec4(normal,0.0)).xyz);
-#endif
-
-#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
-# if !defined(SKIP_TRANSFORM_USED)
-
- tangent=normalize((modelview * vec4(tangent,0.0)).xyz);
-# endif
vec3 binormal = normalize( cross(normal,tangent) * binormalf );
#endif
-
-
-
#if defined(ENABLE_UV_INTERP)
uv_interp = uv_attrib;
#endif
@@ -257,16 +249,45 @@ void main() {
uv2_interp = uv2_attrib;
#endif
+#if defined(USE_INSTANCING) && defined(ENABLE_INSTANCE_CUSTOM)
+ vec4 instance_custom = instance_custom_data;
+#else
+ vec4 instance_custom = vec4(0.0);
+#endif
+
+ highp mat4 modelview = camera_inverse_matrix * world_matrix;
+ highp mat4 local_projection = projection_matrix;
+
+//defines that make writing custom shaders easier
+#define projection_matrix local_projection
+#define world_transform world_matrix
{
VERTEX_SHADER_CODE
}
+
+
+
+#if !defined(SKIP_TRANSFORM_USED)
+
+ vertex = modelview * vertex;
+ normal = normalize((modelview * vec4(normal,0.0)).xyz);
+#endif
+
+
vertex_interp = vertex.xyz;
normal_interp = normal;
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
+
+#if !defined(SKIP_TRANSFORM_USED)
+
+ tangent = normalize((modelview * vec4(tangent,0.0)).xyz);
+ binormal = normalize((modelview * vec4(binormal,0.0)).xyz);
+
+#endif
tangent_interp = tangent;
binormal_interp = binormal;
#endif
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index e2a544b676..ea765e8f8a 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -54,6 +54,7 @@
#endif
#include "global_config.h"
#include <assert.h>
+#include <dlfcn.h>
#include <errno.h>
#include <poll.h>
#include <signal.h>
@@ -435,6 +436,36 @@ String OS_Unix::get_locale() const {
return locale;
}
+Error OS_Unix::open_dynamic_library(const String p_path, void *&p_library_handle) {
+ p_library_handle = dlopen(p_path.utf8().get_data(), RTLD_NOW);
+ if (!p_library_handle) {
+ ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + dlerror());
+ ERR_FAIL_V(ERR_CANT_OPEN);
+ }
+ return OK;
+}
+
+Error OS_Unix::close_dynamic_library(void *p_library_handle) {
+ if (dlclose(p_library_handle)) {
+ return FAILED;
+ }
+ return OK;
+}
+
+Error OS_Unix::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle) {
+ const char *error;
+ dlerror(); // Clear existing errors
+
+ p_symbol_handle = dlsym(p_library_handle, p_name.utf8().get_data());
+
+ error = dlerror();
+ if (error != NULL) {
+ ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + error);
+ ERR_FAIL_V(ERR_CANT_RESOLVE);
+ }
+ return OK;
+}
+
Error OS_Unix::set_cwd(const String &p_cwd) {
if (chdir(p_cwd.utf8().get_data()) != 0)
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index 3ac4f46109..ff259ab0f0 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -82,6 +82,10 @@ public:
//virtual VideoMode get_video_mode() const;
//virtual void get_fullscreen_mode_list(List<VideoMode> *p_list) const;
+ virtual Error open_dynamic_library(const String p_path, void *&p_library_handle);
+ virtual Error close_dynamic_library(void *p_library_handle);
+ virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle);
+
virtual Error set_cwd(const String &p_cwd);
virtual String get_name();
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index b188a5760b..032e200775 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -789,7 +789,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
} else {
uint64_t import_mt = FileAccess::get_modified_time(path + ".import");
- print_line(itos(import_mt) + " vs " + itos(p_dir->files[i]->import_modified_time));
+ //print_line(itos(import_mt) + " vs " + itos(p_dir->files[i]->import_modified_time));
if (import_mt != p_dir->files[i]->import_modified_time) {
print_line("REIMPORT: import modified changed, reimport");
reimport = true;
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 18c16af5af..72f26a5230 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -73,7 +73,9 @@
#include "plugins/collision_shape_2d_editor_plugin.h"
#include "plugins/color_ramp_editor_plugin.h"
#include "plugins/cube_grid_theme_editor_plugin.h"
+#include "plugins/curve_editor_plugin.h"
#include "plugins/gi_probe_editor_plugin.h"
+#include "plugins/gradient_texture_editor_plugin.h"
#include "plugins/item_list_editor_plugin.h"
#include "plugins/light_occluder_2d_editor_plugin.h"
#include "plugins/line_2d_editor_plugin.h"
@@ -1088,7 +1090,7 @@ void EditorNode::_dialog_action(String p_file) {
GlobalConfig::get_singleton()->set("application/main_scene", p_file);
GlobalConfig::get_singleton()->save();
- //would be nice to show the project manager opened with the hilighted field..
+ //would be nice to show the project manager opened with the highlighted field..
} break;
case FILE_SAVE_OPTIMIZED: {
@@ -5681,7 +5683,7 @@ EditorNode::EditorNode() {
overridden_default_layout = -1;
default_layout.instance();
default_layout->set_value(docks_section, "dock_3", TTR("FileSystem"));
- default_layout->set_value(docks_section, "dock_5", TTR("Scene"));
+ default_layout->set_value(docks_section, "dock_5", TTR("Scene") + "," + TTR("Import"));
default_layout->set_value(docks_section, "dock_6", TTR("Inspector") + "," + TTR("Node"));
for (int i = 0; i < DOCK_SLOT_MAX / 2; i++)
@@ -5909,7 +5911,7 @@ EditorNode::EditorNode() {
//add_editor_plugin( memnew( MeshLibraryEditorPlugin(this) ) );
//add_editor_plugin( memnew( StreamEditorPlugin(this) ) );
add_editor_plugin(memnew(StyleBoxEditorPlugin(this)));
- //add_editor_plugin( memnew( ParticlesEditorPlugin(this) ) );
+ add_editor_plugin(memnew(ParticlesEditorPlugin(this)));
add_editor_plugin(memnew(ResourcePreloaderEditorPlugin(this)));
add_editor_plugin(memnew(ItemListEditorPlugin(this)));
//add_editor_plugin( memnew( RichTextEditorPlugin(this) ) );
@@ -5929,7 +5931,9 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(LightOccluder2DEditorPlugin(this)));
add_editor_plugin(memnew(NavigationPolygonEditorPlugin(this)));
add_editor_plugin(memnew(ColorRampEditorPlugin(this)));
+ add_editor_plugin(memnew(GradientTextureEditorPlugin(this)));
add_editor_plugin(memnew(CollisionShape2DEditorPlugin(this)));
+ add_editor_plugin(memnew(CurveTextureEditorPlugin(this)));
add_editor_plugin(memnew(TextureEditorPlugin(this)));
add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
//add_editor_plugin( memnew( MaterialEditorPlugin(this) ) );
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index fe1f984f39..3e0a2c712a 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1101,7 +1101,7 @@ void FileSystemDock::_dir_rmb_pressed(const Vector2 &p_pos) {
folder_options->add_item(TTR("Expand all"), FOLDER_EXPAND_ALL);
folder_options->add_item(TTR("Collapse all"), FOLDER_COLLAPSE_ALL);
- folder_options->set_pos(files->get_global_pos() + p_pos);
+ folder_options->set_pos(tree->get_global_pos() + p_pos);
folder_options->popup();
}
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index 93614fb511..95baacb9e7 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -364,7 +364,7 @@ Error ColladaImport::_create_material(const String &p_target) {
ERR_FAIL_COND_V(!collada.state.effect_map.has(src_mat.instance_effect), ERR_INVALID_PARAMETER);
Collada::Effect &effect = collada.state.effect_map[src_mat.instance_effect];
- Ref<FixedSpatialMaterial> material = memnew(FixedSpatialMaterial);
+ Ref<SpatialMaterial> material = memnew(SpatialMaterial);
if (src_mat.name != "")
material->set_name(src_mat.name);
@@ -381,15 +381,15 @@ Error ColladaImport::_create_material(const String &p_target) {
Ref<Texture> texture = ResourceLoader::load(texfile, "Texture");
if (texture.is_valid()) {
- material->set_texture(FixedSpatialMaterial::TEXTURE_ALBEDO, texture);
+ material->set_texture(SpatialMaterial::TEXTURE_ALBEDO, texture);
material->set_albedo(Color(1, 1, 1, 1));
- //material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1,1));
+ //material->set_parameter(SpatialMaterial::PARAM_DIFFUSE,Color(1,1,1,1));
} else {
missing_textures.push_back(texfile.get_file());
}
}
} else {
- //material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,effect.diffuse.color);
+ //material->set_parameter(SpatialMaterial::PARAM_DIFFUSE,effect.diffuse.color);
}
// SPECULAR
@@ -401,11 +401,11 @@ Error ColladaImport::_create_material(const String &p_target) {
Ref<Texture> texture = ResourceLoader::load(texfile, "Texture");
if (texture.is_valid()) {
- material->set_texture(FixedSpatialMaterial::TEXTURE_SPECULAR, texture);
+ material->set_texture(SpatialMaterial::TEXTURE_SPECULAR, texture);
material->set_specular(Color(1, 1, 1, 1));
- //material->set_texture(FixedSpatialMaterial::PARAM_SPECULAR,texture);
- //material->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR,Color(1,1,1,1));
+ //material->set_texture(SpatialMaterial::PARAM_SPECULAR,texture);
+ //material->set_parameter(SpatialMaterial::PARAM_SPECULAR,Color(1,1,1,1));
} else {
missing_textures.push_back(texfile.get_file());
}
@@ -424,18 +424,18 @@ Error ColladaImport::_create_material(const String &p_target) {
Ref<Texture> texture = ResourceLoader::load(texfile, "Texture");
if (texture.is_valid()) {
- material->set_feature(FixedSpatialMaterial::FEATURE_EMISSION, true);
- material->set_texture(FixedSpatialMaterial::TEXTURE_EMISSION, texture);
+ material->set_feature(SpatialMaterial::FEATURE_EMISSION, true);
+ material->set_texture(SpatialMaterial::TEXTURE_EMISSION, texture);
material->set_emission(Color(1, 1, 1, 1));
- //material->set_parameter(FixedSpatialMaterial::PARAM_EMISSION,Color(1,1,1,1));
+ //material->set_parameter(SpatialMaterial::PARAM_EMISSION,Color(1,1,1,1));
} else {
missing_textures.push_back(texfile.get_file());
}
}
} else {
if (effect.emission.color != Color()) {
- material->set_feature(FixedSpatialMaterial::FEATURE_EMISSION, true);
+ material->set_feature(SpatialMaterial::FEATURE_EMISSION, true);
material->set_emission(effect.emission.color);
}
}
@@ -449,11 +449,11 @@ Error ColladaImport::_create_material(const String &p_target) {
Ref<Texture> texture = ResourceLoader::load(texfile, "Texture");
if (texture.is_valid()) {
- material->set_feature(FixedSpatialMaterial::FEATURE_NORMAL_MAPPING, true);
- material->set_texture(FixedSpatialMaterial::TEXTURE_NORMAL, texture);
+ material->set_feature(SpatialMaterial::FEATURE_NORMAL_MAPPING, true);
+ material->set_texture(SpatialMaterial::TEXTURE_NORMAL, texture);
//material->set_emission(Color(1,1,1,1));
- //material->set_texture(FixedSpatialMaterial::PARAM_NORMAL,texture);
+ //material->set_texture(SpatialMaterial::PARAM_NORMAL,texture);
} else {
//missing_textures.push_back(texfile.get_file());
}
@@ -464,9 +464,9 @@ Error ColladaImport::_create_material(const String &p_target) {
material->set_roughness(roughness);
if (effect.double_sided) {
- material->set_cull_mode(FixedSpatialMaterial::CULL_DISABLED);
+ material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
}
- material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, effect.unshaded);
+ material->set_flag(SpatialMaterial::FLAG_UNSHADED, effect.unshaded);
material_cache[p_target] = material;
return OK;
@@ -1000,7 +1000,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<Mesh> &p_mesh, c
{
- Ref<FixedSpatialMaterial> material;
+ Ref<SpatialMaterial> material;
//find material
Mesh::PrimitiveType primitive = Mesh::PRIMITIVE_TRIANGLES;
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 8a78376f13..3aa412bd5c 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -157,7 +157,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
memdelete(p_node);
return NULL;
}
-
+#if 0
if (p_node->cast_to<MeshInstance>()) {
MeshInstance *mi = p_node->cast_to<MeshInstance>();
@@ -177,18 +177,18 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
Ref<Mesh> m = mi->get_mesh();
for (int i = 0; i < m->get_surface_count(); i++) {
- Ref<FixedSpatialMaterial> fm = m->surface_get_material(i);
+ Ref<SpatialMaterial> fm = m->surface_get_material(i);
if (fm.is_valid()) {
//fm->set_flag(Material::FLAG_UNSHADED,true);
//fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
//fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER);
- //fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
+ //fm->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA,true);
}
}
}
}
}
-
+#endif
if (p_node->cast_to<MeshInstance>()) {
MeshInstance *mi = p_node->cast_to<MeshInstance>();
@@ -199,19 +199,19 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
for (int i = 0; i < m->get_surface_count(); i++) {
- Ref<FixedSpatialMaterial> mat = m->surface_get_material(i);
+ Ref<SpatialMaterial> mat = m->surface_get_material(i);
if (!mat.is_valid())
continue;
if (_teststr(mat->get_name(), "alpha")) {
- mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
mat->set_name(_fixstr(mat->get_name(), "alpha"));
}
if (_teststr(mat->get_name(), "vcol")) {
- mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- mat->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
mat->set_name(_fixstr(mat->get_name(), "vcol"));
}
}
@@ -242,7 +242,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
}
}
}
-
+#if 0
if (p_node->cast_to<MeshInstance>()) {
MeshInstance *mi = p_node->cast_to<MeshInstance>();
@@ -277,12 +277,12 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
Ref<Mesh> m = mi->get_mesh();
for (int i = 0; i < m->get_surface_count(); i++) {
- Ref<FixedSpatialMaterial> fm = m->surface_get_material(i);
+ Ref<SpatialMaterial> fm = m->surface_get_material(i);
if (fm.is_valid()) {
//fm->set_flag(Material::FLAG_UNSHADED,true);
//fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
//fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER);
- //fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
+ //fm->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA,true);
}
}
}
@@ -290,6 +290,8 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
}
}
}
+
+#endif
#if 0
if (p_flags&SCENE_FLAG_CREATE_LODS && p_node->cast_to<MeshInstance>()) {
@@ -325,12 +327,12 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
Ref<Mesh> m = mi->get_mesh();
for(int i=0;i<m->get_surface_count();i++) {
- Ref<FixedSpatialMaterial> fm = m->surface_get_material(i);
+ Ref<SpatialMaterial> fm = m->surface_get_material(i);
if (fm.is_valid()) {
fm->set_flag(Material::FLAG_UNSHADED,true);
fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
- fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
+ fm->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA,true);
}
}
}*/
@@ -687,16 +689,16 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
for (int i = 0; i < mesh->get_surface_count(); i++) {
- Ref<FixedSpatialMaterial> fm = mesh->surface_get_material(i);
+ Ref<SpatialMaterial> fm = mesh->surface_get_material(i);
if (fm.is_valid()) {
String name = fm->get_name();
/* if (_teststr(name,"alpha")) {
- fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
+ fm->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA,true);
name=_fixstr(name,"alpha");
}
if (_teststr(name,"vcol")) {
- fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY,true);
+ fm->set_fixed_flag(SpatialMaterial::FLAG_USE_COLOR_ARRAY,true);
name=_fixstr(name,"vcol");
}*/
fm->set_name(name);
diff --git a/editor/io_plugins/editor_scene_import_plugin.cpp b/editor/io_plugins/editor_scene_import_plugin.cpp
index 52a554f6d1..1fd7078135 100644
--- a/editor/io_plugins/editor_scene_import_plugin.cpp
+++ b/editor/io_plugins/editor_scene_import_plugin.cpp
@@ -1408,7 +1408,7 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<Imag
for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) {
if (E->get().type==Variant::OBJECT || E->get().type==Variant::ARRAY || E->get().type==Variant::DICTIONARY) {
- if (E->get().type==Variant::OBJECT && res->cast_to<FixedSpatialMaterial>() && (E->get().name=="textures/diffuse" || E->get().name=="textures/detail" || E->get().name=="textures/emission")) {
+ if (E->get().type==Variant::OBJECT && res->cast_to<SpatialMaterial>() && (E->get().name=="textures/diffuse" || E->get().name=="textures/detail" || E->get().name=="textures/emission")) {
Ref<ImageTexture> tex =res->get(E->get().name);
if (tex.is_valid()) {
@@ -1416,7 +1416,7 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<Imag
image_map.insert(tex,TEXTURE_ROLE_DIFFUSE);
}
- } else if (E->get().type==Variant::OBJECT && res->cast_to<FixedSpatialMaterial>() && (E->get().name=="textures/normal")) {
+ } else if (E->get().type==Variant::OBJECT && res->cast_to<SpatialMaterial>() && (E->get().name=="textures/normal")) {
Ref<ImageTexture> tex =res->get(E->get().name);
if (tex.is_valid()) {
@@ -1424,7 +1424,7 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<Imag
image_map.insert(tex,TEXTURE_ROLE_NORMALMAP);
/*
if (p_flags&SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY)
- res->cast_to<FixedSpatialMaterial>()->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_XY_NORMALMAP,true);
+ res->cast_to<SpatialMaterial>()->set_fixed_flag(SpatialMaterial::FLAG_USE_XY_NORMALMAP,true);
*/
}
@@ -1532,12 +1532,12 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
Ref<Mesh> m = mi->get_mesh();
for(int i=0;i<m->get_surface_count();i++) {
- Ref<FixedSpatialMaterial> fm = m->surface_get_material(i);
+ Ref<SpatialMaterial> fm = m->surface_get_material(i);
if (fm.is_valid()) {
//fm->set_flag(Material::FLAG_UNSHADED,true);
//fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
//fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER);
- //fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
+ //fm->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA,true);
}
}
}
@@ -1555,18 +1555,18 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
for(int i=0;i<m->get_surface_count();i++) {
- Ref<FixedSpatialMaterial> mat = m->surface_get_material(i);
+ Ref<SpatialMaterial> mat = m->surface_get_material(i);
if (!mat.is_valid())
continue;
if (p_flags&SCENE_FLAG_DETECT_ALPHA && _teststr(mat->get_name(),"alpha")) {
- //mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
+ //mat->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA,true);
//mat->set_name(_fixstr(mat->get_name(),"alpha"));
}
if (p_flags&SCENE_FLAG_DETECT_VCOLOR && _teststr(mat->get_name(),"vcol")) {
- //mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY,true);
+ //mat->set_fixed_flag(SpatialMaterial::FLAG_USE_COLOR_ARRAY,true);
//mat->set_name(_fixstr(mat->get_name(),"vcol"));
}
@@ -1641,12 +1641,12 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
Ref<Mesh> m = mi->get_mesh();
for(int i=0;i<m->get_surface_count();i++) {
- Ref<FixedSpatialMaterial> fm = m->surface_get_material(i);
+ Ref<SpatialMaterial> fm = m->surface_get_material(i);
if (fm.is_valid()) {
//fm->set_flag(Material::FLAG_UNSHADED,true);
//fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
//fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER);
- //fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
+ //fm->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA,true);
}
}
}
@@ -1689,12 +1689,12 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
Ref<Mesh> m = mi->get_mesh();
for(int i=0;i<m->get_surface_count();i++) {
- Ref<FixedSpatialMaterial> fm = m->surface_get_material(i);
+ Ref<SpatialMaterial> fm = m->surface_get_material(i);
if (fm.is_valid()) {
fm->set_flag(Material::FLAG_UNSHADED,true);
fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
- fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
+ fm->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA,true);
}
}
}*/
@@ -2062,16 +2062,16 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
for(int i=0;i<mesh->get_surface_count();i++) {
- Ref<FixedSpatialMaterial> fm = mesh->surface_get_material(i);
+ Ref<SpatialMaterial> fm = mesh->surface_get_material(i);
if (fm.is_valid()) {
String name = fm->get_name();
/* if (_teststr(name,"alpha")) {
- fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
+ fm->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA,true);
name=_fixstr(name,"alpha");
}
if (_teststr(name,"vcol")) {
- fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY,true);
+ fm->set_fixed_flag(SpatialMaterial::FLAG_USE_COLOR_ARRAY,true);
name=_fixstr(name,"vcol");
}*/
fm->set_name(name);
diff --git a/editor/io_plugins/editor_scene_importer_fbxconv.cpp b/editor/io_plugins/editor_scene_importer_fbxconv.cpp
index a2fe4a649b..12a88c3eb6 100644
--- a/editor/io_plugins/editor_scene_importer_fbxconv.cpp
+++ b/editor/io_plugins/editor_scene_importer_fbxconv.cpp
@@ -483,29 +483,29 @@ void EditorSceneImporterFBXConv::_parse_materials(State& state) {
ERR_CONTINUE(!material.has("id"));
String id = _id(material["id"]);
- Ref<FixedSpatialMaterial> mat = memnew( FixedSpatialMaterial );
+ Ref<SpatialMaterial> mat = memnew( SpatialMaterial );
if (material.has("diffuse")) {
- mat->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,_get_color(material["diffuse"]));
+ mat->set_parameter(SpatialMaterial::PARAM_DIFFUSE,_get_color(material["diffuse"]));
}
if (material.has("specular")) {
- mat->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR,_get_color(material["specular"]));
+ mat->set_parameter(SpatialMaterial::PARAM_SPECULAR,_get_color(material["specular"]));
}
if (material.has("emissive")) {
- mat->set_parameter(FixedSpatialMaterial::PARAM_EMISSION,_get_color(material["emissive"]));
+ mat->set_parameter(SpatialMaterial::PARAM_EMISSION,_get_color(material["emissive"]));
}
if (material.has("shininess")) {
float exp = material["shininess"];
- mat->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR_EXP,exp);
+ mat->set_parameter(SpatialMaterial::PARAM_SPECULAR_EXP,exp);
}
if (material.has("opacity")) {
- Color c = mat->get_parameter(FixedSpatialMaterial::PARAM_DIFFUSE);
+ Color c = mat->get_parameter(SpatialMaterial::PARAM_DIFFUSE);
c.a=material["opacity"];
- mat->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,c);
+ mat->set_parameter(SpatialMaterial::PARAM_DIFFUSE,c);
}
@@ -537,15 +537,15 @@ void EditorSceneImporterFBXConv::_parse_materials(State& state) {
String type=texture["type"];
if (type=="DIFFUSE")
- mat->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,tex);
+ mat->set_texture(SpatialMaterial::PARAM_DIFFUSE,tex);
else if (type=="SPECULAR")
- mat->set_texture(FixedSpatialMaterial::PARAM_SPECULAR,tex);
+ mat->set_texture(SpatialMaterial::PARAM_SPECULAR,tex);
else if (type=="SHININESS")
- mat->set_texture(FixedSpatialMaterial::PARAM_SPECULAR_EXP,tex);
+ mat->set_texture(SpatialMaterial::PARAM_SPECULAR_EXP,tex);
else if (type=="NORMAL")
- mat->set_texture(FixedSpatialMaterial::PARAM_NORMAL,tex);
+ mat->set_texture(SpatialMaterial::PARAM_NORMAL,tex);
else if (type=="EMISSIVE")
- mat->set_texture(FixedSpatialMaterial::PARAM_EMISSION,tex);
+ mat->set_texture(SpatialMaterial::PARAM_EMISSION,tex);
}
}
diff --git a/editor/plugins/baked_light_baker.cpp b/editor/plugins/baked_light_baker.cpp
index de2b78b8dd..3db54978e1 100644
--- a/editor/plugins/baked_light_baker.cpp
+++ b/editor/plugins/baked_light_baker.cpp
@@ -144,18 +144,18 @@ void BakedLightBaker::_add_mesh(const Ref<Mesh>& p_mesh,const Ref<Material>& p_m
MeshMaterial mm;
- Ref<FixedSpatialMaterial> fm = mat;
+ Ref<SpatialMaterial> fm = mat;
if (fm.is_valid()) {
//fixed route
- mm.diffuse.color=fm->get_parameter(FixedSpatialMaterial::PARAM_DIFFUSE);
+ mm.diffuse.color=fm->get_parameter(SpatialMaterial::PARAM_DIFFUSE);
if (linear_color)
mm.diffuse.color=mm.diffuse.color.to_linear();
- mm.diffuse.tex=_get_mat_tex(fm->get_texture(FixedSpatialMaterial::PARAM_DIFFUSE));
- mm.specular.color=fm->get_parameter(FixedSpatialMaterial::PARAM_SPECULAR);
+ mm.diffuse.tex=_get_mat_tex(fm->get_texture(SpatialMaterial::PARAM_DIFFUSE));
+ mm.specular.color=fm->get_parameter(SpatialMaterial::PARAM_SPECULAR);
if (linear_color)
mm.specular.color=mm.specular.color.to_linear();
- mm.specular.tex=_get_mat_tex(fm->get_texture(FixedSpatialMaterial::PARAM_SPECULAR));
+ mm.specular.tex=_get_mat_tex(fm->get_texture(SpatialMaterial::PARAM_SPECULAR));
} else {
mm.diffuse.color=Color(1,1,1,1);
diff --git a/editor/plugins/collision_polygon_editor_plugin.cpp b/editor/plugins/collision_polygon_editor_plugin.cpp
index 62426a7699..c0599bf26e 100644
--- a/editor/plugins/collision_polygon_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_editor_plugin.cpp
@@ -571,25 +571,25 @@ CollisionPolygonEditor::CollisionPolygonEditor(EditorNode *p_editor) {
imgeom->set_transform(Transform(Matrix3(),Vector3(0,0,0.00001)));
- line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
+ line_material = Ref<SpatialMaterial>( memnew( SpatialMaterial ));
line_material->set_flag(Material::FLAG_UNSHADED, true);
line_material->set_line_width(3.0);
- line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
- line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
- line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1));
+ line_material->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA, true);
+ line_material->set_fixed_flag(SpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
+ line_material->set_parameter(SpatialMaterial::PARAM_DIFFUSE,Color(1,1,1));
- handle_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
+ handle_material = Ref<SpatialMaterial>( memnew( SpatialMaterial ));
handle_material->set_flag(Material::FLAG_UNSHADED, true);
- handle_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_POINT_SIZE, true);
- handle_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1));
- handle_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
- handle_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, false);
+ handle_material->set_fixed_flag(SpatialMaterial::FLAG_USE_POINT_SIZE, true);
+ handle_material->set_parameter(SpatialMaterial::PARAM_DIFFUSE,Color(1,1,1));
+ handle_material->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA, true);
+ handle_material->set_fixed_flag(SpatialMaterial::FLAG_USE_COLOR_ARRAY, false);
Ref<Texture> handle=editor->get_gui_base()->get_icon("Editor3DHandle","EditorIcons");
handle_material->set_point_size(handle->get_width());
- handle_material->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,handle);
+ handle_material->set_texture(SpatialMaterial::PARAM_DIFFUSE,handle);
pointsm = memnew( MeshInstance );
imgeom->add_child(pointsm);
diff --git a/editor/plugins/collision_polygon_editor_plugin.h b/editor/plugins/collision_polygon_editor_plugin.h
index ace8c3429f..d033fbf2ed 100644
--- a/editor/plugins/collision_polygon_editor_plugin.h
+++ b/editor/plugins/collision_polygon_editor_plugin.h
@@ -62,8 +62,8 @@ class CollisionPolygonEditor : public HBoxContainer {
ToolButton *button_edit;
- Ref<FixedSpatialMaterial> line_material;
- Ref<FixedSpatialMaterial> handle_material;
+ Ref<SpatialMaterial> line_material;
+ Ref<SpatialMaterial> handle_material;
EditorNode *editor;
Panel *panel;
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
new file mode 100644
index 0000000000..52edc75bc0
--- /dev/null
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -0,0 +1,519 @@
+#include "curve_editor_plugin.h"
+
+#include "canvas_item_editor_plugin.h"
+#include "os/keyboard.h"
+#include "spatial_editor_plugin.h"
+void CurveTextureEdit::_gui_input(const InputEvent &p_event) {
+
+ if (p_event.type == InputEvent::KEY && p_event.key.pressed && p_event.key.scancode == KEY_DELETE && grabbed != -1) {
+
+ points.remove(grabbed);
+ grabbed = -1;
+ update();
+ emit_signal("curve_changed");
+ accept_event();
+ }
+
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.pressed) {
+
+ update();
+ Ref<Font> font = get_font("font", "Label");
+
+ int font_h = font->get_height();
+
+ Vector2 size = get_size();
+ size.y -= font_h;
+
+ Point2 p = Vector2(p_event.mouse_button.x, p_event.mouse_button.y) / size;
+ p.y = CLAMP(1.0 - p.y, 0, 1) * (max - min) + min;
+ grabbed = -1;
+ grabbing = true;
+
+ for (int i = 0; i < points.size(); i++) {
+
+ Vector2 ps = p * get_size();
+ Vector2 pt = Vector2(points[i].offset, points[i].height) * get_size();
+ if (ps.distance_to(pt) < 4) {
+ grabbed = i;
+ }
+ }
+
+ //grab or select
+ if (grabbed != -1) {
+ return;
+ }
+ //insert
+
+ Point np;
+ np.offset = p.x;
+ np.height = p.y;
+
+ points.push_back(np);
+ points.sort();
+ for (int i = 0; i < points.size(); i++) {
+ if (points[i].offset == p.x && points[i].height == p.y) {
+ grabbed = i;
+ break;
+ }
+ }
+
+ emit_signal("curve_changed");
+ }
+
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && !p_event.mouse_button.pressed) {
+
+ if (grabbing) {
+ grabbing = false;
+ emit_signal("curve_changed");
+ }
+ update();
+ }
+
+ if (p_event.type == InputEvent::MOUSE_MOTION && grabbing && grabbed != -1) {
+
+ Ref<Font> font = get_font("font", "Label");
+ int font_h = font->get_height();
+ Vector2 size = get_size();
+ size.y -= font_h;
+
+ Point2 p = Vector2(p_event.mouse_motion.x, p_event.mouse_motion.y) / size;
+ p.y = CLAMP(1.0 - p.y, 0, 1) * (max - min) + min;
+ p.x = CLAMP(p.x, 0.0, 1.0);
+
+ bool valid = true;
+
+ for (int i = 0; i < points.size(); i++) {
+
+ if (points[i].offset == p.x && points[i].height == p.y && i != grabbed) {
+ valid = false;
+ }
+ }
+
+ if (!valid)
+ return;
+
+ points[grabbed].offset = p.x;
+ points[grabbed].height = p.y;
+
+ points.sort();
+ for (int i = 0; i < points.size(); i++) {
+ if (points[i].offset == p.x && points[i].height == p.y) {
+ grabbed = i;
+ break;
+ }
+ }
+
+ emit_signal("curve_changed");
+
+ update();
+ }
+}
+
+void CurveTextureEdit::_plot_curve(const Vector2 &p_a, const Vector2 &p_b, const Vector2 &p_c, const Vector2 &p_d) {
+
+ Ref<Font> font = get_font("font", "Label");
+
+ int font_h = font->get_height();
+
+ float geometry[4][4];
+ float tmp1[4][4];
+ float tmp2[4][4];
+ float deltas[4][4];
+ double x, dx, dx2, dx3;
+ double y, dy, dy2, dy3;
+ double d, d2, d3;
+ int lastx, lasty;
+ int newx, newy;
+ int ntimes;
+ int i, j;
+
+ int xmax = get_size().x;
+ int ymax = get_size().y - font_h;
+
+ int vsplits = 4;
+
+ int zero_ofs = (1.0 - (0.0 - min) / (max - min)) * ymax;
+
+ draw_line(Vector2(0, zero_ofs), Vector2(xmax, zero_ofs), Color(0.8, 0.8, 0.8, 0.15), 2.0);
+
+ for (int i = 0; i <= vsplits; i++) {
+ float fofs = float(i) / vsplits;
+ int yofs = fofs * ymax;
+ draw_line(Vector2(xmax, yofs), Vector2(xmax - 4, yofs), Color(0.8, 0.8, 0.8, 0.8), 2.0);
+
+ String text = rtos((1.0 - fofs) * (max - min) + min);
+ int ppos = text.find(".");
+ if (ppos != -1) {
+ if (text.length() > ppos + 2)
+ text = text.substr(0, ppos + 2);
+ }
+
+ int size = font->get_string_size(text).x;
+ int xofs = xmax - size - 4;
+ yofs -= font_h / 2;
+
+ if (yofs < 2) {
+ yofs = 2;
+ } else if (yofs + font_h > ymax - 2) {
+ yofs = ymax - font_h - 2;
+ }
+
+ draw_string(font, Vector2(xofs, yofs + font->get_ascent()), text, Color(0.8, 0.8, 0.8, 1));
+ }
+
+ /* construct the geometry matrix from the segment */
+ for (i = 0; i < 4; i++) {
+ geometry[i][2] = 0;
+ geometry[i][3] = 0;
+ }
+
+ geometry[0][0] = (p_a[0] * xmax);
+ geometry[1][0] = (p_b[0] * xmax);
+ geometry[2][0] = (p_c[0] * xmax);
+ geometry[3][0] = (p_d[0] * xmax);
+
+ geometry[0][1] = ((p_a[1] - min) / (max - min) * ymax);
+ geometry[1][1] = ((p_b[1] - min) / (max - min) * ymax);
+ geometry[2][1] = ((p_c[1] - min) / (max - min) * ymax);
+ geometry[3][1] = ((p_d[1] - min) / (max - min) * ymax);
+
+ /* subdivide the curve ntimes (1000) times */
+ ntimes = 4 * xmax;
+ /* ntimes can be adjusted to give a finer or coarser curve */
+ d = 1.0 / ntimes;
+ d2 = d * d;
+ d3 = d * d * d;
+
+ /* construct a temporary matrix for determining the forward differencing deltas */
+ tmp2[0][0] = 0;
+ tmp2[0][1] = 0;
+ tmp2[0][2] = 0;
+ tmp2[0][3] = 1;
+ tmp2[1][0] = d3;
+ tmp2[1][1] = d2;
+ tmp2[1][2] = d;
+ tmp2[1][3] = 0;
+ tmp2[2][0] = 6 * d3;
+ tmp2[2][1] = 2 * d2;
+ tmp2[2][2] = 0;
+ tmp2[2][3] = 0;
+ tmp2[3][0] = 6 * d3;
+ tmp2[3][1] = 0;
+ tmp2[3][2] = 0;
+ tmp2[3][3] = 0;
+
+ /* compose the basis and geometry matrices */
+
+ static const float CR_basis[4][4] = {
+ { -0.5, 1.5, -1.5, 0.5 },
+ { 1.0, -2.5, 2.0, -0.5 },
+ { -0.5, 0.0, 0.5, 0.0 },
+ { 0.0, 1.0, 0.0, 0.0 },
+ };
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ tmp1[i][j] = (CR_basis[i][0] * geometry[0][j] +
+ CR_basis[i][1] * geometry[1][j] +
+ CR_basis[i][2] * geometry[2][j] +
+ CR_basis[i][3] * geometry[3][j]);
+ }
+ }
+ /* compose the above results to get the deltas matrix */
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ deltas[i][j] = (tmp2[i][0] * tmp1[0][j] +
+ tmp2[i][1] * tmp1[1][j] +
+ tmp2[i][2] * tmp1[2][j] +
+ tmp2[i][3] * tmp1[3][j]);
+ }
+ }
+
+ /* extract the x deltas */
+ x = deltas[0][0];
+ dx = deltas[1][0];
+ dx2 = deltas[2][0];
+ dx3 = deltas[3][0];
+
+ /* extract the y deltas */
+ y = deltas[0][1];
+ dy = deltas[1][1];
+ dy2 = deltas[2][1];
+ dy3 = deltas[3][1];
+
+ lastx = CLAMP(x, 0, xmax);
+ lasty = CLAMP(y, 0, ymax);
+
+ /* if (fix255)
+ {
+ cd->curve[cd->outline][lastx] = lasty;
+ }
+ else
+ {
+ cd->curve_ptr[cd->outline][lastx] = lasty;
+ if(gb_debug) printf("bender_plot_curve xmax:%d ymax:%d\n", (int)xmax, (int)ymax);
+ }
+*/
+ /* loop over the curve */
+ for (i = 0; i < ntimes; i++) {
+ /* increment the x values */
+ x += dx;
+ dx += dx2;
+ dx2 += dx3;
+
+ /* increment the y values */
+ y += dy;
+ dy += dy2;
+ dy2 += dy3;
+
+ newx = CLAMP((Math::round(x)), 0, xmax);
+ newy = CLAMP((Math::round(y)), 0, ymax);
+
+ /* if this point is different than the last one...then draw it */
+ if ((lastx != newx) || (lasty != newy)) {
+#if 0
+ if(fix255)
+ {
+ /* use fixed array size (for the curve graph) */
+ cd->curve[cd->outline][newx] = newy;
+ }
+ else
+ {
+ /* use dynamic allocated curve_ptr (for the real curve) */
+ cd->curve_ptr[cd->outline][newx] = newy;
+
+ if(gb_debug) printf("outline: %d cX: %d cY: %d\n", (int)cd->outline, (int)newx, (int)newy);
+ }
+#endif
+ draw_line(Vector2(lastx, ymax - lasty), Vector2(newx, ymax - newy), Color(0.8, 0.8, 0.8, 0.8), 2.0);
+ }
+
+ lastx = newx;
+ lasty = newy;
+ }
+
+ int splits = 8;
+
+ draw_line(Vector2(0, ymax - 1), Vector2(xmax, ymax - 1), Color(0.8, 0.8, 0.8, 0.3), 2.0);
+
+ for (int i = 0; i <= splits; i++) {
+ float fofs = float(i) / splits;
+ draw_line(Vector2(fofs * xmax, ymax), Vector2(fofs * xmax, ymax - 2), Color(0.8, 0.8, 0.8, 0.8), 2.0);
+
+ String text = rtos(fofs);
+ int size = font->get_string_size(text).x;
+ int ofs = fofs * xmax - size * 0.5;
+ if (ofs < 2) {
+ ofs = 2;
+ } else if (ofs + size > xmax - 2) {
+ ofs = xmax - size - 2;
+ }
+
+ draw_string(font, Vector2(ofs, ymax + font->get_ascent()), text, Color(0.8, 0.8, 0.8, 1));
+ }
+}
+
+void CurveTextureEdit::_notification(int p_what) {
+
+ if (p_what == NOTIFICATION_DRAW) {
+
+ Ref<Font> font = get_font("font", "Label");
+
+ int font_h = font->get_height();
+
+ draw_style_box(get_stylebox("bg", "Tree"), Rect2(Point2(), get_size()));
+
+ int w = get_size().x;
+ int h = get_size().y;
+
+ Vector2 prev = Vector2(0, 0);
+ Vector2 prev2 = Vector2(0, 0);
+
+ for (int i = -1; i < points.size(); i++) {
+
+ Vector2 next;
+ Vector2 next2;
+ if (i + 1 >= points.size()) {
+ next = Vector2(1, 0);
+ } else {
+ next = Vector2(points[i + 1].offset, points[i + 1].height);
+ }
+
+ if (i + 2 >= points.size()) {
+ next2 = Vector2(1, 0);
+ } else {
+ next2 = Vector2(points[i + 2].offset, points[i + 2].height);
+ }
+
+ /*if (i==-1 && prev.offset==next.offset) {
+ prev=next;
+ continue;
+ }*/
+
+ _plot_curve(prev2, prev, next, next2);
+
+ prev2 = prev;
+ prev = next;
+ }
+
+ Vector2 size = get_size();
+ size.y -= font_h;
+ for (int i = 0; i < points.size(); i++) {
+
+ Color col = i == grabbed ? Color(1, 0.0, 0.0, 0.9) : Color(1, 1, 1, 0.8);
+
+ float h = (points[i].height - min) / (max - min);
+ draw_rect(Rect2(Vector2(points[i].offset, 1.0 - h) * size - Vector2(2, 2), Vector2(5, 5)), col);
+ }
+
+ /* if (grabbed!=-1) {
+
+ draw_rect(Rect2(total_w+3,0,h,h),points[grabbed].color);
+ }
+*/
+ if (has_focus()) {
+
+ draw_line(Vector2(-1, -1), Vector2(w + 1, -1), Color(1, 1, 1, 0.6));
+ draw_line(Vector2(w + 1, -1), Vector2(w + 1, h + 1), Color(1, 1, 1, 0.6));
+ draw_line(Vector2(w + 1, h + 1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6));
+ draw_line(Vector2(-1, -1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6));
+ }
+ }
+}
+
+Size2 CurveTextureEdit::get_minimum_size() const {
+
+ return Vector2(64, 64);
+}
+
+void CurveTextureEdit::set_range(float p_min, float p_max) {
+ max = p_max;
+ min = p_min;
+ update();
+}
+
+void CurveTextureEdit::set_points(const Vector<Vector2> &p_points) {
+
+ points.clear();
+ for (int i = 0; i < p_points.size(); i++) {
+ Point p;
+ p.offset = p_points[i].x;
+ p.height = p_points[i].y;
+ points.push_back(p);
+ }
+
+ points.sort();
+ update();
+}
+
+Vector<Vector2> CurveTextureEdit::get_points() const {
+ Vector<Vector2> ret;
+ for (int i = 0; i < points.size(); i++)
+ ret.push_back(Vector2(points[i].offset, points[i].height));
+ return ret;
+}
+
+void CurveTextureEdit::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("_gui_input"), &CurveTextureEdit::_gui_input);
+
+ ADD_SIGNAL(MethodInfo("curve_changed"));
+}
+
+CurveTextureEdit::CurveTextureEdit() {
+
+ grabbed = -1;
+ grabbing = false;
+ max = 1;
+ min = 0;
+ set_focus_mode(FOCUS_ALL);
+}
+
+void CurveTextureEditorPlugin::_curve_settings_changed() {
+
+ if (!curve_texture_ref.is_valid())
+ return;
+ curve_editor->set_points(Variant(curve_texture_ref->get_points()));
+ curve_editor->set_range(curve_texture_ref->get_min(), curve_texture_ref->get_max());
+}
+
+CurveTextureEditorPlugin::CurveTextureEditorPlugin(EditorNode *p_node) {
+
+ editor = p_node;
+ curve_editor = memnew(CurveTextureEdit);
+
+ curve_button = editor->add_bottom_panel_item("CurveTexture", curve_editor);
+
+ curve_button->hide();
+ curve_editor->set_custom_minimum_size(Size2(100, 128 * EDSCALE));
+ curve_editor->hide();
+ curve_editor->connect("curve_changed", this, "curve_changed");
+}
+
+void CurveTextureEditorPlugin::edit(Object *p_object) {
+
+ if (curve_texture_ref.is_valid()) {
+ curve_texture_ref->disconnect("changed", this, "_curve_settings_changed");
+ }
+ CurveTexture *curve_texture = p_object->cast_to<CurveTexture>();
+ if (!curve_texture)
+ return;
+ curve_texture_ref = Ref<CurveTexture>(curve_texture);
+ curve_editor->set_points(Variant(curve_texture_ref->get_points()));
+ curve_editor->set_range(curve_texture_ref->get_min(), curve_texture_ref->get_max());
+ if (!curve_texture_ref->is_connected("changed", this, "_curve_settings_changed")) {
+ curve_texture_ref->connect("changed", this, "_curve_settings_changed");
+ }
+}
+
+bool CurveTextureEditorPlugin::handles(Object *p_object) const {
+
+ return p_object->is_class("CurveTexture");
+}
+
+void CurveTextureEditorPlugin::make_visible(bool p_visible) {
+
+ if (p_visible) {
+ curve_button->show();
+ editor->make_bottom_panel_item_visible(curve_editor);
+
+ } else {
+
+ curve_button->hide();
+ if (curve_editor->is_visible_in_tree())
+ editor->hide_bottom_panel();
+ }
+}
+
+void CurveTextureEditorPlugin::_curve_changed() {
+
+ if (curve_texture_ref.is_valid()) {
+
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+
+ Vector<Vector2> points = curve_editor->get_points();
+ PoolVector<Vector2> ppoints = Variant(points);
+
+ ur->create_action(TTR("Modify Curve"), UndoRedo::MERGE_ENDS);
+ ur->add_do_method(this, "undo_redo_curve_texture", ppoints);
+ ur->add_undo_method(this, "undo_redo_curve_texture", curve_texture_ref->get_points());
+ ur->commit_action();
+ }
+}
+
+void CurveTextureEditorPlugin::_undo_redo_curve_texture(const PoolVector<Vector2> &points) {
+
+ curve_texture_ref->set_points(points);
+ curve_editor->set_points(Variant(curve_texture_ref->get_points()));
+ curve_editor->update();
+}
+
+CurveTextureEditorPlugin::~CurveTextureEditorPlugin() {
+}
+
+void CurveTextureEditorPlugin::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("curve_changed"), &CurveTextureEditorPlugin::_curve_changed);
+ ClassDB::bind_method(D_METHOD("_curve_settings_changed"), &CurveTextureEditorPlugin::_curve_settings_changed);
+ ClassDB::bind_method(D_METHOD("undo_redo_curve_texture", "points"), &CurveTextureEditorPlugin::_undo_redo_curve_texture);
+}
diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h
new file mode 100644
index 0000000000..e98cec2727
--- /dev/null
+++ b/editor/plugins/curve_editor_plugin.h
@@ -0,0 +1,66 @@
+#ifndef CURVE_EDITOR_PLUGIN_H
+#define CURVE_EDITOR_PLUGIN_H
+
+#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
+
+class CurveTextureEdit : public Control {
+
+ GDCLASS(CurveTextureEdit, Control);
+
+ struct Point {
+
+ float offset;
+ float height;
+ bool operator<(const Point &p_ponit) const {
+ return offset < p_ponit.offset;
+ }
+ };
+
+ bool grabbing;
+ int grabbed;
+ Vector<Point> points;
+ float max, min;
+
+ void _plot_curve(const Vector2 &p_a, const Vector2 &p_b, const Vector2 &p_c, const Vector2 &p_d);
+
+protected:
+ void _gui_input(const InputEvent &p_event);
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ void set_range(float p_min, float p_max);
+ void set_points(const Vector<Vector2> &p_points);
+ Vector<Vector2> get_points() const;
+ virtual Size2 get_minimum_size() const;
+ CurveTextureEdit();
+};
+
+class CurveTextureEditorPlugin : public EditorPlugin {
+
+ GDCLASS(CurveTextureEditorPlugin, EditorPlugin);
+
+ CurveTextureEdit *curve_editor;
+ Ref<CurveTexture> curve_texture_ref;
+ EditorNode *editor;
+ ToolButton *curve_button;
+
+protected:
+ static void _bind_methods();
+ void _curve_changed();
+ void _undo_redo_curve_texture(const PoolVector<Vector2> &points);
+ void _curve_settings_changed();
+
+public:
+ virtual String get_name() const { return "CurveTexture"; }
+ bool has_main_screen() const { return false; }
+ virtual void edit(Object *p_node);
+ virtual bool handles(Object *p_node) const;
+ virtual void make_visible(bool p_visible);
+
+ CurveTextureEditorPlugin(EditorNode *p_node);
+ ~CurveTextureEditorPlugin();
+};
+
+#endif // CURVE_EDITOR_PLUGIN_H
diff --git a/editor/plugins/gradient_texture_editor_plugin.cpp b/editor/plugins/gradient_texture_editor_plugin.cpp
new file mode 100644
index 0000000000..1e82a1105a
--- /dev/null
+++ b/editor/plugins/gradient_texture_editor_plugin.cpp
@@ -0,0 +1,504 @@
+#include "gradient_texture_editor_plugin.h"
+
+#include "canvas_item_editor_plugin.h"
+#include "spatial_editor_plugin.h"
+
+#include "os/keyboard.h"
+#include "scene/resources/default_theme/theme_data.h"
+#define POINT_WIDTH 8
+
+GradientTextureEdit::GradientTextureEdit() {
+ grabbed = -1;
+ grabbing = false;
+ set_focus_mode(FOCUS_ALL);
+
+ popup = memnew(PopupPanel);
+ picker = memnew(ColorPicker);
+ popup->add_child(picker);
+
+ add_child(popup);
+
+ checker = Ref<ImageTexture>(memnew(ImageTexture));
+ checker->create_from_image(Image(checker_bg_png), ImageTexture::FLAG_REPEAT);
+}
+
+int GradientTextureEdit::_get_point_from_pos(int x) {
+ int result = -1;
+ int total_w = get_size().width - get_size().height - 3;
+ for (int i = 0; i < points.size(); i++) {
+ //Check if we clicked at point
+ if (ABS(x - points[i].offset * total_w + 1) < (POINT_WIDTH / 2 + 1)) {
+ result = i;
+ }
+ }
+ return result;
+}
+
+void GradientTextureEdit::_show_color_picker() {
+ if (grabbed == -1)
+ return;
+ Size2 ms = Size2(350, picker->get_combined_minimum_size().height + 10);
+ picker->set_pick_color(points[grabbed].color);
+ popup->set_pos(get_global_pos() - Vector2(ms.width - get_size().width, ms.height));
+ popup->set_size(ms);
+ popup->popup();
+}
+
+GradientTextureEdit::~GradientTextureEdit() {
+}
+
+void GradientTextureEdit::_gui_input(const InputEvent &p_event) {
+
+ if (p_event.type == InputEvent::KEY && p_event.key.pressed && p_event.key.scancode == KEY_DELETE && grabbed != -1) {
+
+ points.remove(grabbed);
+ grabbed = -1;
+ grabbing = false;
+ update();
+ emit_signal("ramp_changed");
+ accept_event();
+ }
+
+ //Show color picker on double click.
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.doubleclick && p_event.mouse_button.pressed) {
+ grabbed = _get_point_from_pos(p_event.mouse_button.x);
+ _show_color_picker();
+ accept_event();
+ }
+
+ //Delete point on right click
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 2 && p_event.mouse_button.pressed) {
+ grabbed = _get_point_from_pos(p_event.mouse_button.x);
+ if (grabbed != -1) {
+ points.remove(grabbed);
+ grabbed = -1;
+ grabbing = false;
+ update();
+ emit_signal("ramp_changed");
+ accept_event();
+ }
+ }
+
+ //Hold alt key to duplicate selected color
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.pressed && p_event.key.mod.alt) {
+
+ int x = p_event.mouse_button.x;
+ grabbed = _get_point_from_pos(x);
+
+ if (grabbed != -1) {
+ int total_w = get_size().width - get_size().height - 3;
+ GradientTexture::Point newPoint = points[grabbed];
+ newPoint.offset = CLAMP(x / float(total_w), 0, 1);
+
+ points.push_back(newPoint);
+ points.sort();
+ for (int i = 0; i < points.size(); ++i) {
+ if (points[i].offset == newPoint.offset) {
+ grabbed = i;
+ break;
+ }
+ }
+
+ emit_signal("ramp_changed");
+ update();
+ }
+ }
+
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.pressed) {
+
+ update();
+ int x = p_event.mouse_button.x;
+ int total_w = get_size().width - get_size().height - 3;
+
+ //Check if color selector was clicked.
+ if (x > total_w + 3) {
+ _show_color_picker();
+ return;
+ }
+
+ grabbing = true;
+
+ grabbed = _get_point_from_pos(x);
+ //grab or select
+ if (grabbed != -1) {
+ return;
+ }
+
+ //insert
+ GradientTexture::Point newPoint;
+ newPoint.offset = CLAMP(x / float(total_w), 0, 1);
+
+ GradientTexture::Point prev;
+ GradientTexture::Point next;
+
+ int pos = -1;
+ for (int i = 0; i < points.size(); i++) {
+ if (points[i].offset < newPoint.offset)
+ pos = i;
+ }
+
+ if (pos == -1) {
+
+ prev.color = Color(0, 0, 0);
+ prev.offset = 0;
+ if (points.size()) {
+ next = points[0];
+ } else {
+ next.color = Color(1, 1, 1);
+ next.offset = 1.0;
+ }
+ } else {
+
+ if (pos == points.size() - 1) {
+ next.color = Color(1, 1, 1);
+ next.offset = 1.0;
+ } else {
+ next = points[pos + 1];
+ }
+ prev = points[pos];
+ }
+
+ newPoint.color = prev.color.linear_interpolate(next.color, (newPoint.offset - prev.offset) / (next.offset - prev.offset));
+
+ points.push_back(newPoint);
+ points.sort();
+ for (int i = 0; i < points.size(); i++) {
+ if (points[i].offset == newPoint.offset) {
+ grabbed = i;
+ break;
+ }
+ }
+
+ emit_signal("ramp_changed");
+ }
+
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && !p_event.mouse_button.pressed) {
+
+ if (grabbing) {
+ grabbing = false;
+ emit_signal("ramp_changed");
+ }
+ update();
+ }
+
+ if (p_event.type == InputEvent::MOUSE_MOTION && grabbing) {
+
+ int total_w = get_size().width - get_size().height - 3;
+
+ int x = p_event.mouse_motion.x;
+ float newofs = CLAMP(x / float(total_w), 0, 1);
+
+ //Snap to nearest point if holding shift
+ if (p_event.key.mod.shift) {
+ float snap_treshhold = 0.03;
+ float smallest_ofs = snap_treshhold;
+ bool founded = false;
+ int nearest_point;
+ for (int i = 0; i < points.size(); ++i) {
+ if (i != grabbed) {
+ float temp_ofs = ABS(points[i].offset - newofs);
+ if (temp_ofs < smallest_ofs) {
+ smallest_ofs = temp_ofs;
+ nearest_point = i;
+ if (founded)
+ break;
+ founded = true;
+ }
+ }
+ }
+ if (founded) {
+ if (points[nearest_point].offset < newofs)
+ newofs = points[nearest_point].offset + 0.00001;
+ else
+ newofs = points[nearest_point].offset - 0.00001;
+ newofs = CLAMP(newofs, 0, 1);
+ }
+ }
+
+ bool valid = true;
+ for (int i = 0; i < points.size(); i++) {
+
+ if (points[i].offset == newofs && i != grabbed) {
+ valid = false;
+ }
+ }
+
+ if (!valid)
+ return;
+
+ points[grabbed].offset = newofs;
+
+ points.sort();
+ for (int i = 0; i < points.size(); i++) {
+ if (points[i].offset == newofs) {
+ grabbed = i;
+ break;
+ }
+ }
+
+ emit_signal("ramp_changed");
+
+ update();
+ }
+}
+
+void GradientTextureEdit::_notification(int p_what) {
+
+ if (p_what == NOTIFICATION_ENTER_TREE) {
+ if (!picker->is_connected("color_changed", this, "_color_changed")) {
+ picker->connect("color_changed", this, "_color_changed");
+ }
+ }
+ if (p_what == NOTIFICATION_DRAW) {
+
+ int w = get_size().x;
+ int h = get_size().y;
+
+ if (w == 0 || h == 0)
+ return; //Safety check. We have division by 'h'. And in any case there is nothing to draw with such size
+
+ int total_w = get_size().width - get_size().height - 3;
+
+ //Draw checker pattern for ramp
+ _draw_checker(0, 0, total_w, h);
+
+ //Draw color ramp
+ GradientTexture::Point prev;
+ prev.offset = 0;
+ if (points.size() == 0)
+ prev.color = Color(0, 0, 0); //Draw black rectangle if we have no points
+ else
+ prev.color = points[0].color; //Extend color of first point to the beginning.
+
+ for (int i = -1; i < points.size(); i++) {
+
+ GradientTexture::Point next;
+ //If there is no next point
+ if (i + 1 == points.size()) {
+ if (points.size() == 0)
+ next.color = Color(0, 0, 0); //Draw black rectangle if we have no points
+ else
+ next.color = points[i].color; //Extend color of last point to the end.
+ next.offset = 1;
+ } else {
+ next = points[i + 1];
+ }
+
+ if (prev.offset == next.offset) {
+ prev = next;
+ continue;
+ }
+
+ Vector<Vector2> points;
+ Vector<Color> colors;
+ points.push_back(Vector2(prev.offset * total_w, h));
+ points.push_back(Vector2(prev.offset * total_w, 0));
+ points.push_back(Vector2(next.offset * total_w, 0));
+ points.push_back(Vector2(next.offset * total_w, h));
+ colors.push_back(prev.color);
+ colors.push_back(prev.color);
+ colors.push_back(next.color);
+ colors.push_back(next.color);
+ draw_primitive(points, colors, Vector<Point2>());
+ prev = next;
+ }
+
+ //Draw point markers
+ for (int i = 0; i < points.size(); i++) {
+
+ Color col = i == grabbed ? Color(1, 0.0, 0.0, 0.9) : points[i].color.contrasted();
+ col.a = 0.9;
+
+ draw_line(Vector2(points[i].offset * total_w, 0), Vector2(points[i].offset * total_w, h / 2), col);
+ draw_rect(Rect2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2, POINT_WIDTH, h / 2), Color(0.6, 0.6, 0.6, i == grabbed ? 0.9 : 0.4));
+ draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h - 1), col);
+ draw_line(Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h - 1), col);
+ draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h / 2), col);
+ draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h - 1), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h - 1), col);
+ }
+
+ //Draw "button" for color selector
+ _draw_checker(total_w + 3, 0, h, h);
+ if (grabbed != -1) {
+ //Draw with selection color
+ draw_rect(Rect2(total_w + 3, 0, h, h), points[grabbed].color);
+ } else {
+ //if no color selected draw grey color with 'X' on top.
+ draw_rect(Rect2(total_w + 3, 0, h, h), Color(0.5, 0.5, 0.5, 1));
+ draw_line(Vector2(total_w + 3, 0), Vector2(total_w + 3 + h, h), Color(1, 1, 1, 0.6));
+ draw_line(Vector2(total_w + 3, h), Vector2(total_w + 3 + h, 0), Color(1, 1, 1, 0.6));
+ }
+
+ //Draw borders around color ramp if in focus
+ if (has_focus()) {
+
+ draw_line(Vector2(-1, -1), Vector2(total_w + 1, -1), Color(1, 1, 1, 0.6));
+ draw_line(Vector2(total_w + 1, -1), Vector2(total_w + 1, h + 1), Color(1, 1, 1, 0.6));
+ draw_line(Vector2(total_w + 1, h + 1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6));
+ draw_line(Vector2(-1, -1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6));
+ }
+ }
+}
+
+void GradientTextureEdit::_draw_checker(int x, int y, int w, int h) {
+ //Draw it with polygon to insert UVs for scale
+ Vector<Vector2> backPoints;
+ backPoints.push_back(Vector2(x, y));
+ backPoints.push_back(Vector2(x, y + h));
+ backPoints.push_back(Vector2(x + w, y + h));
+ backPoints.push_back(Vector2(x + w, y));
+ Vector<Color> colorPoints;
+ colorPoints.push_back(Color(1, 1, 1, 1));
+ colorPoints.push_back(Color(1, 1, 1, 1));
+ colorPoints.push_back(Color(1, 1, 1, 1));
+ colorPoints.push_back(Color(1, 1, 1, 1));
+ Vector<Vector2> uvPoints;
+ //Draw checker pattern pixel-perfect and scale it by 2.
+ uvPoints.push_back(Vector2(x, y));
+ uvPoints.push_back(Vector2(x, y + h * .5f / checker->get_height()));
+ uvPoints.push_back(Vector2(x + w * .5f / checker->get_width(), y + h * .5f / checker->get_height()));
+ uvPoints.push_back(Vector2(x + w * .5f / checker->get_width(), y));
+ draw_polygon(backPoints, colorPoints, uvPoints, checker);
+}
+
+Size2 GradientTextureEdit::get_minimum_size() const {
+
+ return Vector2(0, 16);
+}
+
+void GradientTextureEdit::_color_changed(const Color &p_color) {
+
+ if (grabbed == -1)
+ return;
+ points[grabbed].color = p_color;
+ update();
+ emit_signal("ramp_changed");
+}
+
+void GradientTextureEdit::set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors) {
+
+ ERR_FAIL_COND(p_offsets.size() != p_colors.size());
+ points.clear();
+ for (int i = 0; i < p_offsets.size(); i++) {
+ GradientTexture::Point p;
+ p.offset = p_offsets[i];
+ p.color = p_colors[i];
+ points.push_back(p);
+ }
+
+ points.sort();
+ update();
+}
+
+Vector<float> GradientTextureEdit::get_offsets() const {
+ Vector<float> ret;
+ for (int i = 0; i < points.size(); i++)
+ ret.push_back(points[i].offset);
+ return ret;
+}
+
+Vector<Color> GradientTextureEdit::get_colors() const {
+ Vector<Color> ret;
+ for (int i = 0; i < points.size(); i++)
+ ret.push_back(points[i].color);
+ return ret;
+}
+
+void GradientTextureEdit::set_points(Vector<GradientTexture::Point> &p_points) {
+ if (points.size() != p_points.size())
+ grabbed = -1;
+ points.clear();
+ points = p_points;
+}
+
+Vector<GradientTexture::Point> &GradientTextureEdit::get_points() {
+ return points;
+}
+
+void GradientTextureEdit::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_gui_input"), &GradientTextureEdit::_gui_input);
+ ClassDB::bind_method(D_METHOD("_color_changed"), &GradientTextureEdit::_color_changed);
+ ADD_SIGNAL(MethodInfo("ramp_changed"));
+}
+
+GradientTextureEditorPlugin::GradientTextureEditorPlugin(EditorNode *p_node) {
+
+ editor = p_node;
+ ramp_editor = memnew(GradientTextureEdit);
+
+ gradient_button = editor->add_bottom_panel_item("GradientTexture", ramp_editor);
+
+ gradient_button->hide();
+ ramp_editor->set_custom_minimum_size(Size2(100, 100 * EDSCALE));
+ ramp_editor->hide();
+ ramp_editor->connect("ramp_changed", this, "ramp_changed");
+}
+
+void GradientTextureEditorPlugin::edit(Object *p_object) {
+
+ GradientTexture *gradient_texture = p_object->cast_to<GradientTexture>();
+ if (!gradient_texture)
+ return;
+ gradient_texture_ref = Ref<GradientTexture>(gradient_texture);
+ ramp_editor->set_points(gradient_texture_ref->get_points());
+}
+
+bool GradientTextureEditorPlugin::handles(Object *p_object) const {
+
+ return p_object->is_class("GradientTexture");
+}
+
+void GradientTextureEditorPlugin::make_visible(bool p_visible) {
+
+ if (p_visible) {
+ gradient_button->show();
+ editor->make_bottom_panel_item_visible(ramp_editor);
+
+ } else {
+
+ gradient_button->hide();
+ if (ramp_editor->is_visible_in_tree())
+ editor->hide_bottom_panel();
+ }
+}
+
+void GradientTextureEditorPlugin::_ramp_changed() {
+
+ if (gradient_texture_ref.is_valid()) {
+
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+
+ //Not sure if I should convert this data to PoolVector
+ Vector<float> new_offsets = ramp_editor->get_offsets();
+ Vector<Color> new_colors = ramp_editor->get_colors();
+ Vector<float> old_offsets = gradient_texture_ref->get_offsets();
+ Vector<Color> old_colors = gradient_texture_ref->get_colors();
+
+ if (old_offsets.size() != new_offsets.size())
+ ur->create_action(TTR("Add/Remove Color Ramp Point"));
+ else
+ ur->create_action(TTR("Modify Color Ramp"), UndoRedo::MERGE_ENDS);
+ ur->add_do_method(this, "undo_redo_gradient_texture", new_offsets, new_colors);
+ ur->add_undo_method(this, "undo_redo_gradient_texture", old_offsets, old_colors);
+ ur->commit_action();
+
+ //gradient_texture_ref->set_points(ramp_editor->get_points());
+ }
+}
+
+void GradientTextureEditorPlugin::_undo_redo_gradient_texture(const Vector<float> &offsets,
+ const Vector<Color> &colors) {
+
+ gradient_texture_ref->set_offsets(offsets);
+ gradient_texture_ref->set_colors(colors);
+ ramp_editor->set_points(gradient_texture_ref->get_points());
+ ramp_editor->update();
+}
+
+GradientTextureEditorPlugin::~GradientTextureEditorPlugin() {
+}
+
+void GradientTextureEditorPlugin::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("ramp_changed"), &GradientTextureEditorPlugin::_ramp_changed);
+ ClassDB::bind_method(D_METHOD("undo_redo_gradient_texture", "offsets", "colors"), &GradientTextureEditorPlugin::_undo_redo_gradient_texture);
+}
diff --git a/editor/plugins/gradient_texture_editor_plugin.h b/editor/plugins/gradient_texture_editor_plugin.h
new file mode 100644
index 0000000000..5af828f17c
--- /dev/null
+++ b/editor/plugins/gradient_texture_editor_plugin.h
@@ -0,0 +1,69 @@
+#ifndef GRADIENT_TEXTURE_EDITOR_PLUGIN_H
+#define GRADIENT_TEXTURE_EDITOR_PLUGIN_H
+
+#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
+#include "scene/resources/texture.h"
+
+class GradientTextureEdit : public Control {
+
+ GDCLASS(GradientTextureEdit, Control);
+
+ PopupPanel *popup;
+ ColorPicker *picker;
+
+ Ref<ImageTexture> checker;
+
+ bool grabbing;
+ int grabbed;
+ Vector<GradientTexture::Point> points;
+
+ void _draw_checker(int x, int y, int w, int h);
+ void _color_changed(const Color &p_color);
+ int _get_point_from_pos(int x);
+ void _show_color_picker();
+
+protected:
+ void _gui_input(const InputEvent &p_event);
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ void set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors);
+ Vector<float> get_offsets() const;
+ Vector<Color> get_colors() const;
+ void set_points(Vector<GradientTexture::Point> &p_points);
+ Vector<GradientTexture::Point> &get_points();
+ virtual Size2 get_minimum_size() const;
+
+ GradientTextureEdit();
+ virtual ~GradientTextureEdit();
+};
+
+class GradientTextureEditorPlugin : public EditorPlugin {
+
+ GDCLASS(GradientTextureEditorPlugin, EditorPlugin);
+
+ bool _2d;
+ Ref<GradientTexture> gradient_texture_ref;
+ GradientTextureEdit *ramp_editor;
+ EditorNode *editor;
+ ToolButton *gradient_button;
+
+protected:
+ static void _bind_methods();
+ void _ramp_changed();
+ void _undo_redo_gradient_texture(const Vector<float> &offsets, const Vector<Color> &colors);
+
+public:
+ virtual String get_name() const { return "GradientTexture"; }
+ bool has_main_screen() const { return false; }
+ virtual void edit(Object *p_node);
+ virtual bool handles(Object *p_node) const;
+ virtual void make_visible(bool p_visible);
+
+ GradientTextureEditorPlugin(EditorNode *p_node);
+ ~GradientTextureEditorPlugin();
+};
+
+#endif // GRADIENT_TEXTURE_EDITOR_PLUGIN_H
diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp
index fd26674a0e..9624030246 100644
--- a/editor/plugins/particles_editor_plugin.cpp
+++ b/editor/plugins/particles_editor_plugin.cpp
@@ -27,30 +27,24 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#if 0
#include "particles_editor_plugin.h"
#include "editor/plugins/spatial_editor_plugin.h"
#include "io/resource_loader.h"
-#include "servers/visual/particle_system_sw.h"
-
void ParticlesEditor::_node_removed(Node *p_node) {
- if(p_node==node) {
- node=NULL;
+ if (p_node == node) {
+ node = NULL;
hide();
}
-
}
-
-void ParticlesEditor::_resource_seleted(const String& p_res) {
+void ParticlesEditor::_resource_seleted(const String &p_res) {
//print_line("selected resource path: "+p_res);
}
-void ParticlesEditor::_node_selected(const NodePath& p_path){
-
+void ParticlesEditor::_node_selected(const NodePath &p_path) {
Node *sel = get_node(p_path);
if (!sel)
@@ -66,12 +60,11 @@ void ParticlesEditor::_node_selected(const NodePath& p_path){
geometry = vi->get_faces(VisualInstance::FACES_SOLID);
- if (geometry.size()==0) {
+ if (geometry.size() == 0) {
err_dialog->set_text(TTR("Node does not contain geometry (faces)."));
err_dialog->popup_centered_minsize();
return;
-
}
Transform geom_xform = node->get_global_transform().affine_inverse() * vi->get_global_transform();
@@ -79,20 +72,17 @@ void ParticlesEditor::_node_selected(const NodePath& p_path){
int gc = geometry.size();
PoolVector<Face3>::Write w = geometry.write();
-
- for(int i=0;i<gc;i++) {
- for(int j=0;j<3;j++) {
- w[i].vertex[j] = geom_xform.xform( w[i].vertex[j] );
+ for (int i = 0; i < gc; i++) {
+ for (int j = 0; j < 3; j++) {
+ w[i].vertex[j] = geom_xform.xform(w[i].vertex[j]);
}
}
-
w = PoolVector<Face3>::Write();
- emission_dialog->popup_centered(Size2(300,130));
+ emission_dialog->popup_centered(Size2(300, 130));
}
-
/*
void ParticlesEditor::_populate() {
@@ -112,74 +102,77 @@ void ParticlesEditor::_populate() {
void ParticlesEditor::_notification(int p_notification) {
- if (p_notification==NOTIFICATION_ENTER_TREE) {
- options->set_icon(options->get_popup()->get_icon("Particles","EditorIcons"));
-
+ if (p_notification == NOTIFICATION_ENTER_TREE) {
+ options->set_icon(options->get_popup()->get_icon("Particles", "EditorIcons"));
}
}
-
void ParticlesEditor::_menu_option(int p_option) {
-
- switch(p_option) {
+ switch (p_option) {
case MENU_OPTION_GENERATE_AABB: {
-
+#if 0
Transform globalizer = node->get_global_transform();
ParticleSystemSW pssw;
- for(int i=0;i<VS::PARTICLE_VAR_MAX;i++) {
+ for (int i = 0; i < VS::PARTICLE_VAR_MAX; i++) {
- pssw.particle_vars[i]=node->get_variable((Particles::Variable)i);
- pssw.particle_randomness[i]=node->get_randomness((Particles::Variable)i);
+ pssw.particle_vars[i] = node->get_variable((Particles::Variable)i);
+ pssw.particle_randomness[i] = node->get_randomness((Particles::Variable)i);
}
- pssw.emission_half_extents=node->get_emission_half_extents();
- pssw.emission_points=node->get_emission_points();
- pssw.emission_base_velocity=node->get_emission_base_velocity();
- pssw.amount=node->get_amount();
- pssw.gravity_normal=node->get_gravity_normal();
- pssw.emitting=true;
- pssw.height_from_velocity=node->has_height_from_velocity();
- pssw.color_phase_count=1;
-
+ pssw.emission_half_extents = node->get_emission_half_extents();
+ pssw.emission_points = node->get_emission_points();
+ pssw.emission_base_velocity = node->get_emission_base_velocity();
+ pssw.amount = node->get_amount();
+ pssw.gravity_normal = node->get_gravity_normal();
+ pssw.emitting = true;
+ pssw.height_from_velocity = node->has_height_from_velocity();
+ pssw.color_phase_count = 1;
ParticleSystemProcessSW pp;
- float delta=0.01;
- float lifetime=pssw.particle_vars[VS::PARTICLE_LIFETIME];
-
+ float delta = 0.01;
+ float lifetime = pssw.particle_vars[VS::PARTICLE_LIFETIME];
Transform localizer = globalizer.affine_inverse();
AABB aabb;
- for(float t=0;t<lifetime;t+=delta) {
+ for (float t = 0; t < lifetime; t += delta) {
- pp.process(&pssw,globalizer,delta);
- for(int i=0;i<pp.particle_data.size();i++) {
+ pp.process(&pssw, globalizer, delta);
+ for (int i = 0; i < pp.particle_data.size(); i++) {
Vector3 p = localizer.xform(pp.particle_data[i].pos);
- if (t==0 && i==0)
- aabb.pos=p;
+ if (t == 0 && i == 0)
+ aabb.pos = p;
else
aabb.expand_to(p);
}
}
- aabb.grow_by( aabb.get_longest_axis_size()*0.2);
+ aabb.grow_by(aabb.get_longest_axis_size() * 0.2);
node->set_visibility_aabb(aabb);
-
-
+#endif
} break;
case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH: {
-
+ Ref<ParticlesMaterial> material = node->get_process_material();
+ if (material.is_null()) {
+ EditorNode::get_singleton()->show_warning(TTR("A processor material of type 'ParticlesMaterial' is required."));
+ return;
+ }
emission_file_dialog->popup_centered_ratio();
} break;
case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE: {
-/*
+ Ref<ParticlesMaterial> material = node->get_process_material();
+ if (material.is_null()) {
+ EditorNode::get_singleton()->show_warning(TTR("A processor material of type 'ParticlesMaterial' is required."));
+ return;
+ }
+ /*
Node *root = get_scene()->get_root_node();
ERR_FAIL_COND(!root);
EditorNode *en = root->cast_to<EditorNode>();
@@ -192,50 +185,50 @@ void ParticlesEditor::_menu_option(int p_option) {
}
}
-
void ParticlesEditor::edit(Particles *p_particles) {
- node=p_particles;
-
+ node = p_particles;
}
void ParticlesEditor::_generate_emission_points() {
/// hacer codigo aca
- PoolVector<Vector3> points;
+ PoolVector<float> points;
+ bool use_normals = emission_fill->get_selected() == 1;
+ PoolVector<float> normals;
- if (emission_fill->get_selected()==0) {
+ if (emission_fill->get_selected() < 2) {
- float area_accum=0;
- Map<float,int> triangle_area_map;
- print_line("geometry size: "+itos(geometry.size()));
+ float area_accum = 0;
+ Map<float, int> triangle_area_map;
+ print_line("geometry size: " + itos(geometry.size()));
- for(int i=0;i<geometry.size();i++) {
+ for (int i = 0; i < geometry.size(); i++) {
float area = geometry[i].get_area();
- if (area<CMP_EPSILON)
+ if (area < CMP_EPSILON)
continue;
- triangle_area_map[area_accum]=i;
- area_accum+=area;
+ triangle_area_map[area_accum] = i;
+ area_accum += area;
}
- if (!triangle_area_map.size() || area_accum==0) {
+ if (!triangle_area_map.size() || area_accum == 0) {
err_dialog->set_text(TTR("Faces contain no area!"));
err_dialog->popup_centered_minsize();
return;
}
- int emissor_count=emission_amount->get_val();
+ int emissor_count = emission_amount->get_value();
- for(int i=0;i<emissor_count;i++) {
+ for (int i = 0; i < emissor_count; i++) {
- float areapos = Math::random(0,area_accum);
+ float areapos = Math::random(0.0f, area_accum);
- Map<float,int>::Element *E = triangle_area_map.find_closest(areapos);
+ Map<float, int>::Element *E = triangle_area_map.find_closest(areapos);
ERR_FAIL_COND(!E)
int index = E->get();
- ERR_FAIL_INDEX(index,geometry.size());
+ ERR_FAIL_INDEX(index, geometry.size());
// ok FINALLY get face
Face3 face = geometry[index];
@@ -243,13 +236,22 @@ void ParticlesEditor::_generate_emission_points() {
Vector3 pos = face.get_random_point_inside();
- points.push_back(pos);
+ points.push_back(pos.x);
+ points.push_back(pos.y);
+ points.push_back(pos.z);
+
+ if (use_normals) {
+ Vector3 normal = face.get_plane().normal;
+ normals.push_back(normal.x);
+ normals.push_back(normal.y);
+ normals.push_back(normal.z);
+ }
}
} else {
int gcount = geometry.size();
- if (gcount==0) {
+ if (gcount == 0) {
err_dialog->set_text(TTR("No faces!"));
err_dialog->popup_centered_minsize();
@@ -258,32 +260,32 @@ void ParticlesEditor::_generate_emission_points() {
PoolVector<Face3>::Read r = geometry.read();
- AABB aabb;
+ Rect3 aabb;
- for(int i=0;i<gcount;i++) {
+ for (int i = 0; i < gcount; i++) {
- for(int j=0;j<3;j++) {
+ for (int j = 0; j < 3; j++) {
- if (i==0 && j==0)
- aabb.pos=r[i].vertex[j];
+ if (i == 0 && j == 0)
+ aabb.pos = r[i].vertex[j];
else
aabb.expand_to(r[i].vertex[j]);
}
}
- int emissor_count=emission_amount->get_val();
+ int emissor_count = emission_amount->get_value();
- for(int i=0;i<emissor_count;i++) {
+ for (int i = 0; i < emissor_count; i++) {
- int attempts=5;
+ int attempts = 5;
- for(int j=0;j<attempts;j++) {
+ for (int j = 0; j < attempts; j++) {
Vector3 dir;
- dir[Math::rand()%3]=1.0;
- Vector3 ofs = Vector3(1,1,1)-dir;
- ofs=(Vector3(1,1,1)-dir)*Vector3(Math::randf(),Math::randf(),Math::randf())*aabb.size;
- ofs+=aabb.pos;
+ dir[Math::rand() % 3] = 1.0;
+ Vector3 ofs = Vector3(1, 1, 1) - dir;
+ ofs = (Vector3(1, 1, 1) - dir) * Vector3(Math::randf(), Math::randf(), Math::randf()) * aabb.size;
+ ofs += aabb.pos;
Vector3 ofsv = ofs + aabb.size * dir;
@@ -291,135 +293,172 @@ void ParticlesEditor::_generate_emission_points() {
ofs -= dir;
ofsv += dir;
- float max=-1e7,min=1e7;
+ float max = -1e7, min = 1e7;
- for(int k=0;k<gcount;k++) {
+ for (int k = 0; k < gcount; k++) {
- const Face3& f3 = r[k];
+ const Face3 &f3 = r[k];
Vector3 res;
- if (f3.intersects_segment(ofs,ofsv,&res)) {
+ if (f3.intersects_segment(ofs, ofsv, &res)) {
- res-=ofs;
+ res -= ofs;
float d = dir.dot(res);
- if (d<min)
- min=d;
- if (d>max)
- max=d;
-
+ if (d < min)
+ min = d;
+ if (d > max)
+ max = d;
}
}
-
- if (max<min)
+ if (max < min)
continue; //lost attempt
- float val = min + (max-min)*Math::randf();
+ float val = min + (max - min) * Math::randf();
Vector3 point = ofs + dir * val;
- points.push_back(point);
+ points.push_back(point.x);
+ points.push_back(point.y);
+ points.push_back(point.z);
break;
}
}
}
- //print_line("point count: "+itos(points.size()));
- node->set_emission_points(points);
+ int point_count = points.size() / 3;
+
+ int w = 2048;
+ int h = (point_count / 2048) + 1;
+ PoolVector<uint8_t> point_img;
+ point_img.resize(w * h * 3 * sizeof(float));
+
+ {
+ PoolVector<uint8_t>::Write iw = point_img.write();
+ zeromem(iw.ptr(), w * h * 3 * sizeof(float));
+ PoolVector<float>::Read r = points.read();
+ copymem(iw.ptr(), r.ptr(), point_count * sizeof(float) * 3);
+ }
+
+ Image image(w, h, false, Image::FORMAT_RGBF, point_img);
+
+ Ref<ImageTexture> tex;
+ tex.instance();
+ tex->create_from_image(image, Texture::FLAG_FILTER);
+
+ Ref<ParticlesMaterial> material = node->get_process_material();
+ ERR_FAIL_COND(material.is_null());
+
+ if (use_normals) {
+
+ material->set_emission_shape(ParticlesMaterial::EMISSION_SHAPE_DIRECTED_POINTS);
+ material->set_emission_point_count(point_count);
+ material->set_emission_point_texture(tex);
+
+ PoolVector<uint8_t> point_img2;
+ point_img2.resize(w * h * 3 * sizeof(float));
+
+ {
+ PoolVector<uint8_t>::Write iw = point_img2.write();
+ zeromem(iw.ptr(), w * h * 3 * sizeof(float));
+ PoolVector<float>::Read r = normals.read();
+ copymem(iw.ptr(), r.ptr(), point_count * sizeof(float) * 3);
+ }
+
+ Image image2(w, h, false, Image::FORMAT_RGBF, point_img2);
+
+ Ref<ImageTexture> tex2;
+ tex2.instance();
+ tex2->create_from_image(image2, Texture::FLAG_FILTER);
+
+ material->set_emission_normal_texture(tex2);
+ } else {
+
+ material->set_emission_shape(ParticlesMaterial::EMISSION_SHAPE_POINTS);
+ material->set_emission_point_count(point_count);
+ material->set_emission_point_texture(tex);
+ }
+
+ //print_line("point count: "+itos(points.size()));
+ //node->set_emission_points(points);
}
void ParticlesEditor::_bind_methods() {
- ClassDB::bind_method("_menu_option",&ParticlesEditor::_menu_option);
- ClassDB::bind_method("_resource_seleted",&ParticlesEditor::_resource_seleted);
- ClassDB::bind_method("_node_selected",&ParticlesEditor::_node_selected);
- ClassDB::bind_method("_generate_emission_points",&ParticlesEditor::_generate_emission_points);
+ ClassDB::bind_method("_menu_option", &ParticlesEditor::_menu_option);
+ ClassDB::bind_method("_resource_seleted", &ParticlesEditor::_resource_seleted);
+ ClassDB::bind_method("_node_selected", &ParticlesEditor::_node_selected);
+ ClassDB::bind_method("_generate_emission_points", &ParticlesEditor::_generate_emission_points);
//ClassDB::bind_method("_populate",&ParticlesEditor::_populate);
-
}
ParticlesEditor::ParticlesEditor() {
- particles_editor_hb = memnew ( HBoxContainer );
+ particles_editor_hb = memnew(HBoxContainer);
SpatialEditor::get_singleton()->add_control_to_menu_panel(particles_editor_hb);
- options = memnew( MenuButton );
+ options = memnew(MenuButton);
particles_editor_hb->add_child(options);
particles_editor_hb->hide();
options->set_text("Particles");
- options->get_popup()->add_item(TTR("Generate AABB"),MENU_OPTION_GENERATE_AABB);
+ options->get_popup()->add_item(TTR("Generate AABB"), MENU_OPTION_GENERATE_AABB);
options->get_popup()->add_separator();
- options->get_popup()->add_item(TTR("Create Emitter From Mesh"),MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH);
- options->get_popup()->add_item(TTR("Create Emitter From Node"),MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE);
- options->get_popup()->add_item(TTR("Clear Emitter"),MENU_OPTION_CLEAR_EMISSION_VOLUME);
+ options->get_popup()->add_item(TTR("Create Emission Points From Mesh"), MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH);
+ options->get_popup()->add_item(TTR("Create Emission Points From Node"), MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE);
+ // options->get_popup()->add_item(TTR("Clear Emitter"), MENU_OPTION_CLEAR_EMISSION_VOLUME);
- options->get_popup()->connect("id_pressed", this,"_menu_option");
+ options->get_popup()->connect("id_pressed", this, "_menu_option");
- emission_dialog = memnew( ConfirmationDialog );
+ emission_dialog = memnew(ConfirmationDialog);
emission_dialog->set_title(TTR("Create Emitter"));
add_child(emission_dialog);
- Label *l = memnew(Label);
- l->set_pos(Point2(5,5));
- l->set_text(TTR("Emission Positions:"));
- emission_dialog->add_child(l);
-
+ VBoxContainer *emd_vb = memnew(VBoxContainer);
+ emission_dialog->add_child(emd_vb);
- emission_amount = memnew( SpinBox );
- emission_amount->set_anchor(MARGIN_RIGHT,ANCHOR_END);
- emission_amount->set_begin( Point2(20,23));
- emission_amount->set_end( Point2(5,25));
+ emission_amount = memnew(SpinBox);
emission_amount->set_min(1);
- emission_amount->set_max(65536);
- emission_amount->set_val(512);
- emission_dialog->add_child(emission_amount);
- emission_dialog->get_ok()->set_text(TTR("Create"));
- emission_dialog->connect("confirmed",this,"_generate_emission_points");
-
- l = memnew(Label);
- l->set_pos(Point2(5,50));
- l->set_text(TTR("Emission Fill:"));
- emission_dialog->add_child(l);
-
- emission_fill = memnew( OptionButton );
- emission_fill->set_anchor(MARGIN_RIGHT,ANCHOR_END);
- emission_fill->set_begin( Point2(20,70));
- emission_fill->set_end( Point2(5,75));
- emission_fill->add_item(TTR("Surface"));
+ emission_amount->set_max(100000);
+ emission_amount->set_value(512);
+ emd_vb->add_margin_child(TTR("Emission Points:"), emission_amount);
+
+ emission_fill = memnew(OptionButton);
+ emission_fill->add_item(TTR("Surface Points"));
+ emission_fill->add_item(TTR("Surface Points+Normal (Directed)"));
emission_fill->add_item(TTR("Volume"));
- emission_dialog->add_child(emission_fill);
+ emd_vb->add_margin_child(TTR("Emission Source: "), emission_fill);
+
+ emission_dialog->get_ok()->set_text(TTR("Create"));
+ emission_dialog->connect("confirmed", this, "_generate_emission_points");
- err_dialog = memnew( ConfirmationDialog );
+ err_dialog = memnew(ConfirmationDialog);
//err_dialog->get_cancel()->hide();
add_child(err_dialog);
-
- emission_file_dialog = memnew( EditorFileDialog );
+ emission_file_dialog = memnew(EditorFileDialog);
add_child(emission_file_dialog);
- emission_file_dialog->connect("file_selected",this,"_resource_seleted");
- emission_tree_dialog = memnew( SceneTreeDialog );
+ emission_file_dialog->connect("file_selected", this, "_resource_seleted");
+ emission_tree_dialog = memnew(SceneTreeDialog);
add_child(emission_tree_dialog);
- emission_tree_dialog->connect("selected",this,"_node_selected");
+ emission_tree_dialog->connect("selected", this, "_node_selected");
List<String> extensions;
- ResourceLoader::get_recognized_extensions_for_type("Mesh",&extensions);
+ ResourceLoader::get_recognized_extensions_for_type("Mesh", &extensions);
emission_file_dialog->clear_filters();
- for(int i=0;i<extensions.size();i++) {
+ for (int i = 0; i < extensions.size(); i++) {
- emission_file_dialog->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper());
+ emission_file_dialog->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
}
emission_file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE);
//options->set_anchor(MARGIN_LEFT,Control::ANCHOR_END);
//options->set_anchor(MARGIN_RIGHT,Control::ANCHOR_END);
-
}
-
void ParticlesEditorPlugin::edit(Object *p_object) {
particles_editor->edit(p_object->cast_to<Particles>());
@@ -427,7 +466,7 @@ void ParticlesEditorPlugin::edit(Object *p_object) {
bool ParticlesEditorPlugin::handles(Object *p_object) const {
- return p_object->is_type("Particles");
+ return p_object->is_class("Particles");
}
void ParticlesEditorPlugin::make_visible(bool p_visible) {
@@ -440,21 +479,16 @@ void ParticlesEditorPlugin::make_visible(bool p_visible) {
particles_editor->hide();
particles_editor->edit(NULL);
}
-
}
ParticlesEditorPlugin::ParticlesEditorPlugin(EditorNode *p_node) {
- editor=p_node;
- particles_editor = memnew( ParticlesEditor );
+ editor = p_node;
+ particles_editor = memnew(ParticlesEditor);
editor->get_viewport()->add_child(particles_editor);
particles_editor->hide();
}
-
-ParticlesEditorPlugin::~ParticlesEditorPlugin()
-{
+ParticlesEditorPlugin::~ParticlesEditorPlugin() {
}
-
-#endif
diff --git a/editor/plugins/particles_editor_plugin.h b/editor/plugins/particles_editor_plugin.h
index 420e20d641..b3394d879e 100644
--- a/editor/plugins/particles_editor_plugin.h
+++ b/editor/plugins/particles_editor_plugin.h
@@ -37,17 +37,16 @@
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
-#if 0
+
class ParticlesEditor : public Control {
- GDCLASS(ParticlesEditor, Control );
+ GDCLASS(ParticlesEditor, Control);
Panel *panel;
MenuButton *options;
HBoxContainer *particles_editor_hb;
Particles *node;
-
EditorFileDialog *emission_file_dialog;
SceneTreeDialog *emission_tree_dialog;
@@ -57,9 +56,6 @@ class ParticlesEditor : public Control {
SpinBox *emission_amount;
OptionButton *emission_fill;
-
-
-
enum Menu {
MENU_OPTION_GENERATE_AABB,
@@ -72,35 +68,33 @@ class ParticlesEditor : public Control {
PoolVector<Face3> geometry;
void _generate_emission_points();
- void _resource_seleted(const String& p_res);
- void _node_selected(const NodePath& p_path);
+ void _resource_seleted(const String &p_res);
+ void _node_selected(const NodePath &p_path);
void _menu_option(int);
void _populate();
-friend class ParticlesEditorPlugin;
+ friend class ParticlesEditorPlugin;
protected:
-
void _notification(int p_notification);
void _node_removed(Node *p_node);
static void _bind_methods();
-public:
+public:
void edit(Particles *p_particles);
ParticlesEditor();
};
class ParticlesEditorPlugin : public EditorPlugin {
- GDCLASS( ParticlesEditorPlugin, EditorPlugin );
+ GDCLASS(ParticlesEditorPlugin, EditorPlugin);
ParticlesEditor *particles_editor;
EditorNode *editor;
public:
-
virtual String get_name() const { return "Particles"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_node);
@@ -109,8 +103,6 @@ public:
ParticlesEditorPlugin(EditorNode *p_node);
~ParticlesEditorPlugin();
-
};
#endif // PARTICLES_EDITOR_PLUGIN_H
-#endif
diff --git a/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp
index 0b3587bc5e..6fcda001ee 100644
--- a/editor/plugins/path_editor_plugin.cpp
+++ b/editor/plugins/path_editor_plugin.cpp
@@ -530,16 +530,16 @@ PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) {
editor=p_node;
singleton=this;
- path_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
- path_material->set_parameter( FixedSpatialMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.8) );
- path_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+ path_material = Ref<SpatialMaterial>( memnew( SpatialMaterial ));
+ path_material->set_parameter( SpatialMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.8) );
+ path_material->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA, true);
path_material->set_line_width(3);
path_material->set_flag(Material::FLAG_DOUBLE_SIDED,true);
path_material->set_flag(Material::FLAG_UNSHADED,true);
- path_thin_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
- path_thin_material->set_parameter( FixedSpatialMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.4) );
- path_thin_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+ path_thin_material = Ref<SpatialMaterial>( memnew( SpatialMaterial ));
+ path_thin_material->set_parameter( SpatialMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.4) );
+ path_thin_material->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA, true);
path_thin_material->set_line_width(1);
path_thin_material->set_flag(Material::FLAG_DOUBLE_SIDED,true);
path_thin_material->set_flag(Material::FLAG_UNSHADED,true);
diff --git a/editor/plugins/path_editor_plugin.h b/editor/plugins/path_editor_plugin.h
index 9d0f6eb9f2..131cf11ef8 100644
--- a/editor/plugins/path_editor_plugin.h
+++ b/editor/plugins/path_editor_plugin.h
@@ -78,8 +78,8 @@ public:
Path *get_edited_path() { return path; }
static PathEditorPlugin* singleton;
- Ref<FixedSpatialMaterial> path_material;
- Ref<FixedSpatialMaterial> path_thin_material;
+ Ref<SpatialMaterial> path_material;
+ Ref<SpatialMaterial> path_thin_material;
virtual bool forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event);
//virtual bool forward_gui_input(const InputEvent& p_event) { return collision_polygon_editor->forward_gui_input(p_event); }
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 11dfb7b910..37782ed173 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -137,14 +137,35 @@ void ShaderTextEditor::_load_theme_settings() {
}*/
}
+void ShaderTextEditor::_check_shader_mode() {
+
+ String type = ShaderLanguage::get_shader_type(get_text_edit()->get_text());
+
+ print_line("type is: " + type);
+ Shader::Mode mode;
+
+ if (type == "canvas_item") {
+ mode = Shader::MODE_CANVAS_ITEM;
+ } else if (type == "particles") {
+ mode = Shader::MODE_PARTICLES;
+ } else {
+ mode = Shader::MODE_SPATIAL;
+ }
+
+ if (shader->get_mode() != mode) {
+ shader->set_code(get_text_edit()->get_text());
+ _load_theme_settings();
+ }
+}
+
void ShaderTextEditor::_code_complete_script(const String &p_code, List<String> *r_options) {
- print_line("code complete");
+ _check_shader_mode();
ShaderLanguage sl;
String calltip;
- Error err = sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())), r_options, calltip);
+ Error err = sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), r_options, calltip);
if (calltip != "") {
get_text_edit()->set_code_hint(calltip);
@@ -153,13 +174,15 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<String>
void ShaderTextEditor::_validate_script() {
+ _check_shader_mode();
+
String code = get_text_edit()->get_text();
//List<StringName> params;
//shader->get_param_list(&params);
ShaderLanguage sl;
- Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())));
+ Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types());
if (err != OK) {
String error_text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text();
diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h
index 4a56c14ecb..14caf4ab49 100644
--- a/editor/plugins/shader_editor_plugin.h
+++ b/editor/plugins/shader_editor_plugin.h
@@ -44,6 +44,8 @@ class ShaderTextEditor : public CodeTextEditor {
Ref<Shader> shader;
+ void _check_shader_mode();
+
protected:
static void _bind_methods();
virtual void _load_theme_settings();
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index c00652bc35..5e0901f9be 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -524,7 +524,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hil
return false;
if (get_selected_count() == 0) {
if (p_hilite_only)
- spatial_editor->select_gizmo_hilight_axis(-1);
+ spatial_editor->select_gizmo_highlight_axis(-1);
return false;
}
@@ -558,7 +558,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hil
if (p_hilite_only) {
- spatial_editor->select_gizmo_hilight_axis(col_axis);
+ spatial_editor->select_gizmo_highlight_axis(col_axis);
} else {
//handle rotate
@@ -598,7 +598,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hil
if (p_hilite_only) {
- spatial_editor->select_gizmo_hilight_axis(col_axis + 3);
+ spatial_editor->select_gizmo_highlight_axis(col_axis + 3);
} else {
//handle rotate
_edit.mode = TRANSFORM_ROTATE;
@@ -610,7 +610,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hil
}
if (p_hilite_only)
- spatial_editor->select_gizmo_hilight_axis(-1);
+ spatial_editor->select_gizmo_highlight_axis(-1);
return false;
}
@@ -1069,7 +1069,7 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
spatial_editor->set_over_gizmo_handle(selected_handle);
spatial_editor->get_selected()->update_gizmo();
if (selected_handle != -1)
- spatial_editor->select_gizmo_hilight_axis(-1);
+ spatial_editor->select_gizmo_highlight_axis(-1);
}
}
}
@@ -2229,7 +2229,7 @@ SpatialEditorSelectedItem::~SpatialEditorSelectedItem() {
VisualServer::get_singleton()->free(sbox_instance);
}
-void SpatialEditor::select_gizmo_hilight_axis(int p_axis) {
+void SpatialEditor::select_gizmo_highlight_axis(int p_axis) {
for (int i = 0; i < 3; i++) {
@@ -2329,12 +2329,12 @@ void SpatialEditor::_generate_selection_box() {
st->add_vertex(b);
}
- Ref<FixedSpatialMaterial> mat = memnew(FixedSpatialMaterial);
- mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
+ Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
+ mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
mat->set_albedo(Color(1, 1, 1));
- mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- mat->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
st->set_material(mat);
selection_box = st->commit();
}
@@ -2888,12 +2888,12 @@ void SpatialEditor::_init_indicators() {
{
indicator_mat.instance();
- indicator_mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- //indicator_mat->set_flag(FixedSpatialMaterial::FLAG_ONTOP,true);
- indicator_mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- indicator_mat->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ indicator_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ //indicator_mat->set_flag(SpatialMaterial::FLAG_ONTOP,true);
+ indicator_mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ indicator_mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- indicator_mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ indicator_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
PoolVector<Color> grid_colors[3];
PoolVector<Vector3> grid_points[3];
@@ -2980,7 +2980,7 @@ void SpatialEditor::_init_indicators() {
cursor_points.push_back(Vector3(0, 0, -cs));
cursor_material.instance();
cursor_material->set_albedo(Color(0, 1, 1));
- cursor_material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
+ cursor_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
Array d;
d.resize(VS::ARRAY_MAX);
@@ -3000,10 +3000,10 @@ void SpatialEditor::_init_indicators() {
float gizmo_alph = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_opacity");
- gizmo_hl = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
- gizmo_hl->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- gizmo_hl->set_flag(FixedSpatialMaterial::FLAG_ONTOP, true);
- gizmo_hl->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ gizmo_hl = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ gizmo_hl->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ gizmo_hl->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ gizmo_hl->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
gizmo_hl->set_albedo(Color(1, 1, 1, gizmo_alph + 0.2f));
for (int i = 0; i < 3; i++) {
@@ -3011,10 +3011,10 @@ void SpatialEditor::_init_indicators() {
move_gizmo[i] = Ref<Mesh>(memnew(Mesh));
rotate_gizmo[i] = Ref<Mesh>(memnew(Mesh));
- Ref<FixedSpatialMaterial> mat = memnew(FixedSpatialMaterial);
- mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- mat->set_flag(FixedSpatialMaterial::FLAG_ONTOP, true);
- mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
+ mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ mat->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
Color col;
col[i] = 1.0;
col.a = gizmo_alph;
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index e0d2a38956..0dedd6ce6d 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -323,8 +323,8 @@ private:
bool grid_enabled;
Ref<Mesh> move_gizmo[3], rotate_gizmo[3];
- Ref<FixedSpatialMaterial> gizmo_color[3];
- Ref<FixedSpatialMaterial> gizmo_hl;
+ Ref<SpatialMaterial> gizmo_color[3];
+ Ref<SpatialMaterial> gizmo_hl;
int over_gizmo_handle;
@@ -333,8 +333,8 @@ private:
RID indicators_instance;
RID cursor_mesh;
RID cursor_instance;
- Ref<FixedSpatialMaterial> indicator_mat;
- Ref<FixedSpatialMaterial> cursor_material;
+ Ref<SpatialMaterial> indicator_mat;
+ Ref<SpatialMaterial> cursor_material;
/*
struct Selected {
@@ -484,7 +484,7 @@ public:
void update_transform_gizmo();
- void select_gizmo_hilight_axis(int p_axis);
+ void select_gizmo_highlight_axis(int p_axis);
void set_custom_camera(Node *p_camera) { custom_camera = p_camera; }
void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; }
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index 6dee151d99..2ae6f6a3d7 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -58,7 +58,7 @@ void TileSetEditor::_import_scene(Node *scene, Ref<TileSet> p_library, bool p_me
Sprite *mi = child->cast_to<Sprite>();
Ref<Texture> texture = mi->get_texture();
- Ref<CanvasItemMaterial> material = mi->get_material();
+ Ref<ShaderMaterial> material = mi->get_material();
if (texture.is_null())
continue;
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index cc26769939..f2a79a2f47 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -3846,8 +3846,8 @@ void PropertyEditor::_item_edited() {
} break;
case Variant::BOOL: {
- _edit_set(name, item->is_checked(1), refresh_all);
item->set_tooltip(1, item->is_checked(1) ? "True" : "False");
+ _edit_set(name, item->is_checked(1), refresh_all);
} break;
case Variant::INT:
case Variant::REAL: {
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 3310405ae9..5f0bc8841b 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -1113,6 +1113,7 @@ SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_ope
tree->set_anchor(MARGIN_BOTTOM, ANCHOR_END);
tree->set_begin(Point2(0, p_label ? 18 : 0));
tree->set_end(Point2(0, 0));
+ tree->add_constant_override("button_margin", 0);
add_child(tree);
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index d1a8aa62e5..47c89419a0 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -359,20 +359,28 @@ ScriptCreateDialog::ScriptCreateDialog() {
language_menu = memnew(OptionButton);
vb->add_margin_child(TTR("Language"), language_menu);
+ int default_lang = 0;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
- language_menu->add_item(ScriptServer::get_language(i)->get_name());
+ String lang = ScriptServer::get_language(i)->get_name();
+ language_menu->add_item(lang);
+ if (lang == "GDScript") {
+ default_lang = i;
+ }
}
editor_settings = EditorSettings::get_singleton();
String last_selected_language = editor_settings->get_project_metadata("script_setup", "last_selected_language", "");
- if (last_selected_language != "")
- for (int i = 0; i < language_menu->get_item_count(); i++)
+ if (last_selected_language != "") {
+ for (int i = 0; i < language_menu->get_item_count(); i++) {
if (language_menu->get_item_text(i) == last_selected_language) {
language_menu->select(i);
break;
- } else
- language_menu->select(0);
+ }
+ }
+ } else {
+ language_menu->select(default_lang);
+ }
language_menu->connect("item_selected", this, "_lang_changed");
diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp
index 8a24ed2b2f..385de3fa18 100644
--- a/editor/spatial_editor_gizmos.cpp
+++ b/editor/spatial_editor_gizmos.cpp
@@ -70,10 +70,6 @@ void EditorSpatialGizmo::Instance::create_instance(Spatial *p_base) {
instance = VS::get_singleton()->instance_create2(mesh->get_rid(), p_base->get_world()->get_scenario());
VS::get_singleton()->instance_attach_object_instance_ID(instance, p_base->get_instance_ID());
- if (billboard)
- VS::get_singleton()->instance_geometry_set_flag(instance, VS::INSTANCE_FLAG_BILLBOARD, true);
- if (unscaled)
- VS::get_singleton()->instance_geometry_set_flag(instance, VS::INSTANCE_FLAG_DEPH_SCALE, true);
if (skeleton.is_valid())
VS::get_singleton()->instance_attach_skeleton(instance, skeleton);
if (extra_margin)
@@ -228,7 +224,6 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_bi
Array a;
a.resize(VS::ARRAY_MAX);
a[VS::ARRAY_VERTEX] = p_handles;
- print_line("handles?: " + itos(p_handles.size()));
PoolVector<Color> colors;
{
colors.resize(p_handles.size());
@@ -243,7 +238,10 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_bi
}
a[VS::ARRAY_COLOR] = colors;
mesh->add_surface_from_arrays(Mesh::PRIMITIVE_POINTS, a);
- mesh->surface_set_material(0, SpatialEditorGizmos::singleton->handle2_material);
+ if (p_billboard)
+ mesh->surface_set_material(0, SpatialEditorGizmos::singleton->handle2_material_billboard);
+ else
+ mesh->surface_set_material(0, SpatialEditorGizmos::singleton->handle2_material);
if (p_billboard) {
float md = 0;
@@ -390,7 +388,7 @@ bool EditorSpatialGizmo::intersect_ray(const Camera *p_camera, const Point2 &p_p
Transform t = spatial_node->get_global_transform();
t.orthonormalize();
if (billboard_handle) {
- t.set_look_at(t.origin, t.origin + p_camera->get_transform().basis.get_axis(2), p_camera->get_transform().basis.get_axis(1));
+ t.set_look_at(t.origin, t.origin - p_camera->get_transform().basis.get_axis(2), p_camera->get_transform().basis.get_axis(1));
}
float min_d = 1e20;
@@ -452,7 +450,7 @@ bool EditorSpatialGizmo::intersect_ray(const Camera *p_camera, const Point2 &p_p
const Vector3 *vptr = collision_segments.ptr();
Transform t = spatial_node->get_global_transform();
if (billboard_handle) {
- t.set_look_at(t.origin, t.origin + p_camera->get_transform().basis.get_axis(2), p_camera->get_transform().basis.get_axis(1));
+ t.set_look_at(t.origin, t.origin - p_camera->get_transform().basis.get_axis(2), p_camera->get_transform().basis.get_axis(1));
}
Vector3 cp;
@@ -504,7 +502,7 @@ bool EditorSpatialGizmo::intersect_ray(const Camera *p_camera, const Point2 &p_p
Transform gt = spatial_node->get_global_transform();
if (billboard_handle) {
- gt.set_look_at(gt.origin, gt.origin + p_camera->get_transform().basis.get_axis(2), p_camera->get_transform().basis.get_axis(1));
+ gt.set_look_at(gt.origin, gt.origin - p_camera->get_transform().basis.get_axis(2), p_camera->get_transform().basis.get_axis(1));
}
Transform ai = gt.affine_inverse();
@@ -777,7 +775,7 @@ void LightSpatialGizmo::redraw() {
points.push_back(Vector3(b.x, b.y, 0));
}
- add_lines(points, SpatialEditorGizmos::singleton->light_material, true);
+ add_lines(points, SpatialEditorGizmos::singleton->light_material_omni, true);
add_collision_segments(points);
add_unscaled_billboard(SpatialEditorGizmos::singleton->light_material_omni_icon, 0.05);
@@ -2994,24 +2992,24 @@ Ref<SpatialEditorGizmo> SpatialEditorGizmos::get_gizmo(Spatial *p_spatial) {
return Ref<SpatialEditorGizmo>();
}
-Ref<FixedSpatialMaterial> SpatialEditorGizmos::create_line_material(const Color &p_base_color) {
+Ref<SpatialMaterial> SpatialEditorGizmos::create_line_material(const Color &p_base_color) {
- Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
- line_material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
+ Ref<SpatialMaterial> line_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ line_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
line_material->set_line_width(3.0);
- line_material->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
- //line_material->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- //->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ line_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ //line_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ //->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
line_material->set_albedo(p_base_color);
return line_material;
}
-Ref<FixedSpatialMaterial> SpatialEditorGizmos::create_solid_material(const Color &p_base_color) {
+Ref<SpatialMaterial> SpatialEditorGizmos::create_solid_material(const Color &p_base_color) {
- Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
- line_material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- line_material->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ Ref<SpatialMaterial> line_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ line_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ line_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
line_material->set_albedo(p_base_color);
return line_material;
@@ -3021,58 +3019,65 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
singleton = this;
- handle_material = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
- handle_material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
+ handle_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ handle_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
handle_material->set_albedo(Color(0.8, 0.8, 0.8));
+ handle_material_billboard = handle_material->duplicate();
+ handle_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
- handle2_material = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
- handle2_material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- handle2_material->set_flag(FixedSpatialMaterial::FLAG_USE_POINT_SIZE, true);
+ handle2_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ handle2_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ handle2_material->set_flag(SpatialMaterial::FLAG_USE_POINT_SIZE, true);
handle_t = SpatialEditor::get_singleton()->get_icon("Editor3DHandle", "EditorIcons");
handle2_material->set_point_size(handle_t->get_width());
- handle2_material->set_texture(FixedSpatialMaterial::TEXTURE_ALBEDO, handle_t);
+ handle2_material->set_texture(SpatialMaterial::TEXTURE_ALBEDO, handle_t);
handle2_material->set_albedo(Color(1, 1, 1));
- handle2_material->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
- handle2_material->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- handle2_material->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ handle2_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ handle2_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ handle2_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ handle2_material_billboard = handle2_material->duplicate();
+ handle2_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
light_material = create_line_material(Color(1, 1, 0.2));
-
- light_material_omni_icon = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
- light_material_omni_icon->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- light_material_omni_icon->set_cull_mode(FixedSpatialMaterial::CULL_DISABLED);
- light_material_omni_icon->set_depth_draw_mode(FixedSpatialMaterial::DEPTH_DRAW_DISABLED);
- light_material_omni_icon->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ light_material_omni = create_line_material(Color(1, 1, 0.2));
+ light_material_omni->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
+
+ light_material_omni_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ light_material_omni_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ light_material_omni_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ light_material_omni_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
+ light_material_omni_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
light_material_omni_icon->set_albedo(Color(1, 1, 1, 0.9));
- light_material_omni_icon->set_texture(FixedSpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoLight", "EditorIcons"));
-
- light_material_directional_icon = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
- light_material_directional_icon->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- light_material_directional_icon->set_cull_mode(FixedSpatialMaterial::CULL_DISABLED);
- light_material_directional_icon->set_depth_draw_mode(FixedSpatialMaterial::DEPTH_DRAW_DISABLED);
- light_material_directional_icon->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ light_material_omni_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoLight", "EditorIcons"));
+ light_material_omni_icon->set_flag(SpatialMaterial::FLAG_FIXED_SIZE, true);
+
+ light_material_directional_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ light_material_directional_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ light_material_directional_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ light_material_directional_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
+ light_material_directional_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
light_material_directional_icon->set_albedo(Color(1, 1, 1, 0.9));
- light_material_directional_icon->set_texture(FixedSpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight", "EditorIcons"));
+ light_material_directional_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight", "EditorIcons"));
camera_material = create_line_material(Color(1.0, 0.5, 1.0));
navmesh_edge_material = create_line_material(Color(0.1, 0.8, 1.0));
navmesh_solid_material = create_solid_material(Color(0.1, 0.8, 1.0, 0.4));
- navmesh_edge_material->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, false);
- navmesh_edge_material->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, false);
- navmesh_solid_material->set_cull_mode(FixedSpatialMaterial::CULL_DISABLED);
+ navmesh_edge_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, false);
+ navmesh_edge_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, false);
+ navmesh_solid_material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
navmesh_edge_material_disabled = create_line_material(Color(1.0, 0.8, 0.1));
navmesh_solid_material_disabled = create_solid_material(Color(1.0, 0.8, 0.1, 0.4));
- navmesh_edge_material_disabled->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, false);
- navmesh_edge_material_disabled->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, false);
- navmesh_solid_material_disabled->set_cull_mode(FixedSpatialMaterial::CULL_DISABLED);
+ navmesh_edge_material_disabled->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, false);
+ navmesh_edge_material_disabled->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, false);
+ navmesh_solid_material_disabled->set_cull_mode(SpatialMaterial::CULL_DISABLED);
skeleton_material = create_line_material(Color(0.6, 1.0, 0.3));
- skeleton_material->set_cull_mode(FixedSpatialMaterial::CULL_DISABLED);
- skeleton_material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- skeleton_material->set_flag(FixedSpatialMaterial::FLAG_ONTOP, true);
- skeleton_material->set_depth_draw_mode(FixedSpatialMaterial::DEPTH_DRAW_DISABLED);
+ skeleton_material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ skeleton_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ skeleton_material->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ skeleton_material->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
//position 3D Shared mesh
@@ -3095,11 +3100,11 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7));
cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7));
- Ref<FixedSpatialMaterial> mat = memnew(FixedSpatialMaterial);
- mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- mat->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
+ mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
mat->set_line_width(3);
Array d;
d.resize(VS::ARRAY_MAX);
@@ -3119,11 +3124,11 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7));
cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7));
- Ref<FixedSpatialMaterial> mat = memnew(FixedSpatialMaterial);
- mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- mat->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
+ mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
mat->set_line_width(3);
Array d;
d.resize(VS::ARRAY_MAX);
@@ -3133,13 +3138,13 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
listener_line_mesh->surface_set_material(0, mat);
}
- sample_player_icon = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
- sample_player_icon->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- sample_player_icon->set_cull_mode(FixedSpatialMaterial::CULL_DISABLED);
- sample_player_icon->set_depth_draw_mode(FixedSpatialMaterial::DEPTH_DRAW_DISABLED);
- sample_player_icon->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ sample_player_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ sample_player_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ sample_player_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ sample_player_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
+ sample_player_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
sample_player_icon->set_albedo(Color(1, 1, 1, 0.9));
- sample_player_icon->set_texture(FixedSpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoSpatialSamplePlayer", "EditorIcons"));
+ sample_player_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoSpatialSamplePlayer", "EditorIcons"));
room_material = create_line_material(Color(1.0, 0.6, 0.9));
portal_material = create_line_material(Color(1.0, 0.8, 0.6));
@@ -3152,29 +3157,29 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
gi_probe_material_internal = create_line_material(Color(0.5, 0.8, 0.3, 0.1));
joint_material = create_line_material(Color(0.6, 0.8, 1.0));
- stream_player_icon = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
- stream_player_icon->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- stream_player_icon->set_cull_mode(FixedSpatialMaterial::CULL_DISABLED);
- stream_player_icon->set_depth_draw_mode(FixedSpatialMaterial::DEPTH_DRAW_DISABLED);
- stream_player_icon->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ stream_player_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ stream_player_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ stream_player_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ stream_player_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
+ stream_player_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
stream_player_icon->set_albedo(Color(1, 1, 1, 0.9));
- stream_player_icon->set_texture(FixedSpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoSpatialStreamPlayer", "EditorIcons"));
+ stream_player_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoSpatialStreamPlayer", "EditorIcons"));
- visibility_notifier_icon = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
- visibility_notifier_icon->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- visibility_notifier_icon->set_cull_mode(FixedSpatialMaterial::CULL_DISABLED);
- visibility_notifier_icon->set_depth_draw_mode(FixedSpatialMaterial::DEPTH_DRAW_DISABLED);
- visibility_notifier_icon->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ visibility_notifier_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ visibility_notifier_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ visibility_notifier_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ visibility_notifier_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
+ visibility_notifier_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
visibility_notifier_icon->set_albedo(Color(1, 1, 1, 0.9));
- visibility_notifier_icon->set_texture(FixedSpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("Visible", "EditorIcons"));
+ visibility_notifier_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("Visible", "EditorIcons"));
- listener_icon = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
- listener_icon->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- listener_icon->set_cull_mode(FixedSpatialMaterial::CULL_DISABLED);
- listener_icon->set_depth_draw_mode(FixedSpatialMaterial::DEPTH_DRAW_DISABLED);
- listener_icon->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ listener_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ listener_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ listener_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ listener_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
+ listener_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
listener_icon->set_albedo(Color(1, 1, 1, 0.9));
- listener_icon->set_texture(FixedSpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoListener", "EditorIcons"));
+ listener_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoListener", "EditorIcons"));
{
diff --git a/editor/spatial_editor_gizmos.h b/editor/spatial_editor_gizmos.h
index 76564c5a99..a47a134975 100644
--- a/editor/spatial_editor_gizmos.h
+++ b/editor/spatial_editor_gizmos.h
@@ -399,38 +399,41 @@ public:
class SpatialEditorGizmos {
public:
- Ref<FixedSpatialMaterial> create_line_material(const Color &p_base_color);
- Ref<FixedSpatialMaterial> create_solid_material(const Color &p_base_color);
- Ref<FixedSpatialMaterial> handle2_material;
- Ref<FixedSpatialMaterial> handle_material;
- Ref<FixedSpatialMaterial> light_material;
- Ref<FixedSpatialMaterial> light_material_omni_icon;
- Ref<FixedSpatialMaterial> light_material_directional_icon;
- Ref<FixedSpatialMaterial> camera_material;
- Ref<FixedSpatialMaterial> skeleton_material;
- Ref<FixedSpatialMaterial> reflection_probe_material;
- Ref<FixedSpatialMaterial> reflection_probe_material_internal;
- Ref<FixedSpatialMaterial> gi_probe_material;
- Ref<FixedSpatialMaterial> gi_probe_material_internal;
- Ref<FixedSpatialMaterial> room_material;
- Ref<FixedSpatialMaterial> portal_material;
- Ref<FixedSpatialMaterial> raycast_material;
- Ref<FixedSpatialMaterial> visibility_notifier_material;
- Ref<FixedSpatialMaterial> car_wheel_material;
- Ref<FixedSpatialMaterial> joint_material;
-
- Ref<FixedSpatialMaterial> navmesh_edge_material;
- Ref<FixedSpatialMaterial> navmesh_solid_material;
- Ref<FixedSpatialMaterial> navmesh_edge_material_disabled;
- Ref<FixedSpatialMaterial> navmesh_solid_material_disabled;
-
- Ref<FixedSpatialMaterial> listener_icon;
-
- Ref<FixedSpatialMaterial> sample_player_icon;
- Ref<FixedSpatialMaterial> stream_player_icon;
- Ref<FixedSpatialMaterial> visibility_notifier_icon;
-
- Ref<FixedSpatialMaterial> shape_material;
+ Ref<SpatialMaterial> create_line_material(const Color &p_base_color);
+ Ref<SpatialMaterial> create_solid_material(const Color &p_base_color);
+ Ref<SpatialMaterial> handle2_material;
+ Ref<SpatialMaterial> handle2_material_billboard;
+ Ref<SpatialMaterial> handle_material;
+ Ref<SpatialMaterial> handle_material_billboard;
+ Ref<SpatialMaterial> light_material;
+ Ref<SpatialMaterial> light_material_omni;
+ Ref<SpatialMaterial> light_material_omni_icon;
+ Ref<SpatialMaterial> light_material_directional_icon;
+ Ref<SpatialMaterial> camera_material;
+ Ref<SpatialMaterial> skeleton_material;
+ Ref<SpatialMaterial> reflection_probe_material;
+ Ref<SpatialMaterial> reflection_probe_material_internal;
+ Ref<SpatialMaterial> gi_probe_material;
+ Ref<SpatialMaterial> gi_probe_material_internal;
+ Ref<SpatialMaterial> room_material;
+ Ref<SpatialMaterial> portal_material;
+ Ref<SpatialMaterial> raycast_material;
+ Ref<SpatialMaterial> visibility_notifier_material;
+ Ref<SpatialMaterial> car_wheel_material;
+ Ref<SpatialMaterial> joint_material;
+
+ Ref<SpatialMaterial> navmesh_edge_material;
+ Ref<SpatialMaterial> navmesh_solid_material;
+ Ref<SpatialMaterial> navmesh_edge_material_disabled;
+ Ref<SpatialMaterial> navmesh_solid_material_disabled;
+
+ Ref<SpatialMaterial> listener_icon;
+
+ Ref<SpatialMaterial> sample_player_icon;
+ Ref<SpatialMaterial> stream_player_icon;
+ Ref<SpatialMaterial> visibility_notifier_icon;
+
+ Ref<SpatialMaterial> shape_material;
Ref<Texture> handle_t;
Ref<Mesh> pos3d_mesh;
diff --git a/main/input_default.cpp b/main/input_default.cpp
index 131e9e3b90..0a5d06c0d3 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -485,12 +485,27 @@ void InputDefault::warp_mouse_pos(const Vector2 &p_to) {
Point2i InputDefault::warp_mouse_motion(const InputEventMouseMotion &p_motion, const Rect2 &p_rect) {
- const Point2i rel_warped(Math::fmod(p_motion.relative_x, p_rect.size.x), Math::fmod(p_motion.relative_y, p_rect.size.y));
+ // The relative distance reported for the next event after a warp is in the boundaries of the
+ // size of the rect on that axis, but it may be greater, in which case there's not problem as fmod()
+ // will warp it, but if the pointer has moved in the opposite direction between the pointer relocation
+ // and the subsequent event, the reported relative distance will be less than the size of the rect
+ // and thus fmod() will be disabled for handling the situation.
+ // And due to this mouse warping mechanism being stateless, we need to apply some heuristics to
+ // detect the warp: if the relative distance is greater than the half of the size of the relevant rect
+ // (checked per each axis), it will be considered as the consequence of a former pointer warp.
+
+ const Point2i rel_sgn(p_motion.relative_x >= 0.0f ? 1 : -1, p_motion.relative_y >= 0.0 ? 1 : -1);
+ const Size2i warp_margin = p_rect.size * 0.5f;
+ const Point2i rel_warped(
+ Math::fmod(p_motion.relative_x + rel_sgn.x * warp_margin.x, p_rect.size.x) - rel_sgn.x * warp_margin.x,
+ Math::fmod(p_motion.relative_y + rel_sgn.y * warp_margin.y, p_rect.size.y) - rel_sgn.y * warp_margin.y);
+
const Point2i pos_local = Point2i(p_motion.global_x, p_motion.global_y) - p_rect.pos;
const Point2i pos_warped(Math::fposmod(pos_local.x, p_rect.size.x), Math::fposmod(pos_local.y, p_rect.size.y));
if (pos_warped != pos_local) {
OS::get_singleton()->warp_mouse_pos(pos_warped + p_rect.pos);
}
+
return rel_warped;
}
diff --git a/main/tests/test_shader_lang.cpp b/main/tests/test_shader_lang.cpp
index 4ca09fe656..74b4f0dd81 100644
--- a/main/tests/test_shader_lang.cpp
+++ b/main/tests/test_shader_lang.cpp
@@ -323,8 +323,10 @@ MainLoop *test() {
Set<String> rm;
rm.insert("popo");
+ Set<String> types;
+ types.insert("spatial");
- Error err = sl.compile(code, dt, rm);
+ Error err = sl.compile(code, dt, rm, types);
if (err) {
diff --git a/modules/cscript/SCsub b/modules/cscript/SCsub
deleted file mode 100644
index 0882406761..0000000000
--- a/modules/cscript/SCsub
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env python
-
-Import('env')
-
-env.add_source_files(env.modules_sources, "*.cpp")
-
-Export('env')
diff --git a/modules/cscript/godot_c.cpp b/modules/cscript/godot_c.cpp
deleted file mode 100644
index f754f2bb21..0000000000
--- a/modules/cscript/godot_c.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/*************************************************************************/
-/* godot_c.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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 "godot_c.h"
diff --git a/modules/cscript/godot_c.h b/modules/cscript/godot_c.h
deleted file mode 100644
index 58acbf8bf9..0000000000
--- a/modules/cscript/godot_c.h
+++ /dev/null
@@ -1,567 +0,0 @@
-/*************************************************************************/
-/* godot_c.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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 GODOT_C_H
-#define GODOT_C_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(GDAPI_BUILT_IN) || !defined(WINDOWS_ENABLED)
-#define GDAPI
-#elif defined(GDAPI_EXPORTS)
-#define GDAPI __declspec(dllexport)
-#else
-#define GDAPI __declspec(dllimport)
-#endif
-
-#define GODOT_API_VERSION 1
-
-typedef int godot_bool;
-
-#define GODOT_FALSE 0
-#define GODOT_TRUE 1
-
-////// Image
-
-#define GODOT_IMAGE_FORMAT_GRAYSCALE 0
-#define GODOT_IMAGE_FORMAT_INTENSITY 1
-#define GODOT_IMAGE_FORMAT_GRAYSCALE_ALPHA 2
-#define GODOT_IMAGE_FORMAT_RGB 3
-#define GODOT_IMAGE_FORMAT_RGBA 4
-#define GODOT_IMAGE_FORMAT_INDEXED 5
-#define GODOT_IMAGE_FORMAT_INDEXED_ALPHA 6
-#define GODOT_IMAGE_FORMAT_YUV_422 7
-#define GODOT_IMAGE_FORMAT_YUV_444 8
-#define GODOT_IMAGE_FORMAT_BC1 9
-#define GODOT_IMAGE_FORMAT_BC2 10
-#define GODOT_IMAGE_FORMAT_BC3 11
-#define GODOT_IMAGE_FORMAT_BC4 12
-#define GODOT_IMAGE_FORMAT_BC5 13
-#define GODOT_IMAGE_FORMAT_PVRTC2 14
-#define GODOT_IMAGE_FORMAT_PVRTC2_ALPHA 15
-#define GODOT_IMAGE_FORMAT_PVRTC4 16
-#define GODOT_IMAGE_FORMAT_PVRTC4_ALPHA 17
-#define GODOT_IMAGE_FORMAT_ETC 18
-#define GODOT_IMAGE_FORMAT_ATC 19
-#define GODOT_IMAGE_FORMAT_ATC_ALPHA_EXPLICIT 20
-#define GODOT_IMAGE_FORMAT_ATC_ALPHA_INTERPOLATED 21
-
-typedef void *godot_image;
-
-godot_image GDAPI godot_image_create_empty();
-godot_image GDAPI godot_image_create(int p_width, int p_height, int p_format, int p_use_mipmaps);
-godot_image GDAPI godot_image_create_with_data(int p_width, int p_height, int p_format, int p_use_mipmaps, unsigned char *p_buffer);
-int GDAPI godot_image_get_width(godot_image p_image);
-int GDAPI godot_image_get_height(godot_image p_image);
-int GDAPI godot_image_get_format(godot_image p_image);
-int GDAPI godot_image_get_mipmap_count(godot_image p_image);
-godot_image GDAPI godot_image_copy(godot_image p_image);
-void GDAPI godot_image_free(godot_image p_image);
-
-////// RID
-
-typedef void *godot_rid;
-
-godot_rid GDAPI godot_rid_create();
-godot_rid GDAPI godot_rid_copy(godot_rid p_rid);
-void GDAPI godot_rid_free(godot_rid p_rid);
-
-////// Variant (forward declared)
-
-typedef void *godot_variant;
-
-////// Dictionary
-
-typedef void *godot_dictionary;
-
-godot_dictionary GDAPI godot_dictionary_create();
-void GDAPI godot_dictionary_has(godot_dictionary p_dictionary, godot_variant p_key);
-godot_variant GDAPI godot_dictionary_get(godot_dictionary p_dictionary, godot_variant p_key);
-void GDAPI godot_dictionary_insert(godot_dictionary p_dictionary, godot_variant p_key, godot_variant p_value);
-void GDAPI godot_dictionary_remove(godot_dictionary p_dictionary, godot_variant p_key);
-void GDAPI godot_dictionary_clear(godot_dictionary p_dictionary);
-int GDAPI godot_dictionary_get_size(godot_dictionary p_dictionary);
-void GDAPI godot_dictionary_get_keys(godot_dictionary p_dictionary, godot_variant *p_keys);
-godot_dictionary GDAPI godot_dictionary_copy(godot_dictionary p_dictionary);
-void GDAPI godot_dictionary_free(godot_dictionary p_dictionary);
-
-////// Array
-
-typedef void *godot_array;
-
-godot_array GDAPI godot_array_create();
-godot_variant GDAPI godot_array_get(godot_array p_array, int p_index);
-void GDAPI godot_array_set(godot_array p_array, int p_index, godot_variant p_value);
-void GDAPI godot_array_resize(godot_array p_array, int p_size);
-void GDAPI godot_array_insert(godot_array p_array, int p_position, godot_variant p_value);
-void GDAPI godot_array_remove(godot_array p_array, int p_position);
-void GDAPI godot_array_clear(godot_array p_array);
-int GDAPI godot_array_get_size(godot_array p_array);
-int GDAPI godot_array_find(godot_array p_array, godot_variant p_value, int p_from_pos = -1);
-godot_array GDAPI godot_array_copy(godot_array p_array);
-void GDAPI godot_array_free(godot_array p_array);
-
-////// InputEvent
-
-#define INPUT_EVENT_BUTTON_LEFT 1
-#define INPUT_EVENT_BUTTON_RIGHT 2
-#define INPUT_EVENT_BUTTON_MIDDLE 3
-#define INPUT_EVENT_BUTTON_WHEEL_UP 4
-#define INPUT_EVENT_BUTTON_WHEEL_DOWN 5
-#define INPUT_EVENT_BUTTON_WHEEL_LEFT 6
-#define INPUT_EVENT_BUTTON_WHEEL_RIGHT 7
-#define INPUT_EVENT_BUTTON_MASK_LEFT (1 << (INPUT_EVENT_BUTTON_LEFT - 1))
-#define INPUT_EVENT_BUTTON_MASK_RIGHT (1 << (INPUT_EVENT_BUTTON_RIGHT - 1))
-#define INPUT_EVENT_BUTTON_MASK_MIDDLE (1 << (INPUT_EVENT_BUTTON_MIDDLE - 1))
-
-#define INPUT_EVENT_TYPE_NONE 0
-#define INPUT_EVENT_TYPE_KEY 1
-#define INPUT_EVENT_TYPE_MOUSE_MOTION 2
-#define INPUT_EVENT_TYPE_MOUSE_BUTTON 3
-#define INPUT_EVENT_TYPE_JOYPAD_MOTION 4
-#define INPUT_EVENT_TYPE_JOYPAD_BUTTON 5
-#define INPUT_EVENT_TYPE_SCREEN_TOUCH 6
-#define INPUT_EVENT_TYPE_SCREEN_DRAG 7
-#define INPUT_EVENT_TYPE_ACTION 8
-
-typedef void *godot_input_event;
-
-godot_input_event GDAPI godot_input_event_create();
-godot_input_event GDAPI godot_input_event_copy(godot_input_event p_input_event);
-void GDAPI godot_input_event_free(godot_input_event p_input_event);
-
-int GDAPI godot_input_event_get_type(godot_input_event p_event);
-int GDAPI godot_input_event_get_device(godot_input_event p_event);
-
-godot_bool GDAPI godot_input_event_mod_has_alt(godot_input_event p_event);
-godot_bool GDAPI godot_input_event_mod_has_ctrl(godot_input_event p_event);
-godot_bool GDAPI godot_input_event_mod_has_command(godot_input_event p_event);
-godot_bool GDAPI godot_input_event_mod_has_shift(godot_input_event p_event);
-godot_bool GDAPI godot_input_event_mod_has_meta(godot_input_event p_event);
-
-int GDAPI godot_input_event_key_get_scancode(godot_input_event p_event);
-int GDAPI godot_input_event_key_get_unicode(godot_input_event p_event);
-godot_bool GDAPI godot_input_event_key_is_pressed(godot_input_event p_event);
-godot_bool GDAPI godot_input_event_key_is_echo(godot_input_event p_event);
-
-int GDAPI godot_input_event_mouse_get_x(godot_input_event p_event);
-int GDAPI godot_input_event_mouse_get_y(godot_input_event p_event);
-int GDAPI godot_input_event_mouse_get_global_x(godot_input_event p_event);
-int GDAPI godot_input_event_mouse_get_global_y(godot_input_event p_event);
-int GDAPI godot_input_event_mouse_get_button_mask(godot_input_event p_event);
-
-int GDAPI godot_input_event_mouse_button_get_button_index(godot_input_event p_event);
-godot_bool GDAPI godot_input_event_mouse_button_is_pressed(godot_input_event p_event);
-godot_bool GDAPI godot_input_event_mouse_button_is_doubleclick(godot_input_event p_event);
-
-int GDAPI godot_input_event_mouse_motion_get_relative_x(godot_input_event p_event);
-int GDAPI godot_input_event_mouse_motion_get_relative_y(godot_input_event p_event);
-
-int GDAPI godot_input_event_mouse_motion_get_speed_x(godot_input_event p_event);
-int GDAPI godot_input_event_mouse_motion_get_speed_y(godot_input_event p_event);
-
-int GDAPI godot_input_event_joypad_motion_get_axis(godot_input_event p_event);
-float GDAPI godot_input_event_joypad_motion_get_axis_value(godot_input_event p_event);
-
-int GDAPI godot_input_event_joypad_button_get_button_index(godot_input_event p_event);
-godot_bool GDAPI godot_input_event_joypad_button_is_pressed(godot_input_event p_event);
-float GDAPI godot_input_event_joypad_button_get_pressure(godot_input_event p_event);
-
-int GDAPI godot_input_event_screen_touch_get_index(godot_input_event p_event);
-int GDAPI godot_input_event_screen_touch_get_x(godot_input_event p_event);
-int GDAPI godot_input_event_screen_touch_get_y(godot_input_event p_event);
-int GDAPI godot_input_event_screen_touch_is_pressed(godot_input_event p_event);
-
-int GDAPI godot_input_event_screen_drag_get_index(godot_input_event p_event);
-int GDAPI godot_input_event_screen_drag_get_x(godot_input_event p_event);
-int GDAPI godot_input_event_screen_drag_get_y(godot_input_event p_event);
-int GDAPI godot_input_event_screen_drag_get_relative_x(godot_input_event p_event);
-int GDAPI godot_input_event_screen_drag_get_relative_y(godot_input_event p_event);
-int GDAPI godot_input_event_screen_drag_get_speed_x(godot_input_event p_event);
-int GDAPI godot_input_event_screen_drag_get_speed_y(godot_input_event p_event);
-
-int GDAPI godot_input_event_is_action(godot_input_event p_event, char *p_action);
-int GDAPI godot_input_event_is_action_pressed(godot_input_event p_event, char *p_action);
-
-////// ByteArray
-
-typedef void *godot_byte_array;
-
-godot_byte_array GDAPI godot_byte_array_create();
-godot_byte_array GDAPI godot_byte_array_copy(godot_byte_array p_byte_array);
-void GDAPI godot_byte_array_free(godot_byte_array p_byte_array);
-
-int GDAPI godot_byte_array_get_size(godot_byte_array p_byte_array);
-unsigned char GDAPI godot_byte_array_get(godot_byte_array p_byte_array, int p_index);
-void GDAPI godot_byte_array_set(godot_byte_array p_byte_array, int p_index, unsigned char p_value);
-void GDAPI godot_byte_array_remove(godot_byte_array p_byte_array, int p_index);
-void GDAPI godot_byte_array_clear(godot_byte_array p_byte_array);
-
-typedef void *godot_byte_array_lock;
-
-godot_byte_array_lock GDAPI godot_byte_array_get_lock(godot_byte_array p_byte_array);
-unsigned char GDAPI *godot_byte_array_lock_get_pointer(godot_byte_array_lock p_byte_array_lock);
-void GDAPI godot_byte_array_lock_free(godot_byte_array_lock p_byte_array_lock);
-
-godot_image GDAPI godot_image_create_with_array(int p_width, int p_height, int p_format, int p_use_mipmaps, godot_array p_array);
-godot_byte_array GDAPI godot_image_get_data(godot_image p_image);
-
-////// IntArray
-
-typedef void *godot_int_array;
-
-godot_int_array GDAPI godot_int_array_create();
-godot_int_array GDAPI godot_int_array_copy(godot_int_array p_int_array);
-void GDAPI godot_int_array_free(godot_int_array p_int_array);
-
-int GDAPI godot_int_array_get_size(godot_int_array p_int_array);
-int GDAPI godot_int_array_get(godot_int_array p_int_array, int p_index);
-void GDAPI godot_int_array_set(godot_int_array p_int_array, int p_index, int p_value);
-void GDAPI godot_int_array_remove(godot_int_array p_int_array, int p_index);
-void GDAPI godot_int_array_clear(godot_int_array p_int_array);
-
-typedef void *godot_int_array_lock;
-
-godot_int_array_lock GDAPI godot_int_array_get_lock(godot_int_array p_int_array);
-int GDAPI *godot_int_array_lock_get_pointer(godot_int_array_lock p_int_array_lock);
-void GDAPI godot_int_array_lock_free(godot_int_array_lock p_int_array_lock);
-
-////// RealArray
-
-typedef void *godot_real_array;
-
-godot_real_array GDAPI godot_real_array_create();
-godot_real_array GDAPI godot_real_array_copy(godot_real_array p_real_array);
-void GDAPI godot_real_array_free(godot_real_array p_real_array);
-
-int GDAPI godot_real_array_get_size(godot_real_array p_real_array);
-float GDAPI godot_real_array_get(godot_real_array p_real_array, int p_index);
-void GDAPI godot_real_array_set(godot_real_array p_real_array, int p_index, float p_value);
-void GDAPI godot_real_array_remove(godot_real_array p_real_array, int p_index);
-void GDAPI godot_real_array_clear(godot_real_array p_real_array);
-
-typedef void *godot_real_array_lock;
-
-godot_real_array_lock GDAPI godot_real_array_get_lock(godot_real_array p_real_array);
-float GDAPI *godot_real_array_lock_get_pointer(godot_real_array_lock p_real_array_lock);
-void GDAPI godot_real_array_lock_free(godot_real_array_lock p_real_array_lock);
-
-////// StringArray
-
-typedef void *godot_string_array;
-
-godot_string_array GDAPI godot_string_array_create();
-godot_string_array GDAPI godot_string_array_copy(godot_string_array p_string_array);
-void GDAPI godot_string_array_free(godot_string_array p_string_array);
-
-int GDAPI godot_string_array_get_size(godot_string_array p_string_array);
-int GDAPI godot_string_array_get(godot_string_array p_string_array, int p_index, unsigned char *p_string, int p_max_len);
-void GDAPI godot_string_array_set(godot_string_array p_string_array, int p_index, unsigned char *p_string);
-void GDAPI godot_string_array_remove(godot_string_array p_string_array, int p_index);
-void GDAPI godot_string_array_clear(godot_string_array p_string_array);
-
-////// Vector2Array
-
-typedef void *godot_vector2_array;
-
-godot_vector2_array GDAPI godot_vector2_array_create();
-godot_vector2_array GDAPI godot_vector2_array_copy(godot_vector2_array p_vector2_array);
-void GDAPI godot_vector2_array_free(godot_vector2_array p_vector2_array);
-
-int GDAPI godot_vector2_array_get_size(godot_vector2_array p_vector2_array);
-int GDAPI godot_vector2_array_get_stride(godot_vector2_array p_vector2_array);
-void GDAPI godot_vector2_array_get(godot_vector2_array p_vector2_array, int p_index, float *p_vector2);
-void GDAPI godot_vector2_array_set(godot_vector2_array p_vector2_array, int p_index, float *p_vector2);
-void GDAPI godot_vector2_array_remove(godot_vector2_array p_vector2_array, int p_index);
-void GDAPI godot_vector2_array_clear(godot_vector2_array p_vector2_array);
-
-typedef void *godot_vector2_array_lock;
-
-godot_vector2_array_lock GDAPI godot_vector2_array_get_lock(godot_vector2_array p_vector2_array);
-float GDAPI *godot_vector2_array_lock_get_pointer(godot_vector2_array_lock p_vector2_array_lock);
-void GDAPI godot_vector2_array_lock_free(godot_vector2_array_lock p_vector2_array_lock);
-
-////// Vector3Array
-
-typedef void *godot_vector3_array;
-
-godot_vector3_array GDAPI godot_vector3_array_create();
-godot_vector3_array GDAPI godot_vector3_array_copy(godot_vector3_array p_vector3_array);
-void GDAPI godot_vector3_array_free(godot_vector3_array p_vector3_array);
-
-int GDAPI godot_vector3_array_get_size(godot_vector3_array p_vector3_array);
-int GDAPI godot_vector3_array_get_stride(godot_vector3_array p_vector3_array);
-void GDAPI godot_vector3_array_get(godot_vector3_array p_vector3_array, int p_index, float *p_vector3);
-void GDAPI godot_vector3_array_set(godot_vector3_array p_vector3_array, int p_index, float *p_vector3);
-void GDAPI godot_vector3_array_remove(godot_vector3_array p_vector3_array, int p_index);
-void GDAPI godot_vector3_array_clear(godot_vector3_array p_vector3_array);
-
-typedef void *godot_vector3_array_lock;
-
-godot_vector3_array_lock GDAPI godot_vector3_array_get_lock(godot_vector3_array p_vector3_array);
-float GDAPI *godot_vector3_array_lock_get_pointer(godot_vector3_array_lock p_vector3_array_lock);
-void GDAPI godot_vector3_array_lock_free(godot_vector3_array_lock p_vector3_array_lock);
-
-////// ColorArray
-
-typedef void *godot_color_array;
-
-godot_color_array GDAPI godot_color_array_create();
-godot_color_array GDAPI godot_color_array_copy(godot_color_array p_color_array);
-void GDAPI godot_color_array_free(godot_color_array p_color_array);
-
-int GDAPI godot_color_array_get_size(godot_color_array p_color_array);
-int GDAPI godot_color_array_get_stride(godot_color_array p_color_array);
-void GDAPI godot_color_array_get(godot_color_array p_color_array, int p_index, float *p_color);
-void GDAPI godot_color_array_set(godot_color_array p_color_array, int p_index, float *p_color);
-void GDAPI godot_color_array_remove(godot_color_array p_color_array, int p_index);
-void GDAPI godot_color_array_clear(godot_color_array p_color_array);
-
-typedef void *godot_color_array_lock;
-
-godot_color_array_lock GDAPI godot_color_array_get_lock(godot_color_array p_color_array);
-float GDAPI *godot_color_array_lock_get_pointer(godot_color_array_lock p_color_array_lock);
-void GDAPI godot_color_array_lock_free(godot_color_array_lock p_color_array_lock);
-
-////// Instance (forward declared)
-
-typedef void *godot_instance;
-
-////// Variant
-
-#define GODOT_VARIANT_NIL 0
-#define GODOT_VARIANT_BOOL 1
-#define GODOT_VARIANT_INT 2
-#define GODOT_VARIANT_REAL 3
-#define GODOT_VARIANT_STRING 4
-#define GODOT_VARIANT_VECTOR2 5
-#define GODOT_VARIANT_RECT2 6
-#define GODOT_VARIANT_VECTOR3 7
-#define GODOT_VARIANT_MATRIX32 8
-#define GODOT_VARIANT_PLANE 9
-#define GODOT_VARIANT_QUAT 10
-#define GODOT_VARIANT_AABB 11
-#define GODOT_VARIANT_MATRIX3 12
-#define GODOT_VARIANT_TRANSFORM 13
-#define GODOT_VARIANT_COLOR 14
-#define GODOT_VARIANT_IMAGE 15
-#define GODOT_VARIANT_NODE_PATH 16
-#define GODOT_VARIANT_RID 17
-#define GODOT_VARIANT_OBJECT 18
-#define GODOT_VARIANT_INPUT_EVENT 19
-#define GODOT_VARIANT_DICTIONARY 20
-#define GODOT_VARIANT_ARRAY 21
-#define GODOT_VARIANT_BYTE_ARRAY 22
-#define GODOT_VARIANT_INT_ARRAY 23
-#define GODOT_VARIANT_REAL_ARRAY 24
-#define GODOT_VARIANT_STRING_ARRAY 25
-#define GODOT_VARIANT_VECTOR2_ARRAY 26
-#define GODOT_VARIANT_VECTOR3_ARRAY 27
-#define GODOT_VARIANT_COLOR_ARRAY 28
-#define GODOT_VARIANT_MAX 29
-
-godot_variant *godot_variant_new();
-
-int GDAPI godot_variant_get_type(godot_variant p_variant);
-
-void GDAPI godot_variant_set_null(godot_variant p_variant);
-void GDAPI godot_variant_set_bool(godot_variant p_variant, godot_bool p_bool);
-void GDAPI godot_variant_set_int(godot_variant p_variant, int p_int);
-void GDAPI godot_variant_set_float(godot_variant p_variant, int p_float);
-void GDAPI godot_variant_set_string(godot_variant p_variant, char *p_string);
-void GDAPI godot_variant_set_vector2(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_set_rect2(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_set_vector3(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_set_matrix32(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_set_plane(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_set_aabb(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_set_matrix3(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_set_transform(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_set_color(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_set_image(godot_variant p_variant, godot_image *p_image);
-void GDAPI godot_variant_set_node_path(godot_variant p_variant, char *p_path);
-void GDAPI godot_variant_set_rid(godot_variant p_variant, char *p_path);
-void GDAPI godot_variant_set_instance(godot_variant p_variant, godot_instance p_instance);
-void GDAPI godot_variant_set_input_event(godot_variant p_variant, godot_input_event p_instance);
-void GDAPI godot_variant_set_dictionary(godot_variant p_variant, godot_dictionary p_dictionary);
-void GDAPI godot_variant_set_array(godot_variant p_variant, godot_array p_array);
-void GDAPI godot_variant_set_byte_array(godot_variant p_variant, godot_byte_array p_array);
-void GDAPI godot_variant_set_int_array(godot_variant p_variant, godot_byte_array p_array);
-void GDAPI godot_variant_set_string_array(godot_variant p_variant, godot_string_array p_array);
-void GDAPI godot_variant_set_vector2_array(godot_variant p_variant, godot_vector2_array p_array);
-void GDAPI godot_variant_set_vector3_array(godot_variant p_variant, godot_vector3_array p_array);
-void GDAPI godot_variant_set_color_array(godot_variant p_variant, godot_color_array p_array);
-
-godot_bool GDAPI godot_variant_get_bool(godot_variant p_variant);
-int GDAPI godot_variant_get_int(godot_variant p_variant);
-float GDAPI godot_variant_get_float(godot_variant p_variant);
-int GDAPI godot_variant_get_string(godot_variant p_variant, char *p_string, int p_bufsize);
-void GDAPI godot_variant_get_vector2(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_get_rect2(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_get_vector3(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_get_matrix32(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_get_plane(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_get_aabb(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_get_matrix3(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_get_transform(godot_variant p_variant, float *p_elems);
-void GDAPI godot_variant_get_color(godot_variant p_variant, float *p_elems);
-godot_image GDAPI *godot_variant_get_image(godot_variant p_variant);
-int GDAPI godot_variant_get_node_path(godot_variant p_variant, char *p_path, int p_bufsize);
-godot_rid GDAPI godot_variant_get_rid(godot_variant p_variant);
-godot_instance GDAPI godot_variant_get_instance(godot_variant p_variant);
-void GDAPI godot_variant_get_input_event(godot_variant p_variant, godot_input_event);
-void GDAPI godot_variant_get_dictionary(godot_variant p_variant, godot_dictionary);
-godot_array GDAPI godot_variant_get_array(godot_variant p_variant);
-godot_byte_array GDAPI godot_variant_get_byte_array(godot_variant p_variant);
-godot_byte_array GDAPI godot_variant_get_int_array(godot_variant p_variant);
-godot_string_array GDAPI godot_variant_get_string_array(godot_variant p_variant);
-godot_vector2_array GDAPI godot_variant_get_vector2_array(godot_variant p_variant);
-godot_vector3_array GDAPI godot_variant_get_vector3_array(godot_variant p_variant);
-godot_color_array GDAPI godot_variant_get_color_array(godot_variant p_variant);
-
-void GDAPI godot_variant_delete(godot_variant p_variant);
-
-////// Class
-///
-
-char GDAPI **godot_class_get_list(); //get list of classes in array to array of strings, must be freed, use godot_list_free()
-
-int GDAPI godot_class_get_base(char *p_class, char *p_base, int p_max_len);
-int GDAPI godot_class_get_name(char *p_class, char *p_base, int p_max_len);
-
-char GDAPI **godot_class_get_method_list(char *p_class); //free with godot_list_free()
-int GDAPI godot_class_method_get_argument_count(char *p_class, char *p_method);
-int GDAPI godot_class_method_get_argument_type(char *p_class, char *p_method, int p_argument);
-godot_variant GDAPI godot_class_method_get_argument_default_value(char *p_class, char *p_method, int p_argument);
-
-char GDAPI **godot_class_get_constant_list(char *p_class); //free with godot_list_free()
-int GDAPI godot_class_constant_get_value(char *p_class, char *p_constant);
-
-////// Instance
-
-typedef int godot_call_error;
-
-#define GODOT_CALL_OK
-#define GODOT_CALL_ERROR_WRONG_ARGUMENTS
-#define GODOT_CALL_ERROR_INVALID_INSTANCE
-
-godot_instance GDAPI godot_instance_new(char *p_class);
-int GDAPI godot_instance_get_class(godot_instance p_instance, char *p_class, int p_max_len);
-
-typedef struct {
- char *name;
- int hint;
- char *hint_string;
- int usage;
-} godot_property_info;
-
-godot_call_error GDAPI godot_instance_call(godot_instance p_instance, char *p_method, ...);
-godot_call_error GDAPI godot_instance_call_ret(godot_instance p_instance, godot_variant r_return, char *p_method, ...);
-godot_bool GDAPI godot_instance_set(godot_instance p_instance, char *p_prop, godot_variant p_value);
-godot_variant GDAPI godot_instance_get(godot_instance p_instance, char *p_prop);
-
-#define GODOT_PROPERTY_HINT_NONE 0 ///< no hint provided.
-#define GODOT_PROPERTY_HINT_RANGE 1 ///< hint_text = "min,max,step,slider; //slider is optional"
-#define GODOT_PROPERTY_HINT_EXP_RANGE 2 ///< hint_text = "min,max,step", exponential edit
-#define GODOT_PROPERTY_HINT_ENUM 3 ///< hint_text= "val1,val2,val3,etc"
-#define GODOT_PROPERTY_HINT_EXP_EASING 4 /// exponential easing function (Math::ease)
-#define GODOT_PROPERTY_HINT_LENGTH 5 ///< hint_text= "length" (as integer)
-#define GODOT_PROPERTY_HINT_SPRITE_FRAME 6
-#define GODOT_PROPERTY_HINT_KEY_ACCEL 7 ///< hint_text= "length" (as integer)
-#define GODOT_PROPERTY_HINT_FLAGS 8 ///< hint_text= "flag1,flag2,etc" (as bit flags)
-#define GODOT_PROPERTY_HINT_ALL_FLAGS 9
-#define GODOT_PROPERTY_HINT_FILE 10 ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,"
-#define GODOT_PROPERTY_HINT_DIR 11 ///< a directort path must be passed
-#define GODOT_PROPERTY_HINT_GLOBAL_FILE 12 ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,"
-#define GODOT_PROPERTY_HINT_GLOBAL_DIR 13 ///< a directort path must be passed
-#define GODOT_PROPERTY_HINT_RESOURCE_TYPE 14 ///< a resource object type
-#define GODOT_PROPERTY_HINT_MULTILINE_TEXT 15 ///< used for string properties that can contain multiple lines
-#define GODOT_PROPERTY_HINT_COLOR_NO_ALPHA 16 ///< used for ignoring alpha component when editing a color
-#define GODOT_PROPERTY_HINT_IMAGE_COMPRESS_LOSSY 17
-#define GODOT_PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS 18
-#define GODOT_PROPERTY_HINT_OBJECT_ID 19
-
-#define GODOT_PROPERTY_USAGE_STORAGE 1
-#define GODOT_PROPERTY_USAGE_EDITOR 2
-#define GODOT_PROPERTY_USAGE_NETWORK 4
-#define GODOT_PROPERTY_USAGE_EDITOR_HELPER 8
-#define GODOT_PROPERTY_USAGE_CHECKABLE 16 //used for editing global variables
-#define GODOT_PROPERTY_USAGE_CHECKED 32 //used for editing global variables
-#define GODOT_PROPERTY_USAGE_INTERNATIONALIZED 64 //hint for internationalized strings
-#define GODOT_PROPERTY_USAGE_BUNDLE 128 //used for optimized bundles
-#define GODOT_PROPERTY_USAGE_CATEGORY 256
-#define GODOT_PROPERTY_USAGE_STORE_IF_NONZERO 512 //only store if nonzero
-#define GODOT_PROPERTY_USAGE_STORE_IF_NONONE 1024 //only store if false
-#define GODOT_PROPERTY_USAGE_NO_INSTANCE_STATE 2048
-#define GODOT_PROPERTY_USAGE_RESTART_IF_CHANGED 4096
-#define GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE 8192
-#define GODOT_PROPERTY_USAGE_STORE_IF_NULL 16384
-#define GODOT_PROPERTY_USAGE_ANIMATE_AS_TRIGGER 32768
-
-#define GODOT_PROPERTY_USAGE_DEFAULT GODOT_PROPERTY_USAGE_STORAGE | GODOT_PROPERTY_USAGE_EDITOR | GODOT_PROPERTY_USAGE_NETWORK
-#define GODOT_PROPERTY_USAGE_DEFAULT_INTL GODOT_PROPERTY_USAGE_STORAGE | GODOT_PROPERTY_USAGE_EDITOR | GODOT_PROPERTY_USAGE_NETWORK | GODOT_PROPERTY_USAGE_INTERNATIONALIZED
-#define GODOT_PROPERTY_USAGE_NOEDITOR GODOT_PROPERTY_USAGE_STORAGE | GODOT_PROPERTY_USAGE_NETWORK
-
-godot_property_info GDAPI **godot_instance_get_property_list(godot_instance p_instance);
-void GDAPI godot_instance_free_property_list(godot_instance p_instance, godot_property_info **p_list);
-
-void GDAPI godot_list_free(char **p_name); //helper to free all the class list
-
-////// Script API
-
-typedef void *(godot_script_instance_func)(godot_instance); //passed an instance, return a pointer to your userdata
-typedef void(godot_script_free_func)(godot_instance, void *); //passed an instance, please free your userdata
-
-void GDAPI godot_script_register(char *p_base, char *p_name, godot_script_instance_func p_instance_func, godot_script_free_func p_free_func);
-void GDAPI godot_script_unregister(char *p_name);
-
-typedef GDAPI godot_variant(godot_script_func)(godot_instance, void *, godot_variant *, int); //instance,userdata,arguments,argument count. Return something or NULL. Arguments must not be freed.
-
-void GDAPI godot_script_add_function(char *p_name, char *p_function_name, godot_script_func p_func);
-void GDAPI godot_script_add_validated_function(char *p_name, char *p_function_name, godot_script_func p_func, int *p_arg_types, int p_arg_count, godot_variant *p_default_args, int p_default_arg_count);
-
-typedef void(godot_set_property_func)(godot_instance, void *, godot_variant); //instance,userdata,value. Value must not be freed.
-typedef godot_variant(godot_get_property_func)(godot_instance, void *); //instance,userdata. Return a value or NULL.
-
-void GDAPI godot_script_add_property(char *p_name, char *p_path, godot_set_property_func p_set_func, godot_get_property_func p_get_func);
-void GDAPI godot_script_add_listed_property(char *p_name, char *p_path, godot_set_property_func p_set_func, godot_get_property_func p_get_func, int p_type, int p_hint, char *p_hint_string, int p_usage);
-
-////// System Functions
-
-//using these will help Godot track how much memory is in use in debug mode
-void GDAPI *godot_alloc(int p_bytes);
-void GDAPI *godot_realloc(void *p_ptr, int p_bytes);
-void GDAPI godot_free(void *p_ptr);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // GODOT_C_H
diff --git a/modules/dlscript/SCsub b/modules/dlscript/SCsub
new file mode 100644
index 0000000000..ac13319a1d
--- /dev/null
+++ b/modules/dlscript/SCsub
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+
+Import('env')
+
+env.add_source_files(env.modules_sources, "*.cpp")
+env.add_source_files(env.modules_sources, "godot/*.cpp")
+
+env.Append(CPPFLAGS=['-DGDAPI_BUILT_IN'])
+
+if "platform" in env and env["platform"] == "x11": # there has to be a better solution?
+ env.Append(LINKFLAGS=["-rdynamic"])
+env.use_ptrcall = True
+
+Export('env')
diff --git a/modules/dlscript/api_generator.cpp b/modules/dlscript/api_generator.cpp
new file mode 100644
index 0000000000..c8e38ca9a3
--- /dev/null
+++ b/modules/dlscript/api_generator.cpp
@@ -0,0 +1,394 @@
+#include "api_generator.h"
+
+#ifdef TOOLS_ENABLED
+
+#include "class_db.h"
+#include "core/global_config.h"
+#include "os/file_access.h"
+
+// helper stuff
+
+static Error save_file(const String &p_path, const List<String> &p_content) {
+
+ FileAccessRef file = FileAccess::open(p_path, FileAccess::WRITE);
+
+ ERR_FAIL_COND_V(!file, ERR_FILE_CANT_WRITE);
+
+ for (const List<String>::Element *e = p_content.front(); e != NULL; e = e->next()) {
+ file->store_string(e->get());
+ }
+
+ file->close();
+
+ return OK;
+}
+
+// helper stuff end
+
+struct MethodAPI {
+ String method_name;
+ String return_type;
+
+ List<String> argument_types;
+ List<String> argument_names;
+
+ Map<int, Variant> default_arguments;
+
+ int argument_count;
+ bool has_varargs;
+ bool is_editor;
+ bool is_noscript;
+ bool is_const;
+ bool is_reverse;
+ bool is_virtual;
+ bool is_from_script;
+};
+
+struct PropertyAPI {
+ String name;
+ String getter;
+ String setter;
+ String type;
+};
+
+struct ConstantAPI {
+ String constant_name;
+ int constant_value;
+};
+
+struct SignalAPI {
+ String name;
+ List<String> argument_types;
+ List<String> argument_names;
+ Map<int, Variant> default_arguments;
+};
+
+struct ClassAPI {
+ String class_name;
+ String super_class_name;
+
+ ClassDB::APIType api_type;
+
+ bool is_singleton;
+ bool is_instanciable;
+ // @Unclear
+ bool is_creatable;
+ // @Unclear
+ bool memory_own;
+
+ List<MethodAPI> methods;
+ List<PropertyAPI> properties;
+ List<ConstantAPI> constants;
+ List<SignalAPI> signals_;
+};
+
+/*
+ * Reads the entire Godot API to a list
+ */
+List<ClassAPI> generate_c_api_classes() {
+
+ List<ClassAPI> api;
+
+ List<StringName> classes;
+ ClassDB::get_class_list(&classes);
+
+ for (List<StringName>::Element *e = classes.front(); e != NULL; e = e->next()) {
+ StringName class_name = e->get();
+
+ ClassAPI class_api;
+ class_api.api_type = ClassDB::get_api_type(e->get());
+ class_api.class_name = class_name;
+ class_api.super_class_name = ClassDB::get_parent_class(class_name);
+ {
+ String name = class_name;
+ if (name.begins_with("_")) {
+ name.remove(0);
+ }
+ class_api.is_singleton = GlobalConfig::get_singleton()->has_singleton(name);
+ }
+ class_api.is_instanciable = !class_api.is_singleton && ClassDB::can_instance(class_name);
+
+ {
+ bool is_reference = false;
+ List<StringName> inheriters;
+ ClassDB::get_inheriters_from_class("Reference", &inheriters);
+ is_reference = inheriters.find(class_name) < 0;
+ // @Unclear
+ class_api.memory_own = !class_api.is_singleton && is_reference;
+ }
+
+ // constants
+ {
+ List<String> constant;
+ ClassDB::get_integer_constant_list(class_name, &constant, true);
+ for (List<String>::Element *c = constant.front(); c != NULL; c = c->next()) {
+ ConstantAPI constant_api;
+ constant_api.constant_name = c->get();
+ constant_api.constant_value = ClassDB::get_integer_constant(class_name, c->get());
+
+ class_api.constants.push_back(constant_api);
+ }
+ }
+
+ // signals
+ {
+ List<MethodInfo> signals_;
+ ClassDB::get_signal_list(class_name, &signals_, true);
+
+ for (int i = 0; i < signals_.size(); i++) {
+ SignalAPI signal;
+
+ MethodInfo method_info = signals_[i];
+ signal.name = method_info.name;
+
+ for (int j = 0; j < method_info.arguments.size(); j++) {
+ PropertyInfo argument = method_info.arguments[j];
+ String type;
+ String name = argument.name;
+
+ if (argument.name.find(":") != -1) {
+ type = argument.name.get_slice(":", 1);
+ name = argument.name.get_slice(":", 0);
+ } else if (argument.hint == PROPERTY_HINT_RESOURCE_TYPE) {
+ type = argument.hint_string;
+ } else if (argument.type == Variant::NIL) {
+ type = "Variant";
+ } else {
+ type = Variant::get_type_name(argument.type);
+ }
+
+ signal.argument_names.push_back(name);
+ signal.argument_types.push_back(type);
+ }
+
+ Vector<Variant> default_arguments = method_info.default_arguments;
+
+ int default_start = signal.argument_names.size() - default_arguments.size();
+
+ for (int j = 0; j < default_arguments.size(); j++) {
+ signal.default_arguments[default_start + j] = default_arguments[j];
+ }
+
+ class_api.signals_.push_back(signal);
+ }
+ }
+
+ //properties
+ {
+ List<PropertyInfo> properties;
+ ClassDB::get_property_list(class_name, &properties, true);
+
+ for (List<PropertyInfo>::Element *p = properties.front(); p != NULL; p = p->next()) {
+ PropertyAPI property_api;
+
+ property_api.name = p->get().name;
+ property_api.getter = ClassDB::get_property_getter(class_name, p->get().name);
+ property_api.setter = ClassDB::get_property_setter(class_name, p->get().name);
+
+ if (p->get().name.find(":") != -1) {
+ property_api.type = p->get().name.get_slice(":", 1);
+ property_api.name = p->get().name.get_slice(":", 0);
+ } else if (p->get().hint == PROPERTY_HINT_RESOURCE_TYPE) {
+ property_api.type = p->get().hint_string;
+ } else if (p->get().type == Variant::NIL) {
+ property_api.type = "Variant";
+ } else {
+ property_api.type = Variant::get_type_name(p->get().type);
+ }
+
+ if (!property_api.setter.empty() || !property_api.getter.empty()) {
+ class_api.properties.push_back(property_api);
+ }
+ }
+ }
+
+ //methods
+ {
+ List<MethodInfo> methods;
+ ClassDB::get_method_list(class_name, &methods, true);
+
+ for (List<MethodInfo>::Element *m = methods.front(); m != NULL; m = m->next()) {
+ MethodAPI method_api;
+ MethodBind *method_bind = ClassDB::get_method(class_name, m->get().name);
+ MethodInfo &method_info = m->get();
+
+ //method name
+ method_api.method_name = m->get().name;
+ //method return type
+ if (method_bind && method_bind->get_return_type() != StringName()) {
+ method_api.return_type = method_bind->get_return_type();
+ } else if (method_api.method_name.find(":") != -1) {
+ method_api.return_type = method_api.method_name.get_slice(":", 1);
+ method_api.method_name = method_api.method_name.get_slice(":", 0);
+ } else if (m->get().return_val.type != Variant::NIL) {
+ method_api.return_type = m->get().return_val.hint == PROPERTY_HINT_RESOURCE_TYPE ? m->get().return_val.hint_string : Variant::get_type_name(m->get().return_val.type);
+ } else {
+ method_api.return_type = "void";
+ }
+
+ method_api.argument_count = method_info.arguments.size();
+ method_api.has_varargs = method_bind && method_bind->is_vararg();
+
+ // Method flags
+ if (method_info.flags) {
+ const uint32_t flags = method_info.flags;
+ method_api.is_editor = flags & METHOD_FLAG_EDITOR;
+ method_api.is_noscript = flags & METHOD_FLAG_NOSCRIPT;
+ method_api.is_const = flags & METHOD_FLAG_CONST;
+ method_api.is_reverse = flags & METHOD_FLAG_REVERSE;
+ method_api.is_virtual = flags & METHOD_FLAG_VIRTUAL;
+ method_api.is_from_script = flags & METHOD_FLAG_FROM_SCRIPT;
+ }
+
+ method_api.is_virtual = method_api.is_virtual || method_api.method_name[0] == '_';
+
+ // method argument name and type
+
+ for (int i = 0; i < method_api.argument_count; i++) {
+ String arg_name;
+ String arg_type;
+ PropertyInfo arg_info = method_info.arguments[i];
+
+ arg_name = arg_info.name;
+
+ if (arg_info.name.find(":") != -1) {
+ arg_type = arg_info.name.get_slice(":", 1);
+ arg_name = arg_info.name.get_slice(":", 0);
+ } else if (arg_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
+ arg_type = arg_info.hint_string;
+ } else if (arg_info.type == Variant::NIL) {
+ arg_type = "Variant";
+ } else {
+ arg_type = Variant::get_type_name(arg_info.type);
+ }
+
+ method_api.argument_names.push_back(arg_name);
+ method_api.argument_types.push_back(arg_type);
+
+ if (method_bind && method_bind->has_default_argument(i)) {
+ method_api.default_arguments[i] = method_bind->get_default_argument(i);
+ }
+ }
+
+ class_api.methods.push_back(method_api);
+ }
+ }
+
+ api.push_back(class_api);
+ }
+
+ return api;
+}
+
+/*
+ * Generates the JSON source from the API in p_api
+ */
+static List<String> generate_c_api_json(const List<ClassAPI> &p_api) {
+
+ // I'm sorry for the \t mess
+
+ List<String> source;
+
+ source.push_back("[\n");
+
+ for (const List<ClassAPI>::Element *c = p_api.front(); c != NULL; c = c->next()) {
+ ClassAPI api = c->get();
+
+ source.push_back("\t{\n");
+
+ source.push_back("\t\t\"name\": \"" + api.class_name + "\",\n");
+ source.push_back("\t\t\"base_class\": \"" + api.super_class_name + "\",\n");
+ source.push_back(String("\t\t\"api_type\": \"") + (api.api_type == ClassDB::API_CORE ? "core" : (api.api_type == ClassDB::API_EDITOR ? "tools" : "none")) + "\",\n");
+ source.push_back(String("\t\t\"singleton\": ") + (api.is_singleton ? "true" : "false") + ",\n");
+ source.push_back(String("\t\t\"instanciable\": ") + (api.is_instanciable ? "true" : "false") + ",\n");
+ // @Unclear
+ // source.push_back(String("\t\t\"createable\": ") + (api.is_creatable ? "true" : "false") + ",\n");
+
+ source.push_back("\t\t\"constants\": {\n");
+ for (List<ConstantAPI>::Element *e = api.constants.front(); e; e = e->next()) {
+ source.push_back("\t\t\t\"" + e->get().constant_name + "\": " + String::num_int64(e->get().constant_value) + (e->next() ? "," : "") + "\n");
+ }
+ source.push_back("\t\t},\n");
+
+ source.push_back("\t\t\"properties\": [\n");
+ for (List<PropertyAPI>::Element *e = api.properties.front(); e; e = e->next()) {
+ source.push_back("\t\t\t{\n");
+ source.push_back("\t\t\t\t\"name\": \"" + e->get().name + "\",\n");
+ source.push_back("\t\t\t\t\"type\": \"" + e->get().type + "\",\n");
+ source.push_back("\t\t\t\t\"getter\": \"" + e->get().getter + "\",\n");
+ source.push_back("\t\t\t\t\"setter\": \"" + e->get().setter + "\"\n");
+ source.push_back(String("\t\t\t}") + (e->next() ? "," : "") + "\n");
+ }
+ source.push_back("\t\t],\n");
+
+ source.push_back("\t\t\"signals\": [\n");
+ for (List<SignalAPI>::Element *e = api.signals_.front(); e; e = e->next()) {
+ source.push_back("\t\t\t{\n");
+ source.push_back("\t\t\t\t\"name\": \"" + e->get().name + "\",\n");
+ source.push_back("\t\t\t\t\"arguments\": [\n");
+ for (int i = 0; i < e->get().argument_names.size(); i++) {
+ source.push_back("\t\t\t\t\t{\n");
+ source.push_back("\t\t\t\t\t\t\"name\": \"" + e->get().argument_names[i] + "\",\n");
+ source.push_back("\t\t\t\t\t\t\"type\": \"" + e->get().argument_types[i] + "\",\n");
+ source.push_back("\t\t\t\t\t\t\"default_value\": \"" + (e->get().default_arguments.has(i) ? (String)e->get().default_arguments[i] : "") + "\"\n");
+ source.push_back(String("\t\t\t\t\t}") + ((i < e->get().argument_names.size() - 1) ? "," : "") + "\n");
+ }
+ source.push_back("\t\t\t\t]\n");
+ source.push_back(String("\t\t\t}") + (e->next() ? "," : "") + "\n");
+ }
+ source.push_back("\t\t],\n");
+
+ source.push_back("\t\t\"methods\": [\n");
+ for (List<MethodAPI>::Element *e = api.methods.front(); e; e = e->next()) {
+ source.push_back("\t\t\t{\n");
+ source.push_back("\t\t\t\t\"name\": \"" + e->get().method_name + "\",\n");
+ source.push_back("\t\t\t\t\"return_type\": \"" + e->get().return_type + "\",\n");
+ source.push_back(String("\t\t\t\t\"is_editor\": ") + (e->get().is_editor ? "true" : "false") + ",\n");
+ source.push_back(String("\t\t\t\t\"is_noscript\": ") + (e->get().is_noscript ? "true" : "false") + ",\n");
+ source.push_back(String("\t\t\t\t\"is_const\": ") + (e->get().is_const ? "true" : "false") + ",\n");
+ source.push_back(String("\t\t\t\t\"is_reverse\": ") + (e->get().is_reverse ? "true" : "false") + ",\n");
+ source.push_back(String("\t\t\t\t\"is_virtual\": ") + (e->get().is_virtual ? "true" : "false") + ",\n");
+ source.push_back(String("\t\t\t\t\"has_varargs\": ") + (e->get().has_varargs ? "true" : "false") + ",\n");
+ source.push_back(String("\t\t\t\t\"is_from_script\": ") + (e->get().is_from_script ? "true" : "false") + ",\n");
+ source.push_back("\t\t\t\t\"arguments\": [\n");
+ for (int i = 0; i < e->get().argument_names.size(); i++) {
+ source.push_back("\t\t\t\t\t{\n");
+ source.push_back("\t\t\t\t\t\t\"name\": \"" + e->get().argument_names[i] + "\",\n");
+ source.push_back("\t\t\t\t\t\t\"type\": \"" + e->get().argument_types[i] + "\",\n");
+ source.push_back("\t\t\t\t\t\t\"default_value\": \"" + (e->get().default_arguments.has(i) ? (String)e->get().default_arguments[i] : "") + "\"\n");
+ source.push_back(String("\t\t\t\t\t}") + ((i < e->get().argument_names.size() - 1) ? "," : "") + "\n");
+ }
+ source.push_back("\t\t\t\t]\n");
+ source.push_back(String("\t\t\t}") + (e->next() ? "," : "") + "\n");
+ }
+ source.push_back("\t\t]\n");
+
+ source.push_back(String("\t}") + (c->next() ? "," : "") + "\n");
+ }
+
+ source.push_back("]");
+
+ return source;
+}
+
+//
+
+#endif
+
+/*
+ * Saves the whole Godot API to a JSON file located at
+ * p_path
+ */
+Error generate_c_api(const String &p_path) {
+
+#ifndef TOOLS_ENABLED
+ return ERR_BUG;
+#else
+
+ List<ClassAPI> api = generate_c_api_classes();
+
+ List<String> json_source = generate_c_api_json(api);
+
+ return save_file(p_path, json_source);
+#endif
+}
diff --git a/modules/dlscript/api_generator.h b/modules/dlscript/api_generator.h
new file mode 100644
index 0000000000..4a8354e9d6
--- /dev/null
+++ b/modules/dlscript/api_generator.h
@@ -0,0 +1,9 @@
+#ifndef API_GENERATOR_H
+#define API_GENERATOR_H
+
+#include "core/ustring.h"
+#include "typedefs.h"
+
+Error generate_c_api(const String &p_path);
+
+#endif // API_GENERATOR_H
diff --git a/modules/cscript/config.py b/modules/dlscript/config.py
index 5698a37295..9f57b9bb74 100644
--- a/modules/cscript/config.py
+++ b/modules/dlscript/config.py
@@ -5,4 +5,4 @@ def can_build(platform):
def configure(env):
- pass
+ env.use_ptrcall = True
diff --git a/modules/dlscript/dl_script.cpp b/modules/dlscript/dl_script.cpp
new file mode 100644
index 0000000000..449d7b4b17
--- /dev/null
+++ b/modules/dlscript/dl_script.cpp
@@ -0,0 +1,1120 @@
+/*************************************************************************/
+/* dl_script.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 "dl_script.h"
+
+#include "global_config.h"
+#include "global_constants.h"
+#include "io/file_access_encrypted.h"
+#include "os/file_access.h"
+#include "os/os.h"
+
+#include "scene/resources/scene_format_text.h"
+
+#ifdef TOOLS_ENABLED
+// #include "editor/editor_import_export.h"
+#endif
+
+#if defined(TOOLS_ENABLED) && defined(DEBUG_METHODS_ENABLED)
+#include "api_generator.h"
+#endif
+
+// Script
+
+bool DLScript::can_instance() const {
+#ifdef DLSCRIPT_EDITOR_FEATURES
+ return script_data || (!is_tool() && !ScriptServer::is_scripting_enabled());
+#else
+ // allow defaultlibrary without editor features
+ if (!library.is_valid()) {
+ String path = GLOBAL_GET("dlscript/default_dllibrary");
+
+ RES lib = ResourceLoader::load(path);
+
+ if (lib.is_valid() && lib->cast_to<DLLibrary>()) {
+ return true;
+ }
+ }
+
+ return script_data;
+#endif
+ //return script_data || (!tool && !ScriptServer::is_scripting_enabled());
+ // change to true enable in editor stuff.
+}
+
+Ref<Script> DLScript::get_base_script() const {
+ Ref<DLScript> base_script;
+ base_script->library = library;
+ base_script->script_data = script_data;
+ base_script->script_name = script_data->base;
+ return base_script;
+}
+
+StringName DLScript::get_instance_base_type() const {
+ return script_data->base_native_type;
+}
+
+ScriptInstance *DLScript::instance_create(Object *p_this) {
+
+#ifdef TOOLS_ENABLED
+
+// find a good way to initialize stuff in the editor
+#ifdef DLSCRIPT_EDITOR_FEATURES
+ if (!ScriptServer::is_scripting_enabled() && !is_tool()) {
+ // placeholder, for nodes. But for tools we want the real thing
+
+ PlaceHolderScriptInstance *sins = memnew(PlaceHolderScriptInstance(DLScriptLanguage::singleton, Ref<Script>((Script *)this), p_this));
+ placeholders.insert(sins);
+
+ List<PropertyInfo> pinfo;
+ Map<StringName, Variant> values;
+
+ if (!library.is_valid())
+ return sins;
+
+ if (!library->library_handle) {
+ Error err = library->_initialize_handle(true);
+ if (err != OK) {
+ return sins;
+ }
+ }
+
+ if (!script_data) {
+ script_data = library->get_script_data(script_name);
+ }
+ if (script_data)
+ script_data->create_func.create_func((godot_object *)p_this, script_data->create_func.method_data);
+
+ if (script_data) {
+ for (Map<StringName, DLScriptData::Property>::Element *E = script_data->properties.front(); E; E = E->next()) {
+
+ PropertyInfo p = E->get().info;
+ p.name = String(E->key());
+ pinfo.push_back(p);
+ values[p.name] = E->get().default_value;
+ }
+ }
+
+ sins->update(pinfo, values);
+
+ return sins;
+ }
+#endif
+
+#endif
+
+ if (!library.is_valid()) {
+ String path = GLOBAL_GET("dlscript/default_dllibrary");
+
+ RES lib = ResourceLoader::load(path);
+
+ if (lib.is_valid() && lib->cast_to<DLLibrary>()) {
+ set_library(lib);
+ }
+ }
+
+ DLInstance *new_instance = memnew(DLInstance);
+
+ new_instance->owner = p_this;
+ new_instance->script = Ref<DLScript>(this);
+
+#ifndef DLSCRIPT_EDITOR_FEATURES
+ if (!ScriptServer::is_scripting_enabled()) {
+ new_instance->userdata = 0;
+ } else {
+ new_instance->userdata = script_data->create_func.create_func((godot_object *)p_this, script_data->create_func.method_data);
+ }
+#else
+ new_instance->userdata = script_data->create_func.create_func((godot_object *)p_this, script_data->create_func.method_data);
+#endif
+
+ instances.insert(p_this);
+ return new_instance;
+}
+
+bool DLScript::instance_has(const Object *p_this) const {
+ return instances.has((Object *)p_this); // TODO
+}
+
+bool DLScript::has_source_code() const {
+ return false;
+}
+
+String DLScript::get_source_code() const {
+ return "";
+}
+
+Error DLScript::reload(bool p_keep_state) {
+ return FAILED;
+}
+
+bool DLScript::has_method(const StringName &p_method) const {
+ if (!script_data)
+ return false;
+ DLScriptData *data = script_data;
+
+ while (data) {
+ if (data->methods.has(p_method))
+ return true;
+
+ data = data->base_data;
+ }
+
+ return false;
+}
+
+MethodInfo DLScript::get_method_info(const StringName &p_method) const {
+ if (!script_data)
+ return MethodInfo();
+ DLScriptData *data = script_data;
+
+ while (data) {
+ if (data->methods.has(p_method))
+ return data->methods[p_method].info;
+
+ data = data->base_data;
+ }
+
+ ERR_FAIL_COND_V(!script_data->methods.has(p_method), MethodInfo());
+ return MethodInfo();
+}
+
+void DLScript::get_script_method_list(List<MethodInfo> *p_list) const {
+ if (!script_data) return;
+
+ Set<MethodInfo> methods;
+ DLScriptData *data = script_data;
+
+ while (data) {
+ for (Map<StringName, DLScriptData::Method>::Element *E = data->methods.front(); E; E = E->next()) {
+ methods.insert(E->get().info);
+ }
+ data = data->base_data;
+ }
+
+ for (Set<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
+ p_list->push_back(E->get());
+ }
+}
+
+void DLScript::get_script_property_list(List<PropertyInfo> *p_list) const {
+ if (!script_data) return;
+
+ Set<PropertyInfo> properties;
+ DLScriptData *data = script_data;
+
+ while (data) {
+ for (Map<StringName, DLScriptData::Property>::Element *E = data->properties.front(); E; E = E->next()) {
+ properties.insert(E->get().info);
+ }
+ data = data->base_data;
+ }
+
+ for (Set<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
+ p_list->push_back(E->get());
+ }
+}
+
+bool DLScript::get_property_default_value(const StringName &p_property, Variant &r_value) const {
+ if (!script_data) return false;
+
+ DLScriptData *data = script_data;
+
+ while (data) {
+ if (data->properties.has(p_property)) {
+ r_value = data->properties[p_property].default_value;
+ return true;
+ }
+
+ data = data->base_data;
+ }
+
+ return false;
+}
+
+bool DLScript::is_tool() const {
+ ERR_FAIL_COND_V(!script_data, false);
+ return script_data->is_tool;
+}
+
+String DLScript::get_node_type() const {
+ return ""; // ?
+}
+
+ScriptLanguage *DLScript::get_language() const {
+ return DLScriptLanguage::singleton;
+}
+
+bool DLScript::has_script_signal(const StringName &p_signal) const {
+ if (!script_data)
+ return false;
+
+ DLScriptData *data = script_data;
+
+ while (data) {
+ if (data->signals_.has(p_signal)) {
+ return true;
+ }
+
+ data = data->base_data;
+ }
+
+ return false;
+}
+
+void DLScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
+ if (!script_data)
+ return;
+
+ Set<MethodInfo> signals_;
+ DLScriptData *data = script_data;
+
+ while (data) {
+
+ for (Map<StringName, DLScriptData::Signal>::Element *S = data->signals_.front(); S; S = S->next()) {
+ signals_.insert(S->get().signal);
+ }
+
+ data = data->base_data;
+ }
+
+ for (Set<MethodInfo>::Element *E = signals_.front(); E; E = E->next()) {
+ r_signals->push_back(E->get());
+ }
+}
+
+Ref<DLLibrary> DLScript::get_library() const {
+ return library;
+}
+
+void DLScript::set_library(Ref<DLLibrary> p_library) {
+ library = p_library;
+
+#ifdef TOOLS_ENABLED
+ if (!ScriptServer::is_scripting_enabled())
+ return;
+#endif
+ if (library.is_valid()) {
+ Error initalize_status = library->_initialize_handle(!ScriptServer::is_scripting_enabled());
+ ERR_FAIL_COND(initalize_status != OK);
+ if (script_name) {
+ script_data = library->get_script_data(script_name);
+ ERR_FAIL_COND(!script_data);
+ }
+ }
+}
+
+StringName DLScript::get_script_name() const {
+ return script_name;
+}
+
+void DLScript::set_script_name(StringName p_script_name) {
+ script_name = p_script_name;
+
+ if (library.is_valid()) {
+ script_data = library->get_script_data(script_name);
+ ERR_FAIL_COND(!script_data);
+ }
+}
+
+void DLScript::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_library"), &DLScript::get_library);
+ ClassDB::bind_method(D_METHOD("set_library", "library"), &DLScript::set_library);
+ ClassDB::bind_method(D_METHOD("get_script_name"), &DLScript::get_script_name);
+ ClassDB::bind_method(D_METHOD("set_script_name", "script_name"), &DLScript::set_script_name);
+
+ ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "library", PROPERTY_HINT_RESOURCE_TYPE, "DLLibrary"), "set_library", "get_library");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "script_name"), "set_script_name", "get_script_name");
+}
+
+DLScript::DLScript() {
+ script_data = NULL;
+}
+
+DLScript::~DLScript() {
+ //hmm
+}
+
+// Library
+
+DLLibrary *DLLibrary::currently_initialized_library = NULL;
+
+DLLibrary *DLLibrary::get_currently_initialized_library() {
+ return currently_initialized_library;
+}
+
+static const char *_dl_platforms_info[] = {
+ "|unix|so|Unix",
+ "unix|x11|so|X11",
+ "unix|server|so|Server",
+ "unix|android|so|Android",
+ "unix|blackberry|so|Blackberry 10",
+ "unix|haiku|so|Haiku", // Right?
+ "|mac|dynlib|Mac",
+ "mac|ios|dynlib|iOS",
+ "mac|osx|dynlib|OSX",
+ "|html5|js|HTML5",
+ "|windows|dll|Windows",
+ "windows|uwp|dll|UWP",
+ NULL // Finishing condition
+};
+
+void DLLibrary::set_platform_file(StringName p_platform, String p_file) {
+ if (p_file.empty()) {
+ platform_files.erase(p_platform);
+ } else {
+ platform_files[p_platform] = p_file;
+ }
+}
+
+String DLLibrary::get_platform_file(StringName p_platform) const {
+ if (platform_files.has(p_platform)) {
+ return platform_files[p_platform];
+ } else {
+ return "";
+ }
+}
+
+Error DLLibrary::_initialize_handle(bool p_in_editor) {
+ _THREAD_SAFE_METHOD_
+
+ void *_library_handle;
+
+ // Get the file
+
+ const String platform_name = OS::get_singleton()->get_name();
+ String platform_file("");
+ char **platform_info = (char **)_dl_platforms_info;
+
+ if (platform_files.has(platform_name.to_lower())) {
+ platform_file = platform_files[platform_name.to_lower()];
+ }
+
+ while (*platform_info) {
+ String platform_info_string(*platform_info);
+
+ if (platform_name == platform_info_string.get_slicec('|', 3)) {
+ String platform_key = platform_info_string.get_slicec('|', 1);
+ String fallback_platform_key = platform_info_string.get_slicec('|', 0);
+
+ if (platform_files.has(platform_key)) {
+ platform_file = platform_files[platform_key];
+ } else if (!fallback_platform_key.empty() && platform_files.has(fallback_platform_key)) {
+ platform_file = platform_files[fallback_platform_key];
+ } else {
+ return ERR_UNAVAILABLE;
+ }
+ }
+ platform_info++;
+ }
+ ERR_FAIL_COND_V(platform_file == "", ERR_DOES_NOT_EXIST);
+
+ library_path = GlobalConfig::get_singleton()->globalize_path(platform_file);
+
+ if (DLScriptLanguage::get_singleton()->is_library_initialized(library_path)) {
+ *this = *DLScriptLanguage::get_singleton()->get_library_dllibrary(library_path);
+ return OK;
+ }
+
+ // Open the file
+
+ Error error;
+ error = OS::get_singleton()->open_dynamic_library(library_path, _library_handle);
+ if (error) return error;
+ ERR_FAIL_COND_V(!_library_handle, ERR_BUG);
+
+ // Get the method
+
+ void *library_init;
+ error = OS::get_singleton()->get_dynamic_library_symbol_handle(_library_handle, DLScriptLanguage::get_init_symbol_name(), library_init);
+ if (error) return error;
+ ERR_FAIL_COND_V(!library_init, ERR_BUG);
+
+ DLLibrary::currently_initialized_library = this;
+
+ void (*library_init_fpointer)(godot_dlscript_init_options *) = (void (*)(godot_dlscript_init_options *))library_init;
+
+ godot_dlscript_init_options options;
+
+ options.in_editor = p_in_editor;
+ options.core_api_hash = ClassDB::get_api_hash(ClassDB::API_CORE);
+ options.editor_api_hash = ClassDB::get_api_hash(ClassDB::API_EDITOR);
+ options.no_api_hash = ClassDB::get_api_hash(ClassDB::API_NONE);
+
+ library_init_fpointer(&options); // Catch errors?
+ /*{
+ ERR_EXPLAIN("Couldn't initialize library");
+ ERR_FAIL_V(ERR_SCRIPT_FAILED);
+ }*/
+
+ DLLibrary::currently_initialized_library = NULL;
+ library_handle = _library_handle;
+
+ DLScriptLanguage::get_singleton()->set_library_initialized(library_path, this);
+
+ return OK;
+}
+
+Error DLLibrary::_free_handle(bool p_in_editor) {
+ ERR_FAIL_COND_V(!library_handle, ERR_BUG);
+
+ if (!DLScriptLanguage::get_singleton()->is_library_initialized(library_path)) {
+ OS::get_singleton()->close_dynamic_library(library_handle);
+ library_handle = 0;
+ return OK;
+ }
+
+ Error error = OK;
+ void *library_terminate;
+ error = OS::get_singleton()->get_dynamic_library_symbol_handle(library_handle, DLScriptLanguage::get_terminate_symbol_name(), library_terminate);
+ if (error)
+ return OK; // no terminate? okay, not that important lol
+
+ void (*library_terminate_pointer)(godot_dlscript_terminate_options *) = (void (*)(godot_dlscript_terminate_options *))library_terminate;
+
+ godot_dlscript_terminate_options options;
+ options.in_editor = p_in_editor;
+
+ library_terminate_pointer(&options);
+
+ DLScriptLanguage::get_singleton()->set_library_uninitialized(library_path);
+
+ OS::get_singleton()->close_dynamic_library(library_handle);
+ library_handle = 0;
+
+ return OK;
+}
+
+void DLLibrary::_register_script(const StringName p_name, const StringName p_base, godot_instance_create_func p_instance_func, godot_instance_destroy_func p_destroy_func) {
+ ERR_FAIL_COND(scripts.has(p_name));
+
+ DLScriptData *s = memnew(DLScriptData);
+ s->base = p_base;
+ s->create_func = p_instance_func;
+ s->destroy_func = p_destroy_func;
+ Map<StringName, DLScriptData *>::Element *E = scripts.find(p_base);
+ if (E) {
+ s->base_data = E->get();
+ s->base_native_type = s->base_data->base_native_type;
+ } else {
+ if (!ClassDB::class_exists(p_base)) {
+ memdelete(s);
+ ERR_EXPLAIN("Invalid base for registered type '" + p_name + "'");
+ ERR_FAIL();
+ }
+ s->base_native_type = p_base;
+ }
+
+ scripts.insert(p_name, s);
+}
+
+void DLLibrary::_register_tool_script(const StringName p_name, const StringName p_base, godot_instance_create_func p_instance_func, godot_instance_destroy_func p_destroy_func) {
+ ERR_FAIL_COND(scripts.has(p_name));
+
+ DLScriptData *s = memnew(DLScriptData);
+ s->base = p_base;
+ s->create_func = p_instance_func;
+ s->destroy_func = p_destroy_func;
+ s->is_tool = true;
+ Map<StringName, DLScriptData *>::Element *E = scripts.find(p_base);
+ if (E) {
+ s->base_data = E->get();
+ s->base_native_type = s->base_data->base_native_type;
+ } else {
+ if (!ClassDB::class_exists(p_base)) {
+ memdelete(s);
+ ERR_EXPLAIN("Invalid base for registered type '" + p_name + "'");
+ ERR_FAIL();
+ }
+ s->base_native_type = p_base;
+ }
+
+ scripts.insert(p_name, s);
+}
+
+void DLLibrary::_register_script_method(const StringName p_name, const StringName p_method, godot_method_attributes p_attr, godot_instance_method p_func, MethodInfo p_info) {
+ ERR_FAIL_COND(!scripts.has(p_name));
+
+ p_info.name = p_method;
+ DLScriptData::Method method;
+
+ method = DLScriptData::Method(p_func, p_info, p_attr.rpc_type);
+
+ scripts[p_name]->methods.insert(p_method, method);
+}
+
+void DLLibrary::_register_script_property(const StringName p_name, const String p_path, godot_property_attributes *p_attr, godot_property_set_func p_setter, godot_property_get_func p_getter) {
+ ERR_FAIL_COND(!scripts.has(p_name));
+
+ DLScriptData::Property p;
+
+ PropertyInfo pi;
+ pi.name = p_path;
+
+ if (p_attr != NULL) {
+ pi = PropertyInfo((Variant::Type)p_attr->type, p_path, (PropertyHint)p_attr->hint, *(String *)&p_attr->hint_string, p_attr->usage);
+
+ p = DLScriptData::Property(p_setter, p_getter, pi, *(Variant *)&p_attr->default_value, p_attr->rset_type);
+ }
+
+ scripts[p_name]->properties.insert(p_path, p);
+}
+
+void DLLibrary::_register_script_signal(const StringName p_name, const godot_signal *p_signal) {
+ ERR_FAIL_COND(!scripts.has(p_name));
+ ERR_FAIL_COND(!p_signal);
+
+ DLScriptData::Signal signal;
+
+ signal.signal.name = *(String *)&p_signal->name;
+
+ {
+ List<PropertyInfo> arguments;
+ for (int i = 0; i < p_signal->num_args; i++) {
+ PropertyInfo info;
+ godot_signal_argument attrib = p_signal->args[i];
+
+ String *name = (String *)&attrib.name;
+ info.name = *name;
+ info.type = (Variant::Type)attrib.type;
+ info.hint = (PropertyHint)attrib.hint;
+ info.hint_string = *(String *)&attrib.hint_string;
+ info.usage = attrib.usage;
+
+ arguments.push_back(info);
+ }
+
+ signal.signal.arguments = arguments;
+ }
+
+ {
+ Vector<Variant> default_arguments;
+ for (int i = 0; i < p_signal->num_default_args; i++) {
+ Variant *v;
+ godot_signal_argument attrib = p_signal->args[i];
+
+ v = (Variant *)&attrib.default_value;
+
+ default_arguments.push_back(*v);
+ }
+
+ signal.signal.default_arguments = default_arguments;
+ }
+
+ scripts[p_name]->signals_.insert(*(String *)&p_signal->name, signal);
+}
+
+DLScriptData *DLLibrary::get_script_data(const StringName p_name) {
+
+ if (!scripts.has(p_name)) {
+ if (DLScriptLanguage::get_singleton()->is_library_initialized(library_path)) {
+ _update_library(*DLScriptLanguage::get_singleton()->get_library_dllibrary(library_path));
+ }
+ ERR_FAIL_COND_V(!scripts.has(p_name), NULL);
+ }
+
+ return scripts[p_name];
+}
+
+bool DLLibrary::_set(const StringName &p_name, const Variant &p_value) {
+ String name = p_name;
+ if (name.begins_with("platform/")) {
+ set_platform_file(name.get_slice("/", 1), p_value);
+ return true;
+ }
+ return false;
+}
+
+bool DLLibrary::_get(const StringName &p_name, Variant &r_ret) const {
+ String name = p_name;
+ if (name.begins_with("platform/")) {
+ r_ret = get_platform_file(name.get_slice("/", 1));
+ return true;
+ }
+ return false;
+}
+
+void DLLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
+ char **platform_info = (char **)_dl_platforms_info;
+
+ Set<String> registered_platform_names;
+ {
+ List<StringName> ep;
+ // ep.push_back("X11");
+ // EditorImportExport::get_singleton()->get_export_platforms(&ep);
+ for (List<StringName>::Element *E = ep.front(); E; E = E->next()) {
+ registered_platform_names.insert(String(E->get()).to_lower());
+ }
+ }
+
+ while (*platform_info) {
+ String platform_info_string(*platform_info);
+ String fallback_platform_key = platform_info_string.get_slicec('|', 0);
+ String platform_key = platform_info_string.get_slicec('|', 1);
+ String platform_extension = platform_info_string.get_slicec('|', 2);
+ String platform_name = platform_info_string.get_slicec('|', 3);
+
+ registered_platform_names.erase(platform_name);
+
+ if (fallback_platform_key.empty()) {
+ p_list->push_back(PropertyInfo(Variant::STRING, "platform/" + platform_key, PROPERTY_HINT_FILE, "*." + platform_extension));
+
+ } else {
+ if (platform_files.has(platform_key)) {
+ p_list->push_back(PropertyInfo(Variant::STRING, "platform/" + platform_key, PROPERTY_HINT_FILE, "*." + platform_extension, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CHECKABLE | PROPERTY_USAGE_CHECKED));
+ } else {
+ p_list->push_back(PropertyInfo(Variant::STRING, "platform/" + platform_key, PROPERTY_HINT_FILE, "*." + platform_extension, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CHECKABLE));
+ }
+ }
+ platform_info++;
+ }
+
+ while (registered_platform_names.size()) {
+ const String platform_name = registered_platform_names.front()->get();
+ registered_platform_names.erase(platform_name);
+ p_list->push_back(PropertyInfo(Variant::STRING, "platform/" + platform_name.to_lower(), PROPERTY_HINT_FILE, "*"));
+ }
+}
+
+void DLLibrary::_notification(int what) {
+ // TODO
+}
+
+void DLLibrary::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_platform_file", "platform", "file"), &DLLibrary::set_platform_file);
+ ClassDB::bind_method(D_METHOD("get_platform_file", "platform"), &DLLibrary::get_platform_file);
+}
+
+DLLibrary::DLLibrary() {
+ library_handle = NULL;
+}
+
+DLLibrary::~DLLibrary() {
+
+ for (Map<StringName, DLScriptData *>::Element *E = scripts.front(); E; E = E->next()) {
+ for (Map<StringName, DLScriptData::Method>::Element *M = E->get()->methods.front(); M; M = M->next()) {
+ if (M->get().method.free_func) {
+ M->get().method.free_func(M->get().method.method_data);
+ }
+ }
+ memdelete(E->get());
+ }
+
+ if (library_handle) {
+ bool in_editor = false;
+#ifdef TOOLS_ENABLED
+ in_editor = !ScriptServer::is_scripting_enabled();
+#endif
+ _free_handle(in_editor);
+ }
+}
+
+// Instance
+
+bool DLInstance::set(const StringName &p_name, const Variant &p_value) {
+ if (!script->script_data)
+ return false;
+ if (script->script_data->properties.has(p_name)) {
+ script->script_data->properties[p_name].setter.set_func((godot_object *)owner, script->script_data->properties[p_name].setter.method_data, userdata, *(godot_variant *)&p_value);
+ return true;
+ }
+ return false;
+}
+
+bool DLInstance::get(const StringName &p_name, Variant &r_ret) const {
+ if (!script->script_data)
+ return false;
+ if (script->script_data->properties.has(p_name)) {
+ godot_variant value = script->script_data->properties[p_name].getter.get_func((godot_object *)owner, script->script_data->properties[p_name].getter.method_data, userdata);
+ r_ret = *(Variant *)&value;
+ return true;
+ }
+ return false;
+}
+
+void DLInstance::get_property_list(List<PropertyInfo> *p_properties) const {
+ script->get_script_property_list(p_properties);
+ // TODO: dynamic properties
+}
+
+Variant::Type DLInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const {
+ if (script->script_data->properties.has(p_name)) {
+ *r_is_valid = true;
+ return script->script_data->properties[p_name].info.type;
+ }
+ *r_is_valid = false;
+ return Variant::NIL;
+}
+
+void DLInstance::get_method_list(List<MethodInfo> *p_list) const {
+ script->get_script_method_list(p_list);
+}
+
+bool DLInstance::has_method(const StringName &p_method) const {
+ return script->has_method(p_method);
+}
+
+Variant DLInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+ // TODO: validated methods & errors
+
+ DLScriptData *data_ptr = script->script_data;
+ while (data_ptr) {
+ Map<StringName, DLScriptData::Method>::Element *E = data_ptr->methods.find(p_method);
+ if (E) {
+ godot_variant result = E->get().method.method((godot_object *)owner, E->get().method.method_data, userdata, p_argcount, (godot_variant **)p_args);
+ return *(Variant *)&result;
+ }
+ data_ptr = data_ptr->base_data;
+ }
+ r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ return Variant();
+}
+
+void DLInstance::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) {
+ // TODO: validated methods & errors
+
+ DLScriptData *data_ptr = script->script_data;
+ while (data_ptr) {
+ Map<StringName, DLScriptData::Method>::Element *E = data_ptr->methods.find(p_method);
+ if (E) {
+ E->get().method.method((godot_object *)owner, E->get().method.method_data, userdata, p_argcount, (godot_variant **)p_args);
+ }
+ data_ptr = data_ptr->base_data;
+ }
+}
+
+void DLInstance::_ml_call_reversed(DLScriptData *data_ptr, const StringName &p_method, const Variant **p_args, int p_argcount) {
+ // TODO: validated methods & errors
+
+ if (data_ptr->base_data)
+ _ml_call_reversed(data_ptr->base_data, p_method, p_args, p_argcount);
+
+ // Variant::CallError ce;
+
+ Map<StringName, DLScriptData::Method>::Element *E = data_ptr->methods.find(p_method);
+ if (E) {
+ E->get().method.method((godot_object *)owner, E->get().method.method_data, userdata, p_argcount, (godot_variant **)p_args);
+ }
+}
+
+void DLInstance::call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) {
+ if (script.ptr() && script->script_data) {
+ _ml_call_reversed(script->script_data, p_method, p_args, p_argcount);
+ }
+}
+
+void DLInstance::notification(int p_notification) {
+ Variant value = p_notification;
+ const Variant *args[1] = { &value };
+ call_multilevel(DLScriptLanguage::singleton->strings._notification, args, 1);
+}
+
+Ref<Script> DLInstance::get_script() const {
+ return script;
+}
+
+ScriptLanguage *DLInstance::get_language() {
+ return DLScriptLanguage::singleton;
+}
+
+ScriptInstance::RPCMode DLInstance::get_rpc_mode(const StringName &p_method) const {
+ DLScriptData::Method m = script->script_data->methods[p_method];
+ switch (m.rpc_mode) {
+ case GODOT_METHOD_RPC_MODE_DISABLED:
+ return RPC_MODE_DISABLED;
+ case GODOT_METHOD_RPC_MODE_REMOTE:
+ return RPC_MODE_REMOTE;
+ case GODOT_METHOD_RPC_MODE_SYNC:
+ return RPC_MODE_SYNC;
+ case GODOT_METHOD_RPC_MODE_MASTER:
+ return RPC_MODE_MASTER;
+ case GODOT_METHOD_RPC_MODE_SLAVE:
+ return RPC_MODE_SLAVE;
+ default:
+ return RPC_MODE_DISABLED;
+ }
+}
+
+ScriptInstance::RPCMode DLInstance::get_rset_mode(const StringName &p_variable) const {
+ DLScriptData::Property p = script->script_data->properties[p_variable];
+ switch (p.rset_mode) {
+ case GODOT_METHOD_RPC_MODE_DISABLED:
+ return RPC_MODE_DISABLED;
+ case GODOT_METHOD_RPC_MODE_REMOTE:
+ return RPC_MODE_REMOTE;
+ case GODOT_METHOD_RPC_MODE_SYNC:
+ return RPC_MODE_SYNC;
+ case GODOT_METHOD_RPC_MODE_MASTER:
+ return RPC_MODE_MASTER;
+ case GODOT_METHOD_RPC_MODE_SLAVE:
+ return RPC_MODE_SLAVE;
+ default:
+ return RPC_MODE_DISABLED;
+ }
+}
+
+DLInstance::DLInstance() {
+ owner = NULL;
+ userdata = NULL;
+}
+
+DLInstance::~DLInstance() {
+ if (script.is_valid()) {
+ if (owner) {
+ script->instances.erase(owner);
+ }
+ if (!script->script_data)
+ return;
+ script->script_data->destroy_func.destroy_func((godot_object *)owner, script->script_data->destroy_func.method_data, userdata);
+ if (script->script_data->destroy_func.free_func)
+ script->script_data->destroy_func.free_func(script->script_data->destroy_func.method_data);
+ if (script->script_data->create_func.free_func)
+ script->script_data->create_func.free_func(script->script_data->create_func.method_data);
+ }
+}
+
+// Language
+
+DLScriptLanguage *DLScriptLanguage::singleton = NULL;
+
+String DLScriptLanguage::get_name() const {
+ return "DLScript";
+}
+
+bool DLScriptLanguage::is_library_initialized(const String &p_path) {
+
+ return initialized_libraries.has(p_path);
+}
+
+void DLScriptLanguage::set_library_initialized(const String &p_path, DLLibrary *p_dllibrary) {
+
+ initialized_libraries[p_path] = p_dllibrary;
+}
+
+DLLibrary *DLScriptLanguage::get_library_dllibrary(const String &p_path) {
+
+ return initialized_libraries[p_path];
+}
+
+void DLScriptLanguage::set_library_uninitialized(const String &p_path) {
+
+ initialized_libraries.erase(p_path);
+}
+
+void DLScriptLanguage::init() {
+ // TODO: Expose globals
+ GLOBAL_DEF("dlscript/default_dllibrary", "");
+ PropertyInfo prop_info(Variant::STRING, "dlscript/default_dllibrary", PROPERTY_HINT_FILE, "tres,res,dllib");
+ GlobalConfig::get_singleton()->set_custom_property_info("dlscript/default_dllibrary", prop_info);
+
+// generate bindings
+#if defined(TOOLS_ENABLED) && defined(DEBUG_METHODS_ENABLED)
+
+ List<String> args = OS::get_singleton()->get_cmdline_args();
+
+ List<String>::Element *E = args.find("--dlscript-generate-json-api");
+
+ if (E && E->next()) {
+ if (generate_c_api(E->next()->get()) != OK) {
+ ERR_PRINT("Failed to generate C API\n");
+ }
+ }
+#endif
+}
+
+String DLScriptLanguage::get_type() const {
+ return "DLScript";
+}
+
+String DLScriptLanguage::get_extension() const {
+ return "dl";
+}
+
+Error DLScriptLanguage::execute_file(const String &p_path) {
+ return OK; // ??
+}
+
+void DLScriptLanguage::finish() {
+ // cleanup is for noobs
+}
+
+// scons doesn't want to link in the api source so we need to call a dummy function to cause it to link
+extern "C" void _api_anchor();
+
+void DLScriptLanguage::_compile_dummy_for_the_api() {
+ _api_anchor();
+}
+
+Ref<Script> DLScriptLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const {
+ DLScript *src = memnew(DLScript);
+ src->set_script_name(p_class_name);
+ return Ref<DLScript>(src);
+}
+
+bool DLScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const {
+ return false; // TODO
+}
+
+Script *DLScriptLanguage::create_script() const {
+ DLScript *scr = memnew(DLScript);
+ return scr;
+}
+
+bool DLScriptLanguage::has_named_classes() const {
+ return true;
+}
+
+int DLScriptLanguage::find_function(const String &p_function, const String &p_code) const {
+ return -1; // No source code!
+}
+
+String DLScriptLanguage::make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const {
+ return ""; // No source code!
+}
+
+void DLScriptLanguage::add_global_constant(const StringName &p_variable, const Variant &p_value) {
+ // TODO TODO TODO
+}
+
+// TODO: Any debugging? (research)
+String DLScriptLanguage::debug_get_error() const {
+ return "";
+}
+
+int DLScriptLanguage::debug_get_stack_level_count() const {
+ return 1; // ?
+}
+
+int DLScriptLanguage::debug_get_stack_level_line(int p_level) const {
+ return -1;
+}
+
+String DLScriptLanguage::debug_get_stack_level_function(int p_level) const {
+ return "[native code]"; // ?
+}
+
+String DLScriptLanguage::debug_get_stack_level_source(int p_level) const {
+ return "";
+}
+
+void DLScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {}
+
+void DLScriptLanguage::debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {}
+
+String DLScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) {
+ return ""; // ??
+}
+
+void DLScriptLanguage::reload_all_scripts() {
+ // @Todo
+}
+
+void DLScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) {
+ // @Todo
+ OS::get_singleton()->print("reload tool scripts\n");
+}
+
+void DLScriptLanguage::get_recognized_extensions(List<String> *p_extensions) const {
+ p_extensions->push_back("dl"); // Container file format
+}
+
+void DLScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const {
+}
+
+void DLScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const {
+}
+
+// TODO: all profilling
+void DLScriptLanguage::profiling_start() {
+}
+
+void DLScriptLanguage::profiling_stop() {
+}
+
+int DLScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) {
+ return 0;
+}
+
+int DLScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) {
+ return 0;
+}
+
+void DLScriptLanguage::frame() {
+}
+
+String DLScriptLanguage::get_init_symbol_name() {
+ return "godot_dlscript_init"; // TODO: Maybe make some internal function which would do the actual stuff
+}
+
+String DLScriptLanguage::get_terminate_symbol_name() {
+ return "godot_dlscript_terminate";
+}
+
+DLScriptLanguage::DLScriptLanguage() {
+ ERR_FAIL_COND(singleton);
+ strings._notification = StringName("_notification");
+ singleton = this;
+ initialized_libraries = Map<String, DLLibrary *>();
+}
+
+DLScriptLanguage::~DLScriptLanguage() {
+ singleton = NULL;
+}
+
+RES ResourceFormatLoaderDLScript::load(const String &p_path, const String &p_original_path, Error *r_error) {
+ ResourceFormatLoaderText rsflt;
+ return rsflt.load(p_path, p_original_path, r_error);
+}
+
+void ResourceFormatLoaderDLScript::get_recognized_extensions(List<String> *p_extensions) const {
+ p_extensions->push_back("dl");
+}
+bool ResourceFormatLoaderDLScript::handles_type(const String &p_type) const {
+ return (p_type == "Script" || p_type == "DLScript");
+}
+String ResourceFormatLoaderDLScript::get_resource_type(const String &p_path) const {
+ String el = p_path.get_extension().to_lower();
+ if (el == "dl")
+ return "DLScript";
+ return "";
+}
+
+Error ResourceFormatSaverDLScript::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
+ ResourceFormatSaverText rfst;
+ return rfst.save(p_path, p_resource, p_flags);
+}
+
+bool ResourceFormatSaverDLScript::recognize(const RES &p_resource) const {
+ return p_resource->cast_to<DLScript>() != NULL;
+}
+
+void ResourceFormatSaverDLScript::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
+ if (p_resource->cast_to<DLScript>()) {
+ p_extensions->push_back("dl");
+ }
+}
diff --git a/modules/dlscript/dl_script.h b/modules/dlscript/dl_script.h
new file mode 100644
index 0000000000..497208c832
--- /dev/null
+++ b/modules/dlscript/dl_script.h
@@ -0,0 +1,404 @@
+/*************************************************************************/
+/* dl_script.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 DL_SCRIPT_H
+#define DL_SCRIPT_H
+
+#include "io/resource_loader.h"
+#include "io/resource_saver.h"
+#include "os/thread_safe.h"
+#include "resource.h"
+#include "script_language.h"
+#include "self_list.h"
+
+#include "godot.h"
+
+#ifdef TOOLS_ENABLED
+// #define DLSCRIPT_EDITOR_FEATURES
+#endif
+
+struct DLScriptData {
+ /* typedef void* (InstanceFunc)(godot_object* instance);
+ typedef void (DestroyFunc)(godot_object* instance,void* userdata);
+ typedef godot_variant (MethodFunc)(godot_object *instance, void *userdata, void *method_data, int arg_count,godot_variant **args);
+ typedef void (MethodDataFreeFunc)(void *method_data);
+ typedef void (SetterFunc)(godot_object* instance,void* userdata,godot_variant value);
+ typedef godot_variant (GetterFunc)(godot_object* instance,void* userdata);*/
+
+ struct Method {
+ godot_instance_method method;
+ MethodInfo info;
+ int rpc_mode;
+
+ Method() {
+ }
+ Method(godot_instance_method p_method, MethodInfo p_info, int p_rpc_mode) {
+ method = p_method;
+ info = p_info;
+ rpc_mode = p_rpc_mode;
+ }
+ };
+ struct Property {
+ godot_property_set_func setter;
+ godot_property_get_func getter;
+ PropertyInfo info;
+ Variant default_value;
+ int rset_mode;
+
+ Property() {
+ }
+ Property(godot_property_set_func p_setter, godot_property_get_func p_getter) {
+ setter = p_setter;
+ getter = p_getter;
+ }
+ Property(godot_property_set_func p_setter, godot_property_get_func p_getter, PropertyInfo p_info, Variant p_default_value, int p_rset_mode) {
+ setter = p_setter;
+ getter = p_getter;
+ info = p_info;
+ default_value = p_default_value;
+ rset_mode = p_rset_mode;
+ }
+ };
+
+ struct Signal {
+ MethodInfo signal;
+ };
+
+ Map<StringName, Method> methods;
+ Map<StringName, Property> properties;
+ Map<StringName, Signal> signals_; // QtCreator doesn't like the name signals
+ StringName base;
+ StringName base_native_type;
+ DLScriptData *base_data;
+ godot_instance_create_func create_func;
+ godot_instance_destroy_func destroy_func;
+
+ bool is_tool;
+
+ DLScriptData() {
+ base = StringName();
+ base_data = NULL;
+ is_tool = false;
+ }
+ DLScriptData(StringName p_base, godot_instance_create_func p_instance, godot_instance_destroy_func p_free) {
+ base = p_base;
+ base_data = NULL;
+ create_func = p_instance;
+ destroy_func = p_free;
+ is_tool = false;
+ }
+};
+
+class DLLibrary;
+
+class DLScript : public Script {
+
+ GDCLASS(DLScript, Script);
+
+ Ref<DLLibrary> library;
+ StringName script_name;
+ StringName base_native_type;
+ Set<Object *> instances;
+ DLScriptData *script_data;
+
+#ifdef TOOLS_ENABLED
+ Set<PlaceHolderScriptInstance *> placeholders;
+// void _update_placeholder(PlaceHolderScriptInstance *p_placeholder);
+// virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder);
+#endif
+
+ friend class DLInstance;
+ friend class DLScriptLanguage;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual bool can_instance() const;
+
+ virtual Ref<Script> get_base_script() const; //for script inheritance
+
+ virtual StringName get_instance_base_type() const; // this may not work in all scripts, will return empty if so
+ virtual ScriptInstance *instance_create(Object *p_this);
+ virtual bool instance_has(const Object *p_this) const;
+
+ virtual bool has_source_code() const;
+ virtual String get_source_code() const;
+ virtual void set_source_code(const String &p_code) {}
+ virtual Error reload(bool p_keep_state = false);
+
+ virtual bool has_method(const StringName &p_method) const;
+ virtual MethodInfo get_method_info(const StringName &p_method) const;
+
+ virtual bool is_tool() const;
+
+ virtual String get_node_type() const;
+
+ virtual ScriptLanguage *get_language() const;
+
+ virtual bool has_script_signal(const StringName &p_signal) const;
+ virtual void get_script_signal_list(List<MethodInfo> *r_signals) const;
+
+ virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const;
+
+ virtual void update_exports() {} //editor tool
+ virtual void get_script_method_list(List<MethodInfo> *p_list) const;
+ virtual void get_script_property_list(List<PropertyInfo> *p_list) const;
+
+ Ref<DLLibrary> get_library() const;
+ void set_library(Ref<DLLibrary> p_library);
+
+ StringName get_script_name() const;
+ void set_script_name(StringName p_script_name);
+
+ DLScript();
+ ~DLScript();
+};
+
+class DLLibrary : public Resource {
+ _THREAD_SAFE_CLASS_
+
+ GDCLASS(DLLibrary, Resource);
+ OBJ_SAVE_TYPE(DLLibrary);
+
+ Map<StringName, String> platform_files;
+ void *library_handle;
+ String library_path;
+ static DLLibrary *currently_initialized_library;
+ Map<StringName, DLScriptData *> scripts;
+
+protected:
+ friend class DLScript;
+ _FORCE_INLINE_ void _update_library(const DLLibrary &p_other) {
+ platform_files = p_other.platform_files;
+ library_handle = p_other.library_handle;
+ library_path = p_other.library_path;
+ scripts = p_other.scripts;
+ }
+
+ Error _initialize_handle(bool p_in_editor = false);
+
+ Error _free_handle(bool p_in_editor = false);
+
+ DLScriptData *get_script_data(const StringName p_name);
+
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ void _get_property_list(List<PropertyInfo> *p_list) const;
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ static DLLibrary *get_currently_initialized_library();
+
+ void _register_script(const StringName p_name, const StringName p_base, godot_instance_create_func p_instance_func, godot_instance_destroy_func p_destroy_func);
+ void _register_tool_script(const StringName p_name, const StringName p_base, godot_instance_create_func p_instance_func, godot_instance_destroy_func p_destroy_func);
+ void _register_script_method(const StringName p_name, const StringName p_method, godot_method_attributes p_attr, godot_instance_method p_func, MethodInfo p_info);
+ void _register_script_property(const StringName p_name, const String p_path, godot_property_attributes *p_attr, godot_property_set_func p_setter, godot_property_get_func p_getter);
+ void _register_script_signal(const StringName p_name, const godot_signal *p_signal);
+
+ void set_platform_file(StringName p_platform, String p_file);
+ String get_platform_file(StringName p_platform) const;
+
+ DLLibrary();
+ ~DLLibrary();
+};
+
+class DLInstance : public ScriptInstance {
+ friend class DLScript;
+
+ Object *owner;
+ Ref<DLScript> script;
+ void *userdata;
+
+ void _ml_call_reversed(DLScriptData *data_ptr, const StringName &p_method, const Variant **p_args, int p_argcount);
+
+public:
+ _FORCE_INLINE_ Object *get_owner() { return owner; }
+
+ _FORCE_INLINE_ void *get_userdata() { return userdata; }
+
+ virtual bool set(const StringName &p_name, const Variant &p_value);
+ virtual bool get(const StringName &p_name, Variant &r_ret) const;
+ virtual void get_property_list(List<PropertyInfo> *p_properties) const;
+ virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = NULL) const;
+
+ virtual void get_method_list(List<MethodInfo> *p_list) const;
+ virtual bool has_method(const StringName &p_method) const;
+ virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount);
+ virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount);
+
+ Variant debug_get_member_by_index(int p_idx) const { return Variant(); }
+
+ virtual void notification(int p_notification);
+
+ virtual Ref<Script> get_script() const;
+
+ virtual ScriptLanguage *get_language();
+
+ void set_path(const String &p_path);
+
+ void reload_members();
+
+ virtual RPCMode get_rpc_mode(const StringName &p_method) const;
+ virtual RPCMode get_rset_mode(const StringName &p_variable) const;
+
+ DLInstance();
+ ~DLInstance();
+};
+
+class DLScriptLanguage : public ScriptLanguage {
+ friend class DLScript;
+ friend class DLInstance;
+
+ static DLScriptLanguage *singleton;
+
+ Variant *_global_array; // @Unused necessary?
+ Vector<Variant> global_array; // @Unused necessary?
+ Map<StringName, int> globals; // @Unused necessary?
+
+ // @Unused necessary?
+ void _add_global(const StringName &p_name, const Variant &p_value);
+
+ Mutex *lock;
+
+ SelfList<DLScript>::List script_list;
+
+ Map<String, DLLibrary *> initialized_libraries;
+
+ bool profiling;
+ uint64_t script_frame_time;
+
+ struct {
+
+ StringName _notification;
+
+ } strings;
+
+public:
+ _FORCE_INLINE_ static DLScriptLanguage *get_singleton() { return singleton; }
+
+ virtual String get_name() const;
+
+ bool is_library_initialized(const String &p_path);
+ void set_library_initialized(const String &p_path, DLLibrary *p_dllibrary);
+ DLLibrary *get_library_dllibrary(const String &p_path);
+ void set_library_uninitialized(const String &p_path);
+
+ /* LANGUAGE FUNCTIONS */
+ virtual void init();
+ virtual String get_type() const;
+ virtual String get_extension() const;
+ virtual Error execute_file(const String &p_path);
+ virtual void finish();
+
+ /* EDITOR FUNCTIONS */
+
+ virtual void get_reserved_words(List<String> *p_words) const {};
+ virtual void get_comment_delimiters(List<String> *p_delimiters) const {};
+ virtual void get_string_delimiters(List<String> *p_delimiters) const {};
+ virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
+ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const;
+ virtual Script *create_script() const;
+ virtual bool has_named_classes() const;
+ virtual int find_function(const String &p_function, const String &p_code) const;
+ virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
+
+ virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, String &r_call_hint) { return ERR_UNAVAILABLE; }
+
+ virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_base_path, Object *p_owner, LookupResult &r_result) { return ERR_UNAVAILABLE; }
+
+ virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {};
+ virtual void add_global_constant(const StringName &p_variable, const Variant &p_value);
+
+ /* MULTITHREAD FUNCTIONS */
+
+ //some VMs need to be notified of thread creation/exiting to allocate a stack
+ virtual void thread_enter() {}
+ virtual void thread_exit() {}
+
+ /* DEBUGGER FUNCTIONS */
+
+ virtual String debug_get_error() const;
+ virtual int debug_get_stack_level_count() const;
+ virtual int debug_get_stack_level_line(int p_level) const;
+ virtual String debug_get_stack_level_function(int p_level) const;
+ virtual String debug_get_stack_level_source(int p_level) const;
+ virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1){};
+ virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1);
+ virtual void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1);
+ virtual String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems = -1, int p_max_depth = -1);
+
+ virtual Vector<StackInfo> debug_get_current_stack_info() { return Vector<StackInfo>(); }
+
+ virtual void reload_all_scripts();
+ virtual void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload);
+ /* LOADER FUNCTIONS */
+
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual void get_public_functions(List<MethodInfo> *p_functions) const;
+ virtual void get_public_constants(List<Pair<String, Variant> > *p_constants) const;
+
+ /* PROFILLER FUNCTIONS */
+
+ virtual void profiling_start();
+ virtual void profiling_stop();
+
+ virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max);
+ virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max);
+
+ virtual void frame();
+
+ static String get_init_symbol_name();
+ static String get_terminate_symbol_name();
+
+ /* HACKER FUNCTIONS */
+ void _compile_dummy_for_the_api();
+
+ DLScriptLanguage();
+ ~DLScriptLanguage();
+};
+
+class ResourceFormatLoaderDLScript : public ResourceFormatLoader {
+public:
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual bool handles_type(const String &p_type) const;
+ virtual String get_resource_type(const String &p_path) const;
+};
+
+class ResourceFormatSaverDLScript : public ResourceFormatSaver {
+ virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
+ virtual bool recognize(const RES &p_resource) const;
+ virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
+};
+
+// ugly, but hey
+
+#endif // DL_SCRIPT_H
diff --git a/modules/dlscript/godot.cpp b/modules/dlscript/godot.cpp
new file mode 100644
index 0000000000..9a488ad612
--- /dev/null
+++ b/modules/dlscript/godot.cpp
@@ -0,0 +1,198 @@
+/*************************************************************************/
+/* godot_c.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 "godot.h"
+
+#include "class_db.h"
+#include "dl_script.h"
+#include "global_config.h"
+#include "variant.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern "C" void _string_api_anchor();
+extern "C" void _vector2_api_anchor();
+extern "C" void _rect2_api_anchor();
+extern "C" void _vector3_api_anchor();
+extern "C" void _transform2d_api_anchor();
+extern "C" void _plane_api_anchor();
+extern "C" void _quat_api_anchor();
+extern "C" void _basis_api_anchor();
+extern "C" void _rect3_api_anchor();
+extern "C" void _transform_api_anchor();
+extern "C" void _color_api_anchor();
+extern "C" void _image_api_anchor();
+extern "C" void _node_path_api_anchor();
+extern "C" void _rid_api_anchor();
+extern "C" void _input_event_api_anchor();
+extern "C" void _dictionary_api_anchor();
+extern "C" void _array_api_anchor();
+extern "C" void _pool_arrays_api_anchor();
+extern "C" void _variant_api_anchor();
+
+void _api_anchor() {
+
+ _string_api_anchor();
+ _vector2_api_anchor();
+ _rect2_api_anchor();
+ _vector3_api_anchor();
+ _transform2d_api_anchor();
+ _plane_api_anchor();
+ _quat_api_anchor();
+ _rect3_api_anchor();
+ _basis_api_anchor();
+ _transform_api_anchor();
+ _color_api_anchor();
+ _image_api_anchor();
+ _node_path_api_anchor();
+ _rid_api_anchor();
+ _input_event_api_anchor();
+ _dictionary_api_anchor();
+ _array_api_anchor();
+ _pool_arrays_api_anchor();
+ _variant_api_anchor();
+}
+
+extern "C++" {
+template <class a, class b>
+_FORCE_INLINE_ a memcast(b v) {
+ return *((a *)&v);
+}
+}
+
+void GDAPI godot_object_destroy(godot_object *p_o) {
+ memdelete((Object *)p_o);
+}
+
+// Singleton API
+
+godot_object GDAPI *godot_global_get_singleton(char *p_name) {
+ return (godot_object *)GlobalConfig::get_singleton()->get_singleton_object(String(p_name));
+} // result shouldn't be freed
+
+// MethodBind API
+
+godot_method_bind GDAPI *godot_method_bind_get_method(const char *p_classname, const char *p_methodname) {
+
+ MethodBind *mb = ClassDB::get_method(StringName(p_classname), StringName(p_methodname));
+ // MethodBind *mb = ClassDB::get_method("Node", "get_name");
+ return (godot_method_bind *)mb;
+}
+
+void GDAPI godot_method_bind_ptrcall(godot_method_bind *p_method_bind, godot_object *p_instance, const void **p_args, void *p_ret) {
+
+ MethodBind *mb = (MethodBind *)p_method_bind;
+ Object *o = (Object *)p_instance;
+ mb->ptrcall(o, p_args, p_ret);
+}
+
+// @Todo
+/*
+void GDAPI godot_method_bind_varcall(godot_method_bind *p_method_bind)
+{
+
+}
+*/
+
+// Script API
+
+void GDAPI godot_script_register_class(const char *p_name, const char *p_base, godot_instance_create_func p_create_func, godot_instance_destroy_func p_destroy_func) {
+ DLLibrary *library = DLLibrary::get_currently_initialized_library();
+ if (!library) {
+ ERR_EXPLAIN("Attempt to register script after initializing library!");
+ ERR_FAIL();
+ }
+ library->_register_script(p_name, p_base, p_create_func, p_destroy_func);
+}
+
+void GDAPI godot_script_register_tool_class(const char *p_name, const char *p_base, godot_instance_create_func p_create_func, godot_instance_destroy_func p_destroy_func) {
+ DLLibrary *library = DLLibrary::get_currently_initialized_library();
+ if (!library) {
+ ERR_EXPLAIN("Attempt to register script after initializing library!");
+ ERR_FAIL();
+ }
+ library->_register_tool_script(p_name, p_base, p_create_func, p_destroy_func);
+}
+
+void GDAPI godot_script_register_method(const char *p_name, const char *p_function_name, godot_method_attributes p_attr, godot_instance_method p_method) {
+ DLLibrary *library = DLLibrary::get_currently_initialized_library();
+ if (!library) {
+ ERR_EXPLAIN("Attempt to register script after initializing library!");
+ ERR_FAIL();
+ }
+ library->_register_script_method(p_name, p_function_name, p_attr, p_method, MethodInfo());
+}
+
+void GDAPI godot_script_register_property(const char *p_name, const char *p_path, godot_property_attributes *p_attr, godot_property_set_func p_set_func, godot_property_get_func p_get_func) {
+ DLLibrary *library = DLLibrary::get_currently_initialized_library();
+ if (!library) {
+ ERR_EXPLAIN("Attempt to register script after initializing library!");
+ ERR_FAIL();
+ }
+
+ library->_register_script_property(p_name, p_path, p_attr, p_set_func, p_get_func);
+}
+
+void GDAPI godot_script_register_signal(const char *p_name, const godot_signal *p_signal) {
+ DLLibrary *library = DLLibrary::get_currently_initialized_library();
+ if (!library) {
+ ERR_EXPLAIN("Attempt to register script after initializing library!");
+ ERR_FAIL();
+ }
+
+ library->_register_script_signal(p_name, p_signal);
+}
+
+void GDAPI *godot_dlinstance_get_userdata(godot_object *p_instance) {
+ Object *instance = (Object *)p_instance;
+ if (!instance)
+ return NULL;
+ if (instance->get_script_instance() && instance->get_script_instance()->get_language() == DLScriptLanguage::get_singleton()) {
+ return ((DLInstance *)instance->get_script_instance())->get_userdata();
+ }
+ return NULL;
+}
+
+// System functions
+void GDAPI *godot_alloc(int p_bytes) {
+ return memalloc(p_bytes);
+}
+
+void GDAPI *godot_realloc(void *p_ptr, int p_bytes) {
+ return memrealloc(p_ptr, p_bytes);
+}
+
+void GDAPI godot_free(void *p_ptr) {
+ memfree(p_ptr);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot.h b/modules/dlscript/godot.h
new file mode 100644
index 0000000000..75f1f47ed1
--- /dev/null
+++ b/modules/dlscript/godot.h
@@ -0,0 +1,389 @@
+/*************************************************************************/
+/* godot_c.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 GODOT_C_H
+#define GODOT_C_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef GDAPI_BUILT_IN
+#define GDAPI_EXPORT
+#endif
+
+#if !defined(_WIN32) && !defined(_MSC_VER)
+#define GDAPI
+#elif defined(GDAPI_EXPORT)
+#define GDAPI __declspec(dllexport)
+#else
+#define GDAPI __declspec(dllimport)
+#endif
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#define GODOT_API_VERSION 1
+
+////// Error
+
+typedef enum godot_error {
+ GODOT_OK,
+ GODOT_FAILED, ///< Generic fail error
+ GODOT_ERR_UNAVAILABLE, ///< What is requested is unsupported/unavailable
+ GODOT_ERR_UNCONFIGURED, ///< The object being used hasnt been properly set up yet
+ GODOT_ERR_UNAUTHORIZED, ///< Missing credentials for requested resource
+ GODOT_ERR_PARAMETER_RANGE_ERROR, ///< Parameter given out of range (5)
+ GODOT_ERR_OUT_OF_MEMORY, ///< Out of memory
+ GODOT_ERR_FILE_NOT_FOUND,
+ GODOT_ERR_FILE_BAD_DRIVE,
+ GODOT_ERR_FILE_BAD_PATH,
+ GODOT_ERR_FILE_NO_PERMISSION, // (10)
+ GODOT_ERR_FILE_ALREADY_IN_USE,
+ GODOT_ERR_FILE_CANT_OPEN,
+ GODOT_ERR_FILE_CANT_WRITE,
+ GODOT_ERR_FILE_CANT_READ,
+ GODOT_ERR_FILE_UNRECOGNIZED, // (15)
+ GODOT_ERR_FILE_CORRUPT,
+ GODOT_ERR_FILE_MISSING_DEPENDENCIES,
+ GODOT_ERR_FILE_EOF,
+ GODOT_ERR_CANT_OPEN, ///< Can't open a resource/socket/file
+ GODOT_ERR_CANT_CREATE, // (20)
+ GODOT_ERR_QUERY_FAILED,
+ GODOT_ERR_ALREADY_IN_USE,
+ GODOT_ERR_LOCKED, ///< resource is locked
+ GODOT_ERR_TIMEOUT,
+ GODOT_ERR_CANT_CONNECT, // (25)
+ GODOT_ERR_CANT_RESOLVE,
+ GODOT_ERR_CONNECTION_ERROR,
+ GODOT_ERR_CANT_AQUIRE_RESOURCE,
+ GODOT_ERR_CANT_FORK,
+ GODOT_ERR_INVALID_DATA, ///< Data passed is invalid (30)
+ GODOT_ERR_INVALID_PARAMETER, ///< Parameter passed is invalid
+ GODOT_ERR_ALREADY_EXISTS, ///< When adding, item already exists
+ GODOT_ERR_DOES_NOT_EXIST, ///< When retrieving/erasing, it item does not exist
+ GODOT_ERR_DATABASE_CANT_READ, ///< database is full
+ GODOT_ERR_DATABASE_CANT_WRITE, ///< database is full (35)
+ GODOT_ERR_COMPILATION_FAILED,
+ GODOT_ERR_METHOD_NOT_FOUND,
+ GODOT_ERR_LINK_FAILED,
+ GODOT_ERR_SCRIPT_FAILED,
+ GODOT_ERR_CYCLIC_LINK, // (40)
+ GODOT_ERR_INVALID_DECLARATION,
+ GODOT_ERR_DUPLICATE_SYMBOL,
+ GODOT_ERR_PARSE_ERROR,
+ GODOT_ERR_BUSY,
+ GODOT_ERR_SKIP, // (45)
+ GODOT_ERR_HELP, ///< user requested help!!
+ GODOT_ERR_BUG, ///< a bug in the software certainly happened, due to a double check failing or unexpected behavior.
+ GODOT_ERR_PRINTER_ON_FIRE, /// the parallel port printer is engulfed in flames
+ GODOT_ERR_OMFG_THIS_IS_VERY_VERY_BAD, ///< shit happens, has never been used, though
+ GODOT_ERR_WTF = GODOT_ERR_OMFG_THIS_IS_VERY_VERY_BAD ///< short version of the above
+} godot_error;
+
+////// bool
+
+typedef bool godot_bool;
+
+#define GODOT_TRUE 1
+#define GODOT_FALSE 0
+
+/////// int
+
+typedef int godot_int;
+
+/////// real
+
+typedef float godot_real;
+
+/////// Object (forward declared)
+typedef void godot_object;
+
+/////// String
+
+#include "godot/godot_string.h"
+
+////// Vector2
+
+#include "godot/godot_vector2.h"
+
+////// Rect2
+
+#include "godot/godot_rect2.h"
+
+////// Vector3
+
+#include "godot/godot_vector3.h"
+
+////// Transform2D
+
+#include "godot/godot_transform2d.h"
+
+/////// Plane
+
+#include "godot/godot_plane.h"
+
+/////// Quat
+
+#include "godot/godot_quat.h"
+
+/////// Rect3
+
+#include "godot/godot_rect3.h"
+
+/////// Basis
+
+#include "godot/godot_basis.h"
+
+/////// Transform
+
+#include "godot/godot_transform.h"
+
+/////// Color
+
+#include "godot/godot_color.h"
+
+/////// Image
+
+#include "godot/godot_image.h"
+
+/////// NodePath
+
+#include "godot/godot_node_path.h"
+
+/////// RID
+
+#include "godot/godot_rid.h"
+
+/////// InputEvent
+
+#include "godot/godot_input_event.h"
+
+/////// Dictionary
+
+#include "godot/godot_dictionary.h"
+
+/////// Array
+
+#include "godot/godot_array.h"
+
+// single API file for Pool*Array
+#include "godot/godot_pool_arrays.h"
+
+void GDAPI godot_object_destroy(godot_object *p_o);
+
+////// Variant
+
+#include "godot/godot_variant.h"
+
+////// Singleton API
+
+godot_object GDAPI *godot_global_get_singleton(char *p_name); // result shouldn't be freed
+
+////// MethodBind API
+
+typedef struct godot_method_bind {
+ uint8_t _dont_touch_that[1]; // TODO
+} godot_method_bind;
+
+godot_method_bind GDAPI *godot_method_bind_get_method(const char *p_classname, const char *p_methodname);
+void GDAPI godot_method_bind_ptrcall(godot_method_bind *p_method_bind, godot_object *p_instance, const void **p_args, void *p_ret);
+
+////// Script API
+
+typedef struct godot_dlscript_init_options {
+ godot_bool in_editor;
+ uint64_t core_api_hash;
+ uint64_t editor_api_hash;
+ uint64_t no_api_hash;
+} godot_dlscript_init_options;
+
+typedef struct godot_dlscript_terminate_options {
+ godot_bool in_editor;
+} godot_dlscript_terminate_options;
+
+typedef enum godot_method_rpc_mode {
+ GODOT_METHOD_RPC_MODE_DISABLED,
+ GODOT_METHOD_RPC_MODE_REMOTE,
+ GODOT_METHOD_RPC_MODE_SYNC,
+ GODOT_METHOD_RPC_MODE_MASTER,
+ GODOT_METHOD_RPC_MODE_SLAVE,
+} godot_method_rpc_mode;
+
+typedef struct godot_method_attributes {
+ godot_method_rpc_mode rpc_type;
+} godot_method_attributes;
+
+typedef enum godot_property_hint {
+ GODOT_PROPERTY_HINT_NONE, ///< no hint provided.
+ GODOT_PROPERTY_HINT_RANGE, ///< hint_text = "min,max,step,slider; //slider is optional"
+ GODOT_PROPERTY_HINT_EXP_RANGE, ///< hint_text = "min,max,step", exponential edit
+ GODOT_PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
+ GODOT_PROPERTY_HINT_EXP_EASING, /// exponential easing funciton (Math::ease)
+ GODOT_PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer)
+ GODOT_PROPERTY_HINT_SPRITE_FRAME,
+ GODOT_PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer)
+ GODOT_PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags)
+ GODOT_PROPERTY_HINT_LAYERS_2D_RENDER,
+ GODOT_PROPERTY_HINT_LAYERS_2D_PHYSICS,
+ GODOT_PROPERTY_HINT_LAYERS_3D_RENDER,
+ GODOT_PROPERTY_HINT_LAYERS_3D_PHYSICS,
+ GODOT_PROPERTY_HINT_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,"
+ GODOT_PROPERTY_HINT_DIR, ///< a directort path must be passed
+ GODOT_PROPERTY_HINT_GLOBAL_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,"
+ GODOT_PROPERTY_HINT_GLOBAL_DIR, ///< a directort path must be passed
+ GODOT_PROPERTY_HINT_RESOURCE_TYPE, ///< a resource object type
+ GODOT_PROPERTY_HINT_MULTILINE_TEXT, ///< used for string properties that can contain multiple lines
+ GODOT_PROPERTY_HINT_COLOR_NO_ALPHA, ///< used for ignoring alpha component when editing a color
+ GODOT_PROPERTY_HINT_IMAGE_COMPRESS_LOSSY,
+ GODOT_PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS,
+ GODOT_PROPERTY_HINT_OBJECT_ID,
+ GODOT_PROPERTY_HINT_TYPE_STRING, ///< a type string, the hint is the base type to choose
+ GODOT_PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE, ///< so something else can provide this (used in scripts)
+ GODOT_PROPERTY_HINT_METHOD_OF_VARIANT_TYPE, ///< a method of a type
+ GODOT_PROPERTY_HINT_METHOD_OF_BASE_TYPE, ///< a method of a base type
+ GODOT_PROPERTY_HINT_METHOD_OF_INSTANCE, ///< a method of an instance
+ GODOT_PROPERTY_HINT_METHOD_OF_SCRIPT, ///< a method of a script & base
+ GODOT_PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE, ///< a property of a type
+ GODOT_PROPERTY_HINT_PROPERTY_OF_BASE_TYPE, ///< a property of a base type
+ GODOT_PROPERTY_HINT_PROPERTY_OF_INSTANCE, ///< a property of an instance
+ GODOT_PROPERTY_HINT_PROPERTY_OF_SCRIPT, ///< a property of a script & base
+ GODOT_PROPERTY_HINT_MAX,
+} godot_property_hint;
+
+typedef enum godot_property_usage_flags {
+
+ GODOT_PROPERTY_USAGE_STORAGE = 1,
+ GODOT_PROPERTY_USAGE_EDITOR = 2,
+ GODOT_PROPERTY_USAGE_NETWORK = 4,
+ GODOT_PROPERTY_USAGE_EDITOR_HELPER = 8,
+ GODOT_PROPERTY_USAGE_CHECKABLE = 16, //used for editing global variables
+ GODOT_PROPERTY_USAGE_CHECKED = 32, //used for editing global variables
+ GODOT_PROPERTY_USAGE_INTERNATIONALIZED = 64, //hint for internationalized strings
+ GODOT_PROPERTY_USAGE_GROUP = 128, //used for grouping props in the editor
+ GODOT_PROPERTY_USAGE_CATEGORY = 256,
+ GODOT_PROPERTY_USAGE_STORE_IF_NONZERO = 512, //only store if nonzero
+ GODOT_PROPERTY_USAGE_STORE_IF_NONONE = 1024, //only store if false
+ GODOT_PROPERTY_USAGE_NO_INSTANCE_STATE = 2048,
+ GODOT_PROPERTY_USAGE_RESTART_IF_CHANGED = 4096,
+ GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE = 8192,
+ GODOT_PROPERTY_USAGE_STORE_IF_NULL = 16384,
+ GODOT_PROPERTY_USAGE_ANIMATE_AS_TRIGGER = 32768,
+ GODOT_PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED = 65536,
+
+ GODOT_PROPERTY_USAGE_DEFAULT = GODOT_PROPERTY_USAGE_STORAGE | GODOT_PROPERTY_USAGE_EDITOR | GODOT_PROPERTY_USAGE_NETWORK,
+ GODOT_PROPERTY_USAGE_DEFAULT_INTL = GODOT_PROPERTY_USAGE_STORAGE | GODOT_PROPERTY_USAGE_EDITOR | GODOT_PROPERTY_USAGE_NETWORK | GODOT_PROPERTY_USAGE_INTERNATIONALIZED,
+ GODOT_PROPERTY_USAGE_NOEDITOR = GODOT_PROPERTY_USAGE_STORAGE | GODOT_PROPERTY_USAGE_NETWORK,
+} godot_property_usage_flags;
+
+typedef struct godot_property_attributes {
+ godot_method_rpc_mode rset_type;
+
+ godot_int type;
+ godot_property_hint hint;
+ godot_string hint_string;
+ godot_property_usage_flags usage;
+ godot_variant default_value;
+} godot_property_attributes;
+
+typedef struct godot_instance_create_func {
+ // instance pointer, method_data - return user data
+ void *(*create_func)(godot_object *, void *);
+ void *method_data;
+ void (*free_func)(void *);
+} godot_script_instance_func;
+
+typedef struct godot_instance_destroy_func {
+ // instance pointer, method data, user data
+ void (*destroy_func)(godot_object *, void *, void *);
+ void *method_data;
+ void (*free_func)(void *);
+} godot_instance_destroy_func;
+
+void GDAPI godot_script_register_class(const char *p_name, const char *p_base, godot_instance_create_func p_create_func, godot_instance_destroy_func p_destroy_func);
+
+void GDAPI godot_script_register_tool_class(const char *p_name, const char *p_base, godot_instance_create_func p_create_func, godot_instance_destroy_func p_destroy_func);
+
+typedef struct godot_instance_method {
+ // instance pointer, method data, user data, num args, args - return result as varaint
+ godot_variant (*method)(godot_object *, void *, void *, int, godot_variant **);
+ void *method_data;
+ void (*free_func)(void *);
+} godot_instance_method;
+
+void GDAPI godot_script_register_method(const char *p_name, const char *p_function_name, godot_method_attributes p_attr, godot_instance_method p_method);
+
+typedef struct godot_property_set_func {
+ // instance pointer, method data, user data, value
+ void (*set_func)(godot_object *, void *, void *, godot_variant);
+ void *method_data;
+ void (*free_func)(void *);
+} godot_property_set_func;
+
+typedef struct godot_property_get_func {
+ // instance pointer, method data, user data, value
+ godot_variant (*get_func)(godot_object *, void *, void *);
+ void *method_data;
+ void (*free_func)(void *);
+} godot_property_get_func;
+
+void GDAPI godot_script_register_property(const char *p_name, const char *p_path, godot_property_attributes *p_attr, godot_property_set_func p_set_func, godot_property_get_func p_get_func);
+
+typedef struct godot_signal_argument {
+ godot_string name;
+ godot_int type;
+ godot_property_hint hint;
+ godot_string hint_string;
+ godot_property_usage_flags usage;
+ godot_variant default_value;
+} godot_signal_argument;
+
+typedef struct godot_signal {
+ godot_string name;
+ int num_args;
+ godot_signal_argument *args;
+ int num_default_args;
+ godot_variant *default_args;
+} godot_signal;
+
+void GDAPI godot_script_register_signal(const char *p_name, const godot_signal *p_signal);
+
+void GDAPI *godot_dlinstance_get_userdata(godot_object *p_instance);
+
+////// System Functions
+
+//using these will help Godot track how much memory is in use in debug mode
+void GDAPI *godot_alloc(int p_bytes);
+void GDAPI *godot_realloc(void *p_ptr, int p_bytes);
+void GDAPI godot_free(void *p_ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_C_H
diff --git a/modules/dlscript/godot/godot_array.cpp b/modules/dlscript/godot/godot_array.cpp
new file mode 100644
index 0000000000..21ad97ca78
--- /dev/null
+++ b/modules/dlscript/godot/godot_array.cpp
@@ -0,0 +1,271 @@
+#include "godot_array.h"
+
+#include "core/array.h"
+#include "core/os/memory.h"
+
+#include "core/color.h"
+#include "core/dvector.h"
+
+#include "core/variant.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _array_api_anchor() {
+}
+
+void GDAPI godot_array_new(godot_array *p_arr) {
+ Array *a = (Array *)p_arr;
+ memnew_placement(a, Array);
+}
+
+void GDAPI godot_array_new_pool_color_array(godot_array *p_arr, const godot_pool_color_array *p_pca) {
+ Array *a = (Array *)p_arr;
+ PoolVector<Color> *pca = (PoolVector<Color> *)p_pca;
+ memnew_placement(a, Array);
+ a->resize(pca->size());
+
+ for (size_t i = 0; i < a->size(); i++) {
+ Variant v = pca->operator[](i);
+ a->operator[](i) = v;
+ }
+}
+
+void GDAPI godot_array_new_pool_vector3_array(godot_array *p_arr, const godot_pool_vector3_array *p_pv3a) {
+ Array *a = (Array *)p_arr;
+ PoolVector<Vector3> *pca = (PoolVector<Vector3> *)p_pv3a;
+ memnew_placement(a, Array);
+ a->resize(pca->size());
+
+ for (size_t i = 0; i < a->size(); i++) {
+ Variant v = pca->operator[](i);
+ a->operator[](i) = v;
+ }
+}
+
+void GDAPI godot_array_new_pool_vector2_array(godot_array *p_arr, const godot_pool_vector2_array *p_pv2a) {
+ Array *a = (Array *)p_arr;
+ PoolVector<Vector2> *pca = (PoolVector<Vector2> *)p_pv2a;
+ memnew_placement(a, Array);
+ a->resize(pca->size());
+
+ for (size_t i = 0; i < a->size(); i++) {
+ Variant v = pca->operator[](i);
+ a->operator[](i) = v;
+ }
+}
+
+void GDAPI godot_array_new_pool_string_array(godot_array *p_arr, const godot_pool_string_array *p_psa) {
+ Array *a = (Array *)p_arr;
+ PoolVector<String> *pca = (PoolVector<String> *)p_psa;
+ memnew_placement(a, Array);
+ a->resize(pca->size());
+
+ for (size_t i = 0; i < a->size(); i++) {
+ Variant v = pca->operator[](i);
+ a->operator[](i) = v;
+ }
+}
+
+void GDAPI godot_array_new_pool_real_array(godot_array *p_arr, const godot_pool_real_array *p_pra) {
+ Array *a = (Array *)p_arr;
+ PoolVector<godot_real> *pca = (PoolVector<godot_real> *)p_pra;
+ memnew_placement(a, Array);
+ a->resize(pca->size());
+
+ for (size_t i = 0; i < a->size(); i++) {
+ Variant v = pca->operator[](i);
+ a->operator[](i) = v;
+ }
+}
+
+void GDAPI godot_array_new_pool_int_array(godot_array *p_arr, const godot_pool_int_array *p_pia) {
+ Array *a = (Array *)p_arr;
+ PoolVector<godot_int> *pca = (PoolVector<godot_int> *)p_pia;
+ memnew_placement(a, Array);
+ a->resize(pca->size());
+
+ for (size_t i = 0; i < a->size(); i++) {
+ Variant v = pca->operator[](i);
+ a->operator[](i) = v;
+ }
+}
+
+void GDAPI godot_array_new_pool_byte_array(godot_array *p_arr, const godot_pool_byte_array *p_pba) {
+ Array *a = (Array *)p_arr;
+ PoolVector<uint8_t> *pca = (PoolVector<uint8_t> *)p_pba;
+ memnew_placement(a, Array);
+ a->resize(pca->size());
+
+ for (size_t i = 0; i < a->size(); i++) {
+ Variant v = pca->operator[](i);
+ a->operator[](i) = v;
+ }
+}
+
+void GDAPI godot_array_set(godot_array *p_arr, const godot_int p_idx, const godot_variant *p_value) {
+ Array *a = (Array *)p_arr;
+ Variant *val = (Variant *)p_value;
+ a->operator[](p_idx) = *val;
+}
+
+godot_variant GDAPI *godot_array_get(godot_array *p_arr, const godot_int p_idx) {
+ Array *a = (Array *)p_arr;
+ return (godot_variant *)&a->operator[](p_idx);
+}
+
+void GDAPI godot_array_append(godot_array *p_arr, const godot_variant *p_value) {
+ Array *a = (Array *)p_arr;
+ Variant *val = (Variant *)p_value;
+ a->append(*val);
+}
+
+void GDAPI godot_array_clear(godot_array *p_arr) {
+ Array *a = (Array *)p_arr;
+ a->clear();
+}
+
+godot_int GDAPI godot_array_count(godot_array *p_arr, const godot_variant *p_value) {
+ Array *a = (Array *)p_arr;
+ Variant *val = (Variant *)p_value;
+ return a->count(*val);
+}
+
+godot_bool GDAPI godot_array_empty(const godot_array *p_arr) {
+ Array *a = (Array *)p_arr;
+ return a->empty();
+}
+
+void GDAPI godot_array_erase(godot_array *p_arr, const godot_variant *p_value) {
+ Array *a = (Array *)p_arr;
+ Variant *val = (Variant *)p_value;
+ a->erase(*val);
+}
+
+godot_variant GDAPI godot_array_front(const godot_array *p_arr) {
+ Array *a = (Array *)p_arr;
+ godot_variant v;
+ Variant *val = (Variant *)&v;
+ memnew_placement(val, Variant);
+ *val = a->front();
+ return v;
+}
+
+godot_variant GDAPI godot_array_back(const godot_array *p_arr) {
+ Array *a = (Array *)p_arr;
+ godot_variant v;
+ Variant *val = (Variant *)&v;
+ memnew_placement(val, Variant);
+ *val = a->back();
+ return v;
+}
+
+godot_int GDAPI godot_array_find(const godot_array *p_arr, const godot_variant *p_what, const godot_int p_from) {
+ Array *a = (Array *)p_arr;
+ Variant *val = (Variant *)p_what;
+ return a->find(*val, p_from);
+}
+
+godot_int GDAPI godot_array_find_last(const godot_array *p_arr, const godot_variant *p_what) {
+ Array *a = (Array *)p_arr;
+ Variant *val = (Variant *)p_what;
+ return a->find_last(*val);
+}
+
+godot_bool GDAPI godot_array_has(const godot_array *p_arr, const godot_variant *p_value) {
+ Array *a = (Array *)p_arr;
+ Variant *val = (Variant *)p_value;
+ return a->has(*val);
+}
+
+uint32_t GDAPI godot_array_hash(const godot_array *p_arr) {
+ Array *a = (Array *)p_arr;
+ return a->hash();
+}
+
+void GDAPI godot_array_insert(godot_array *p_arr, const godot_int p_pos, const godot_variant *p_value) {
+ Array *a = (Array *)p_arr;
+ Variant *val = (Variant *)p_value;
+ a->insert(p_pos, *val);
+}
+
+void GDAPI godot_array_invert(godot_array *p_arr) {
+ Array *a = (Array *)p_arr;
+ a->invert();
+}
+
+godot_bool GDAPI godot_array_is_shared(const godot_array *p_arr) {
+ Array *a = (Array *)p_arr;
+ return false; // @Todo how do I do it?
+}
+
+godot_variant GDAPI godot_array_pop_back(godot_array *p_arr) {
+ Array *a = (Array *)p_arr;
+ godot_variant v;
+ Variant *val = (Variant *)&v;
+ memnew_placement(val, Variant);
+ *val = a->pop_back();
+ return v;
+}
+
+godot_variant GDAPI godot_array_pop_front(godot_array *p_arr) {
+ Array *a = (Array *)p_arr;
+ godot_variant v;
+ Variant *val = (Variant *)&v;
+ memnew_placement(val, Variant);
+ *val = a->pop_front();
+ return v;
+}
+
+void GDAPI godot_array_push_back(godot_array *p_arr, const godot_variant *p_value) {
+ Array *a = (Array *)p_arr;
+ Variant *val = (Variant *)p_value;
+ a->push_back(*val);
+}
+
+void GDAPI godot_array_push_front(godot_array *p_arr, const godot_variant *p_value) {
+ Array *a = (Array *)p_arr;
+ Variant *val = (Variant *)p_value;
+ a->push_front(*val);
+}
+
+void GDAPI godot_array_remove(godot_array *p_arr, const godot_int p_idx) {
+ Array *a = (Array *)p_arr;
+ a->remove(p_idx);
+}
+
+void GDAPI godot_array_resize(godot_array *p_arr, const godot_int p_size) {
+ Array *a = (Array *)p_arr;
+ a->resize(p_size);
+}
+
+godot_int GDAPI godot_array_rfind(const godot_array *p_arr, const godot_variant *p_what, const godot_int p_from) {
+ Array *a = (Array *)p_arr;
+ Variant *val = (Variant *)p_what;
+ return a->rfind(*val, p_from);
+}
+
+godot_int GDAPI godot_array_size(const godot_array *p_arr) {
+ Array *a = (Array *)p_arr;
+ return a->size();
+}
+
+void GDAPI godot_array_sort(godot_array *p_arr) {
+ Array *a = (Array *)p_arr;
+ a->sort();
+}
+
+void GDAPI godot_array_sort_custom(godot_array *p_arr, godot_object *p_obj, const godot_string *p_func) {
+ Array *a = (Array *)p_arr;
+ String *func = (String *)p_func;
+ a->sort_custom((Object *)p_obj, *func);
+}
+
+void GDAPI godot_array_destroy(godot_array *p_arr) {
+ ((Array *)p_arr)->~Array();
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_array.h b/modules/dlscript/godot/godot_array.h
new file mode 100644
index 0000000000..544e95a2ed
--- /dev/null
+++ b/modules/dlscript/godot/godot_array.h
@@ -0,0 +1,88 @@
+#ifndef GODOT_DLSCRIPT_ARRAY_H
+#define GODOT_DLSCRIPT_ARRAY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_ARRAY_TYPE_DEFINED
+typedef struct godot_array {
+ uint8_t _dont_touch_that[8];
+} godot_array;
+#endif
+
+#include "../godot.h"
+
+#include "godot_pool_arrays.h"
+#include "godot_variant.h"
+
+void GDAPI godot_array_new(godot_array *p_arr);
+void GDAPI godot_array_new_pool_color_array(godot_array *p_arr, const godot_pool_color_array *p_pca);
+void GDAPI godot_array_new_pool_vector3_array(godot_array *p_arr, const godot_pool_vector3_array *p_pv3a);
+void GDAPI godot_array_new_pool_vector2_array(godot_array *p_arr, const godot_pool_vector2_array *p_pv2a);
+void GDAPI godot_array_new_pool_string_array(godot_array *p_arr, const godot_pool_string_array *p_psa);
+void GDAPI godot_array_new_pool_real_array(godot_array *p_arr, const godot_pool_real_array *p_pra);
+void GDAPI godot_array_new_pool_int_array(godot_array *p_arr, const godot_pool_int_array *p_pia);
+void GDAPI godot_array_new_pool_byte_array(godot_array *p_arr, const godot_pool_byte_array *p_pba);
+
+void GDAPI godot_array_set(godot_array *p_arr, const godot_int p_idx, const godot_variant *p_value);
+
+godot_variant GDAPI *godot_array_get(godot_array *p_arr, const godot_int p_idx);
+
+void GDAPI godot_array_append(godot_array *p_arr, const godot_variant *p_value);
+
+void GDAPI godot_array_clear(godot_array *p_arr);
+
+godot_int GDAPI godot_array_count(godot_array *p_arr, const godot_variant *p_value);
+
+godot_bool GDAPI godot_array_empty(const godot_array *p_arr);
+
+void GDAPI godot_array_erase(godot_array *p_arr, const godot_variant *p_value);
+
+godot_variant GDAPI godot_array_front(const godot_array *p_arr);
+
+godot_variant GDAPI godot_array_back(const godot_array *p_arr);
+
+godot_int GDAPI godot_array_find(const godot_array *p_arr, const godot_variant *p_what, const godot_int p_from);
+
+godot_int GDAPI godot_array_find_last(const godot_array *p_arr, const godot_variant *p_what);
+
+godot_bool GDAPI godot_array_has(const godot_array *p_arr, const godot_variant *p_value);
+
+uint32_t GDAPI godot_array_hash(const godot_array *p_arr);
+
+void GDAPI godot_array_insert(godot_array *p_arr, const godot_int p_pos, const godot_variant *p_value);
+
+void GDAPI godot_array_invert(godot_array *p_arr);
+
+godot_bool GDAPI godot_array_is_shared(const godot_array *p_arr);
+
+godot_variant GDAPI godot_array_pop_back(godot_array *p_arr);
+
+godot_variant GDAPI godot_array_pop_front(godot_array *p_arr);
+
+void GDAPI godot_array_push_back(godot_array *p_arr, const godot_variant *p_value);
+
+void GDAPI godot_array_push_front(godot_array *p_arr, const godot_variant *p_value);
+
+void GDAPI godot_array_remove(godot_array *p_arr, const godot_int p_idx);
+
+void GDAPI godot_array_resize(godot_array *p_arr, const godot_int p_size);
+
+godot_int GDAPI godot_array_rfind(const godot_array *p_arr, const godot_variant *p_what, const godot_int p_from);
+
+godot_int GDAPI godot_array_size(const godot_array *p_arr);
+
+void GDAPI godot_array_sort(godot_array *p_arr);
+
+void GDAPI godot_array_sort_custom(godot_array *p_arr, godot_object *p_obj, const godot_string *p_func);
+
+void GDAPI godot_array_destroy(godot_array *p_arr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_DLSCRIPT_ARRAY_H
diff --git a/modules/dlscript/godot/godot_basis.cpp b/modules/dlscript/godot/godot_basis.cpp
new file mode 100644
index 0000000000..813a531de5
--- /dev/null
+++ b/modules/dlscript/godot/godot_basis.cpp
@@ -0,0 +1,58 @@
+#include "godot_basis.h"
+
+#include "math/matrix3.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _basis_api_anchor() {
+}
+
+void GDAPI godot_basis_new(godot_basis *p_basis) {
+ Basis *basis = (Basis *)p_basis;
+ *basis = Basis();
+}
+
+void GDAPI godot_basis_new_with_euler_quat(godot_basis *p_basis, const godot_quat *p_euler) {
+ Basis *basis = (Basis *)p_basis;
+ Quat *euler = (Quat *)p_euler;
+ *basis = Basis(*euler);
+}
+
+void GDAPI godot_basis_new_with_euler(godot_basis *p_basis, const godot_vector3 *p_euler) {
+ Basis *basis = (Basis *)p_basis;
+ Vector3 *euler = (Vector3 *)p_euler;
+ *basis = Basis(*euler);
+}
+
+godot_quat GDAPI godot_basis_as_quat(const godot_basis *p_basis) {
+ const Basis *basis = (const Basis *)p_basis;
+ godot_quat quat;
+ Quat *p_quat = (Quat *)&quat;
+ *p_quat = basis->operator Quat();
+ return quat;
+}
+
+godot_vector3 GDAPI godot_basis_get_euler(const godot_basis *p_basis) {
+ const Basis *basis = (const Basis *)p_basis;
+ godot_vector3 euler;
+ Vector3 *p_euler = (Vector3 *)&euler;
+ *p_euler = basis->get_euler();
+ return euler;
+}
+
+/*
+ * p_elements is a pointer to an array of 3 (!!) vector3
+ */
+void GDAPI godot_basis_get_elements(godot_basis *p_basis, godot_vector3 *p_elements) {
+ Basis *basis = (Basis *)p_basis;
+ Vector3 *elements = (Vector3 *)p_elements;
+ elements[0] = basis->elements[0];
+ elements[1] = basis->elements[1];
+ elements[2] = basis->elements[2];
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_basis.h b/modules/dlscript/godot/godot_basis.h
new file mode 100644
index 0000000000..43efd65ea2
--- /dev/null
+++ b/modules/dlscript/godot/godot_basis.h
@@ -0,0 +1,34 @@
+#ifndef GODOT_DLSCRIPT_BASIS_H
+#define GODOT_DLSCRIPT_BASIS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_BASIS_TYPE_DEFINED
+typedef struct godot_basis {
+ uint8_t _dont_touch_that[36];
+} godot_basis;
+#endif
+
+#include "../godot.h"
+
+void GDAPI godot_basis_new(godot_basis *p_basis);
+void GDAPI godot_basis_new_with_euler_quat(godot_basis *p_basis, const godot_quat *p_euler);
+void GDAPI godot_basis_new_with_euler(godot_basis *p_basis, const godot_vector3 *p_euler);
+
+godot_quat GDAPI godot_basis_as_quat(const godot_basis *p_basis);
+godot_vector3 GDAPI godot_basis_get_euler(const godot_basis *p_basis);
+
+/*
+ * p_elements is a pointer to an array of 3 (!!) vector3
+ */
+void GDAPI godot_basis_get_elements(godot_basis *p_basis, godot_vector3 *p_elements);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_DLSCRIPT_BASIS_H
diff --git a/modules/dlscript/godot/godot_color.cpp b/modules/dlscript/godot/godot_color.cpp
new file mode 100644
index 0000000000..7e49565d40
--- /dev/null
+++ b/modules/dlscript/godot/godot_color.cpp
@@ -0,0 +1,34 @@
+#include "godot_color.h"
+
+#include "color.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _color_api_anchor() {
+}
+
+void GDAPI godot_color_new(godot_color *p_color) {
+ Color *color = (Color *)p_color;
+ *color = Color();
+}
+
+void GDAPI godot_color_new_rgba(godot_color *p_color, const godot_real r, const godot_real g, const godot_real b, const godot_real a) {
+ Color *color = (Color *)p_color;
+ *color = Color(r, g, b, a);
+}
+
+uint32_t GDAPI godot_color_get_32(const godot_color *p_color) {
+ const Color *color = (const Color *)p_color;
+ return color->to_32();
+}
+
+float GDAPI *godot_color_index(godot_color *p_color, const godot_int idx) {
+ Color *color = (Color *)p_color;
+ return &color->operator[](idx);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_color.h b/modules/dlscript/godot/godot_color.h
new file mode 100644
index 0000000000..72e16a2c5a
--- /dev/null
+++ b/modules/dlscript/godot/godot_color.h
@@ -0,0 +1,29 @@
+#ifndef GODOT_DLSCRIPT_COLOR_H
+#define GODOT_DLSCRIPT_COLOR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_COLOR_TYPE_DEFINED
+typedef struct godot_color {
+ uint8_t _dont_touch_that[16];
+} godot_color;
+#endif
+
+#include "../godot.h"
+
+void GDAPI godot_color_new(godot_color *p_color);
+void GDAPI godot_color_new_rgba(godot_color *p_color, const godot_real r, const godot_real g, const godot_real b, const godot_real a);
+
+uint32_t GDAPI godot_color_get_32(const godot_color *p_color);
+
+float GDAPI *godot_color_index(godot_color *p_color, const godot_int idx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_DLSCRIPT_COLOR_H
diff --git a/modules/dlscript/godot/godot_dictionary.cpp b/modules/dlscript/godot/godot_dictionary.cpp
new file mode 100644
index 0000000000..9147b17307
--- /dev/null
+++ b/modules/dlscript/godot/godot_dictionary.cpp
@@ -0,0 +1,109 @@
+#include "godot_dictionary.h"
+
+#include "core/dictionary.h"
+
+#include "core/os/memory.h"
+
+#include "core/io/json.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _dictionary_api_anchor() {
+}
+
+void GDAPI godot_dictionary_new(godot_dictionary *p_dict) {
+ Dictionary *dict = (Dictionary *)p_dict;
+ memnew_placement(dict, Dictionary);
+}
+
+void GDAPI godot_dictionary_clear(godot_dictionary *p_dict) {
+ Dictionary *dict = (Dictionary *)p_dict;
+ dict->clear();
+}
+
+godot_bool GDAPI godot_dictionary_empty(const godot_dictionary *p_dict) {
+ const Dictionary *dict = (const Dictionary *)p_dict;
+ return dict->empty();
+}
+
+void GDAPI godot_dictionary_erase(godot_dictionary *p_dict, const godot_variant *p_key) {
+ Dictionary *dict = (Dictionary *)p_dict;
+ Variant *key = (Variant *)p_key;
+ dict->erase(*key);
+}
+
+godot_bool GDAPI godot_dictionary_has(const godot_dictionary *p_dict, const godot_variant *p_key) {
+ const Dictionary *dict = (const Dictionary *)p_dict;
+ const Variant *key = (const Variant *)p_key;
+ return dict->has(*key);
+}
+
+godot_bool GDAPI godot_dictionary_has_all(const godot_dictionary *p_dict, const godot_array *p_keys) {
+ const Dictionary *dict = (const Dictionary *)p_dict;
+ const Array *keys = (const Array *)p_keys;
+ return dict->has_all(*keys);
+}
+
+uint32_t GDAPI godot_dictionary_hash(const godot_dictionary *p_dict) {
+ const Dictionary *dict = (const Dictionary *)p_dict;
+ return dict->hash();
+}
+
+godot_array GDAPI godot_dictionary_keys(const godot_dictionary *p_dict) {
+ godot_array a;
+ godot_array_new(&a);
+ const Dictionary *dict = (const Dictionary *)p_dict;
+ Array *array = (Array *)&a;
+ *array = dict->keys();
+ return a;
+}
+
+godot_int GDAPI godot_dictionary_parse_json(godot_dictionary *p_dict, const godot_string *p_json) {
+ Dictionary *dict = (Dictionary *)p_dict;
+ const String *json = (const String *)p_json;
+ Variant ret;
+ int err_line;
+ String err_str;
+ int err = (int)JSON::parse(*json, ret, err_str, err_line);
+ *dict = ret;
+ return err;
+}
+
+godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_dict, const godot_variant *p_key) {
+ Dictionary *dict = (Dictionary *)p_dict;
+ Variant *key = (Variant *)p_key;
+ return (godot_variant *)&dict->operator[](*key);
+}
+
+godot_int GDAPI godot_dictionary_size(const godot_dictionary *p_dict) {
+ const Dictionary *dict = (const Dictionary *)p_dict;
+ return dict->size();
+}
+
+godot_string GDAPI godot_dictionary_to_json(const godot_dictionary *p_dict) {
+ const Dictionary *dict = (const Dictionary *)p_dict;
+ godot_string str;
+ godot_string_new(&str);
+ String *s = (String *)&str;
+ *s = JSON::print(Variant(*dict));
+ return str;
+}
+
+godot_array GDAPI godot_dictionary_values(const godot_dictionary *p_dict) {
+ godot_array a;
+ godot_array_new(&a);
+ const Dictionary *dict = (const Dictionary *)p_dict;
+ Array *array = (Array *)&a;
+ *array = dict->values();
+ return a;
+}
+
+void GDAPI godot_dictionary_destroy(godot_dictionary *p_dict) {
+ ((Dictionary *)p_dict)->~Dictionary();
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_dictionary.h b/modules/dlscript/godot/godot_dictionary.h
new file mode 100644
index 0000000000..5f86cbca5a
--- /dev/null
+++ b/modules/dlscript/godot/godot_dictionary.h
@@ -0,0 +1,51 @@
+#ifndef GODOT_DLSCRIPT_DICTIONARY_H
+#define GODOT_DLSCRIPT_DICTIONARY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_DICITIONARY_TYPE_DEFINED
+typedef struct godot_dictionary {
+ uint8_t _dont_touch_that[8];
+} godot_dictionary;
+#endif
+
+#include "godot_array.h"
+#include "godot_variant.h"
+
+void GDAPI godot_dictionary_new(godot_dictionary *p_dict);
+
+void GDAPI godot_dictionary_clear(godot_dictionary *p_dict);
+
+godot_bool GDAPI godot_dictionary_empty(const godot_dictionary *p_dict);
+
+void GDAPI godot_dictionary_erase(godot_dictionary *p_dict, const godot_variant *p_key);
+
+godot_bool GDAPI godot_dictionary_has(const godot_dictionary *p_dict, const godot_variant *p_key);
+
+godot_bool GDAPI godot_dictionary_has_all(const godot_dictionary *p_dict, const godot_array *p_keys);
+
+uint32_t GDAPI godot_dictionary_hash(const godot_dictionary *p_dict);
+
+godot_array GDAPI godot_dictionary_keys(const godot_dictionary *p_dict);
+
+godot_int GDAPI godot_dictionary_parse_json(godot_dictionary *p_dict, const godot_string *p_json);
+
+godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_dict, const godot_variant *p_key);
+
+godot_int GDAPI godot_dictionary_size(const godot_dictionary *p_dict);
+
+godot_string GDAPI godot_dictionary_to_json(const godot_dictionary *p_dict);
+
+godot_array GDAPI godot_dictionary_values(const godot_dictionary *p_dict);
+
+void GDAPI godot_dictionary_destroy(godot_dictionary *p_dict);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_DLSCRIPT_DICTIONARY_H
diff --git a/modules/dlscript/godot/godot_image.cpp b/modules/dlscript/godot/godot_image.cpp
new file mode 100644
index 0000000000..362d1aa3e6
--- /dev/null
+++ b/modules/dlscript/godot/godot_image.cpp
@@ -0,0 +1,85 @@
+#include "godot_image.h"
+
+#include "image.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _image_api_anchor() {
+}
+
+#define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr)
+
+void GDAPI godot_image_new(godot_image *p_img) {
+ Image *img = (Image *)p_img;
+ memnew_placement_custom(img, Image, Image());
+}
+
+void GDAPI godot_image_new_with_png_jpg(godot_image *p_img, const uint8_t *p_mem_png_jpg, int p_len) {
+ Image *img = (Image *)p_img;
+ memnew_placement_custom(img, Image, Image(p_mem_png_jpg, p_len));
+}
+
+void GDAPI godot_image_new_with_xpm(godot_image *p_img, const char **p_xpm) {
+ Image *img = (Image *)p_img;
+ memnew_placement_custom(img, Image, Image(p_xpm));
+}
+
+void GDAPI godot_image_new_with_size_format(godot_image *p_img, int p_width, int p_height, bool p_use_mipmaps, godot_image_format p_format) {
+ Image *img = (Image *)p_img;
+ memnew_placement_custom(img, Image, Image(p_width, p_height, p_use_mipmaps, (Image::Format)p_format));
+}
+
+void GDAPI godot_image_new_with_size_format_data(godot_image *p_img, int p_width, int p_height, bool p_use_mipmaps, godot_image_format p_format, godot_pool_byte_array *p_data) {
+ Image *img = (Image *)p_img;
+ PoolVector<uint8_t> *data = (PoolVector<uint8_t> *)p_data;
+ memnew_placement_custom(img, Image, Image(p_width, p_height, p_use_mipmaps, (Image::Format)p_format, *data));
+}
+
+godot_pool_byte_array GDAPI godot_image_get_data(godot_image *p_img) {
+ Image *img = (Image *)p_img;
+ PoolVector<uint8_t> cpp_data = img->get_data();
+ godot_pool_byte_array *data = (godot_pool_byte_array *)&cpp_data;
+ return *data;
+}
+
+godot_error GDAPI godot_image_load(godot_image *p_img, const godot_string *p_path) {
+ Image *img = (Image *)p_img;
+ String *path = (String *)p_path;
+ return (godot_error)img->load(*path);
+}
+
+godot_error GDAPI godot_image_save_png(godot_image *p_img, const godot_string *p_path) {
+ Image *img = (Image *)p_img;
+ String *path = (String *)p_path;
+ return (godot_error)img->save_png(*path);
+}
+
+int GDAPI godot_image_get_width(const godot_image *p_img) {
+ Image *img = (Image *)p_img;
+ return img->get_width();
+}
+
+int GDAPI godot_image_get_height(const godot_image *p_img) {
+ Image *img = (Image *)p_img;
+ return img->get_height();
+}
+
+godot_bool GDAPI godot_image_has_mipmaps(const godot_image *p_img) {
+ Image *img = (Image *)p_img;
+ return img->has_mipmaps();
+}
+
+int GDAPI godot_image_get_mipmap_count(const godot_image *p_img) {
+ Image *img = (Image *)p_img;
+ return img->get_mipmap_count();
+}
+
+void GDAPI godot_image_destroy(godot_image *p_img) {
+ ((Image *)p_img)->~Image();
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_image.h b/modules/dlscript/godot/godot_image.h
new file mode 100644
index 0000000000..78593f21a7
--- /dev/null
+++ b/modules/dlscript/godot/godot_image.h
@@ -0,0 +1,95 @@
+#ifndef GODOT_DLSCRIPT_IMAGE_H
+#define GODOT_DLSCRIPT_IMAGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_IMAGE_TYPE_DEFINED
+typedef struct godot_image {
+ uint8_t _dont_touch_that[32];
+} godot_image;
+#endif
+
+#include "godot_pool_arrays.h"
+
+#include "../godot.h"
+
+// This is a copypasta of the C++ enum inside the Image class
+// There's no neat way of automatically updating the C enum / using the C++ enum directly
+// if somebody knows a way feel free to open a PR or open an issue (or ask for Karroffel or bojidar-bg on IRC)
+
+enum godot_image_format {
+
+ GODOT_IMAGE_FORMAT_L8, //luminance
+ GODOT_IMAGE_FORMAT_LA8, //luminance-alpha
+ GODOT_IMAGE_FORMAT_R8,
+ GODOT_IMAGE_FORMAT_RG8,
+ GODOT_IMAGE_FORMAT_RGB8,
+ GODOT_IMAGE_FORMAT_RGBA8,
+ GODOT_IMAGE_FORMAT_RGB565, //16 bit
+ GODOT_IMAGE_FORMAT_RGBA4444,
+ GODOT_IMAGE_FORMAT_RGBA5551,
+ GODOT_IMAGE_FORMAT_RF, //float
+ GODOT_IMAGE_FORMAT_RGF,
+ GODOT_IMAGE_FORMAT_RGBF,
+ GODOT_IMAGE_FORMAT_RGBAF,
+ GODOT_IMAGE_FORMAT_RH, //half float
+ GODOT_IMAGE_FORMAT_RGH,
+ GODOT_IMAGE_FORMAT_RGBH,
+ GODOT_IMAGE_FORMAT_RGBAH,
+ GODOT_IMAGE_FORMAT_DXT1, //s3tc bc1
+ GODOT_IMAGE_FORMAT_DXT3, //bc2
+ GODOT_IMAGE_FORMAT_DXT5, //bc3
+ GODOT_IMAGE_FORMAT_ATI1, //bc4
+ GODOT_IMAGE_FORMAT_ATI2, //bc5
+ GODOT_IMAGE_FORMAT_BPTC_RGBA, //btpc bc6h
+ GODOT_IMAGE_FORMAT_BPTC_RGBF, //float /
+ GODOT_IMAGE_FORMAT_BPTC_RGBFU, //unsigned float
+ GODOT_IMAGE_FORMAT_PVRTC2, //pvrtc
+ GODOT_IMAGE_FORMAT_PVRTC2A,
+ GODOT_IMAGE_FORMAT_PVRTC4,
+ GODOT_IMAGE_FORMAT_PVRTC4A,
+ GODOT_IMAGE_FORMAT_ETC, //etc1
+ GODOT_IMAGE_FORMAT_ETC2_R11, //etc2
+ GODOT_IMAGE_FORMAT_ETC2_R11S, //signed, NOT srgb.
+ GODOT_IMAGE_FORMAT_ETC2_RG11,
+ GODOT_IMAGE_FORMAT_ETC2_RG11S,
+ GODOT_IMAGE_FORMAT_ETC2_RGB8,
+ GODOT_IMAGE_FORMAT_ETC2_RGBA8,
+ GODOT_IMAGE_FORMAT_ETC2_RGB8A1,
+ GODOT_IMAGE_FORMAT_MAX
+};
+typedef enum godot_image_format godot_image_format;
+
+void GDAPI godot_image_new(godot_image *p_img);
+// p_len can be -1
+void GDAPI godot_image_new_with_png_jpg(godot_image *p_img, const uint8_t *p_mem_png_jpg, int p_len);
+void GDAPI godot_image_new_with_xpm(godot_image *p_img, const char **p_xpm);
+
+void GDAPI godot_image_new_with_size_format(godot_image *p_img, int p_width, int p_height, bool p_use_mipmaps, godot_image_format p_format);
+void GDAPI godot_image_new_with_size_format_data(godot_image *p_img, int p_width, int p_height, bool p_use_mipmaps, godot_image_format p_format, godot_pool_byte_array *p_data);
+
+godot_pool_byte_array GDAPI godot_image_get_data(godot_image *p_img);
+
+godot_error GDAPI godot_image_load(godot_image *p_img, const godot_string *p_path);
+godot_error GDAPI godot_image_save_png(godot_image *p_img, const godot_string *p_path);
+
+int GDAPI godot_image_get_width(const godot_image *p_img);
+int GDAPI godot_image_get_height(const godot_image *p_img);
+godot_bool GDAPI godot_image_has_mipmaps(const godot_image *p_img);
+int GDAPI godot_image_get_mipmap_count(const godot_image *p_img);
+
+// @Incomplete
+// I think it's too complex for the binding authors to implement the image class anew, so we should definitely
+// export all methods here. That takes a while so it's on my @Todo list
+
+void GDAPI godot_image_destroy(godot_image *p_img);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_DLSCRIPT_IMAGE_H
diff --git a/modules/dlscript/godot/godot_input_event.cpp b/modules/dlscript/godot/godot_input_event.cpp
new file mode 100644
index 0000000000..b50ed8a22d
--- /dev/null
+++ b/modules/dlscript/godot/godot_input_event.cpp
@@ -0,0 +1,280 @@
+#include "godot_input_event.h"
+
+#include "os/input_event.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _input_event_api_anchor() {
+}
+
+void GDAPI godot_input_event_new(godot_input_event *p_ie) {
+ InputEvent *ie = (InputEvent *)p_ie;
+ *ie = InputEvent();
+}
+
+godot_bool GDAPI godot_input_event_is_pressed(const godot_input_event *p_ie) {
+ const InputEvent *ie = (const InputEvent *)p_ie;
+ return ie->is_pressed();
+}
+
+godot_bool GDAPI godot_input_event_is_action(const godot_input_event *p_ie, const godot_string *p_action) {
+ const InputEvent *ie = (const InputEvent *)p_ie;
+ const String *action = (const String *)p_action;
+ return ie->is_action(*action);
+}
+
+godot_bool GDAPI godot_input_event_is_action_pressed(const godot_input_event *p_ie, const godot_string *p_action) {
+ const InputEvent *ie = (const InputEvent *)p_ie;
+ const String *action = (const String *)p_action;
+ return ie->is_action_pressed(*action);
+}
+
+godot_bool GDAPI godot_input_event_is_action_released(const godot_input_event *p_ie, const godot_string *p_action) {
+ const InputEvent *ie = (const InputEvent *)p_ie;
+ const String *action = (const String *)p_action;
+ return ie->is_action_released(*action);
+}
+
+godot_bool GDAPI godot_input_event_is_echo(const godot_input_event *p_ie) {
+ const InputEvent *ie = (const InputEvent *)p_ie;
+ return ie->is_echo();
+}
+
+void GDAPI godot_input_event_set_as_action(godot_input_event *p_ie, const godot_string *p_action, const godot_bool p_pressed) {
+ InputEvent *ie = (InputEvent *)p_ie;
+ const String *action = (const String *)p_action;
+ return ie->set_as_action(*action, p_pressed);
+}
+
+godot_string GDAPI godot_input_event_as_string(const godot_input_event *p_ie) {
+ const InputEvent *ie = (const InputEvent *)p_ie;
+ godot_string str;
+ String *s = (String *)&str;
+ memnew_placement(s, String);
+ *s = (String)*ie;
+ return str;
+}
+
+uint32_t GDAPI *godot_input_event_get_id(godot_input_event *p_ie) {
+ InputEvent *ie = (InputEvent *)p_ie;
+ return &ie->ID;
+}
+
+godot_input_event_type GDAPI *godot_input_event_get_type(godot_input_event *p_ie) {
+ InputEvent *ie = (InputEvent *)p_ie;
+ return (godot_input_event_type *)&ie->type;
+}
+
+godot_int GDAPI *godot_input_event_get_device(godot_input_event *p_ie) {
+ InputEvent *ie = (InputEvent *)p_ie;
+ return &ie->device;
+}
+
+static InputModifierState *_get_mod_for_type(InputEvent *ie) {
+ switch (ie->type) {
+ case InputEvent::MOUSE_BUTTON:
+ return &ie->mouse_button.mod;
+ case InputEvent::MOUSE_MOTION:
+ return &ie->mouse_motion.mod;
+ case InputEvent::KEY:
+ return &ie->key.mod;
+ default:
+ return 0;
+ }
+}
+
+godot_bool GDAPI *godot_input_event_mod_get_alt(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ InputModifierState *mod = _get_mod_for_type(ie);
+ return &mod->alt;
+}
+
+godot_bool GDAPI *godot_input_event_mod_get_ctrl(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ InputModifierState *mod = _get_mod_for_type(ie);
+ return &mod->control;
+}
+
+godot_bool GDAPI *godot_input_event_mod_get_command(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ InputModifierState *mod = _get_mod_for_type(ie);
+ return &mod->command;
+}
+
+godot_bool GDAPI *godot_input_event_mod_get_shift(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ InputModifierState *mod = _get_mod_for_type(ie);
+ return &mod->shift;
+}
+
+godot_bool GDAPI *godot_input_event_mod_get_meta(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ InputModifierState *mod = _get_mod_for_type(ie);
+ return &mod->meta;
+}
+
+uint32_t GDAPI *godot_input_event_key_get_scancode(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->key.scancode;
+}
+
+uint32_t GDAPI *godot_input_event_key_get_unicode(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->key.unicode;
+}
+
+godot_bool GDAPI *godot_input_event_key_get_pressed(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->key.pressed;
+}
+
+godot_bool GDAPI *godot_input_event_key_get_echo(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->key.echo;
+}
+
+float GDAPI *godot_input_event_mouse_get_x(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->mouse_button.x;
+}
+
+float GDAPI *godot_input_event_mouse_get_y(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->mouse_button.y;
+}
+
+float GDAPI *godot_input_event_mouse_get_global_x(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->mouse_button.global_x;
+}
+
+float GDAPI *godot_input_event_mouse_get_global_y(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->mouse_button.global_y;
+}
+
+godot_int GDAPI *godot_input_event_mouse_get_button_mask(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->mouse_button.button_mask;
+}
+
+godot_int GDAPI *godot_input_event_mouse_button_get_button_index(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->mouse_button.button_index;
+}
+
+godot_bool GDAPI *godot_input_event_mouse_button_get_pressed(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->mouse_button.pressed;
+}
+
+godot_bool GDAPI *godot_input_event_mouse_button_get_doubleclick(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->mouse_button.doubleclick;
+}
+
+float GDAPI *godot_input_event_mouse_motion_get_relative_x(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->mouse_motion.relative_x;
+}
+
+float GDAPI *godot_input_event_mouse_motion_get_relative_y(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->mouse_motion.relative_y;
+}
+
+float GDAPI *godot_input_event_mouse_motion_get_speed_x(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->mouse_motion.speed_x;
+}
+
+float GDAPI *godot_input_event_mouse_motion_get_speed_y(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->mouse_motion.speed_y;
+}
+
+godot_int GDAPI *godot_input_event_joypad_motion_get_axis(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->joy_motion.axis;
+}
+
+float GDAPI *godot_input_event_joypad_motion_get_axis_value(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->joy_motion.axis_value;
+}
+
+godot_int GDAPI *godot_input_event_joypad_button_get_button_index(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->joy_button.button_index;
+}
+
+godot_bool GDAPI *godot_input_event_joypad_button_get_pressed(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->joy_button.pressed;
+}
+
+float GDAPI *godot_input_event_joypad_button_get_pressure(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->joy_button.pressure;
+}
+
+godot_int GDAPI *godot_input_event_screen_touch_get_index(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->screen_touch.index;
+}
+
+float GDAPI *godot_input_event_screen_touch_get_x(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->screen_touch.x;
+}
+
+float GDAPI *godot_input_event_screen_touch_get_y(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->screen_touch.y;
+}
+
+godot_bool GDAPI *godot_input_event_screen_touch_get_pressed(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->screen_touch.pressed;
+}
+
+godot_int GDAPI *godot_input_event_screen_drag_get_index(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->screen_drag.index;
+}
+
+float GDAPI *godot_input_event_screen_drag_get_x(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->screen_drag.x;
+}
+
+float GDAPI *godot_input_event_screen_drag_get_y(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->screen_drag.y;
+}
+
+float GDAPI *godot_input_event_screen_drag_get_relative_x(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->screen_drag.relative_x;
+}
+
+float GDAPI *godot_input_event_screen_drag_get_relative_y(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->screen_drag.relative_y;
+}
+
+float GDAPI *godot_input_event_screen_drag_get_speed_x(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->screen_drag.speed_x;
+}
+
+float GDAPI *godot_input_event_screen_drag_get_speed_y(godot_input_event *p_event) {
+ InputEvent *ie = (InputEvent *)p_event;
+ return &ie->screen_drag.speed_y;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_input_event.h b/modules/dlscript/godot/godot_input_event.h
new file mode 100644
index 0000000000..bfda18bf7c
--- /dev/null
+++ b/modules/dlscript/godot/godot_input_event.h
@@ -0,0 +1,206 @@
+#ifndef GODOT_DLSCRIPT_INPUT_EVENT_H
+#define GODOT_DLSCRIPT_INPUT_EVENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_INPUT_EVENT_TYPE_DEFINED
+typedef struct godot_input_event {
+ uint8_t _dont_touch_that[56];
+} godot_input_event;
+#endif
+
+enum godot_input_event_type {
+ GODOT_INPUT_EVENT_TYPE_NONE,
+ GODOT_INPUT_EVENT_TYPE_KEY,
+ GODOT_INPUT_EVENT_TYPE_MOUSE_MOTION,
+ GODOT_INPUT_EVENT_TYPE_MOUSE_BUTTON,
+ GODOT_INPUT_EVENT_TYPE_JOYPAD_MOTION,
+ GODOT_INPUT_EVENT_TYPE_JOYPAD_BUTTON,
+ GODOT_INPUT_EVENT_TYPE_SCREEN_TOUCH,
+ GODOT_INPUT_EVENT_TYPE_SCREEN_DRAG,
+ GODOT_INPUT_EVENT_TYPE_ACTION,
+ GODOT_INPUT_EVENT_TYPE_TYPE_MAX
+};
+typedef enum godot_input_event_type godot_input_event_type;
+
+enum {
+ GODOT_BUTTON_LEFT = 1,
+ GODOT_BUTTON_RIGHT = 2,
+ GODOT_BUTTON_MIDDLE = 3,
+ GODOT_BUTTON_WHEEL_UP = 4,
+ GODOT_BUTTON_WHEEL_DOWN = 5,
+ GODOT_BUTTON_WHEEL_LEFT = 6,
+ GODOT_BUTTON_WHEEL_RIGHT = 7,
+ GODOT_BUTTON_MASK_LEFT = (1 << (GODOT_BUTTON_LEFT - 1)),
+ GODOT_BUTTON_MASK_RIGHT = (1 << (GODOT_BUTTON_RIGHT - 1)),
+ GODOT_BUTTON_MASK_MIDDLE = (1 << (GODOT_BUTTON_MIDDLE - 1)),
+
+};
+
+enum {
+
+ GODOT_JOY_BUTTON_0 = 0,
+ GODOT_JOY_BUTTON_1 = 1,
+ GODOT_JOY_BUTTON_2 = 2,
+ GODOT_JOY_BUTTON_3 = 3,
+ GODOT_JOY_BUTTON_4 = 4,
+ GODOT_JOY_BUTTON_5 = 5,
+ GODOT_JOY_BUTTON_6 = 6,
+ GODOT_JOY_BUTTON_7 = 7,
+ GODOT_JOY_BUTTON_8 = 8,
+ GODOT_JOY_BUTTON_9 = 9,
+ GODOT_JOY_BUTTON_10 = 10,
+ GODOT_JOY_BUTTON_11 = 11,
+ GODOT_JOY_BUTTON_12 = 12,
+ GODOT_JOY_BUTTON_13 = 13,
+ GODOT_JOY_BUTTON_14 = 14,
+ GODOT_JOY_BUTTON_15 = 15,
+ GODOT_JOY_BUTTON_MAX = 16,
+
+ GODOT_JOY_L = GODOT_JOY_BUTTON_4,
+ GODOT_JOY_R = GODOT_JOY_BUTTON_5,
+ GODOT_JOY_L2 = GODOT_JOY_BUTTON_6,
+ GODOT_JOY_R2 = GODOT_JOY_BUTTON_7,
+ GODOT_JOY_L3 = GODOT_JOY_BUTTON_8,
+ GODOT_JOY_R3 = GODOT_JOY_BUTTON_9,
+ GODOT_JOY_SELECT = GODOT_JOY_BUTTON_10,
+ GODOT_JOY_START = GODOT_JOY_BUTTON_11,
+ GODOT_JOY_DPAD_UP = GODOT_JOY_BUTTON_12,
+ GODOT_JOY_DPAD_DOWN = GODOT_JOY_BUTTON_13,
+ GODOT_JOY_DPAD_LEFT = GODOT_JOY_BUTTON_14,
+ GODOT_JOY_DPAD_RIGHT = GODOT_JOY_BUTTON_15,
+
+ // a little history about game controllers (who copied who)
+
+ GODOT_JOY_SNES_B = GODOT_JOY_BUTTON_0,
+ GODOT_JOY_SNES_A = GODOT_JOY_BUTTON_1,
+ GODOT_JOY_SNES_Y = GODOT_JOY_BUTTON_2,
+ GODOT_JOY_SNES_X = GODOT_JOY_BUTTON_3,
+
+ GODOT_JOY_SONY_CIRCLE = GODOT_JOY_SNES_A,
+ GODOT_JOY_SONY_X = GODOT_JOY_SNES_B,
+ GODOT_JOY_SONY_SQUARE = GODOT_JOY_SNES_Y,
+ GODOT_JOY_SONY_TRIANGLE = GODOT_JOY_SNES_X,
+
+ GODOT_JOY_SEGA_B = GODOT_JOY_SNES_A,
+ GODOT_JOY_SEGA_A = GODOT_JOY_SNES_B,
+ GODOT_JOY_SEGA_X = GODOT_JOY_SNES_Y,
+ GODOT_JOY_SEGA_Y = GODOT_JOY_SNES_X,
+
+ GODOT_JOY_XBOX_B = GODOT_JOY_SEGA_B,
+ GODOT_JOY_XBOX_A = GODOT_JOY_SEGA_A,
+ GODOT_JOY_XBOX_X = GODOT_JOY_SEGA_X,
+ GODOT_JOY_XBOX_Y = GODOT_JOY_SEGA_Y,
+
+ GODOT_JOY_DS_A = GODOT_JOY_SNES_A,
+ GODOT_JOY_DS_B = GODOT_JOY_SNES_B,
+ GODOT_JOY_DS_X = GODOT_JOY_SNES_X,
+ GODOT_JOY_DS_Y = GODOT_JOY_SNES_Y,
+
+ GODOT_JOY_WII_C = GODOT_JOY_BUTTON_5,
+ GODOT_JOY_WII_Z = GODOT_JOY_BUTTON_6,
+
+ GODOT_JOY_WII_MINUS = GODOT_JOY_BUTTON_9,
+ GODOT_JOY_WII_PLUS = GODOT_JOY_BUTTON_10,
+
+ // end of history
+
+ GODOT_JOY_AXIS_0 = 0,
+ GODOT_JOY_AXIS_1 = 1,
+ GODOT_JOY_AXIS_2 = 2,
+ GODOT_JOY_AXIS_3 = 3,
+ GODOT_JOY_AXIS_4 = 4,
+ GODOT_JOY_AXIS_5 = 5,
+ GODOT_JOY_AXIS_6 = 6,
+ GODOT_JOY_AXIS_7 = 7,
+ GODOT_JOY_AXIS_MAX = 8,
+
+ GODOT_JOY_ANALOG_0_X = GODOT_JOY_AXIS_0,
+ GODOT_JOY_ANALOG_0_Y = GODOT_JOY_AXIS_1,
+
+ GODOT_JOY_ANALOG_1_X = GODOT_JOY_AXIS_2,
+ GODOT_JOY_ANALOG_1_Y = GODOT_JOY_AXIS_3,
+
+ GODOT_JOY_ANALOG_2_X = GODOT_JOY_AXIS_4,
+ GODOT_JOY_ANALOG_2_Y = GODOT_JOY_AXIS_5,
+
+ GODOT_JOY_ANALOG_L2 = GODOT_JOY_AXIS_6,
+ GODOT_JOY_ANALOG_R2 = GODOT_JOY_AXIS_7,
+};
+
+#include "../godot.h"
+
+void GDAPI godot_input_event_new(godot_input_event *p_ie);
+
+godot_bool GDAPI godot_input_event_is_pressed(const godot_input_event *p_ie);
+godot_bool GDAPI godot_input_event_is_action(const godot_input_event *p_ie, const godot_string *p_action);
+godot_bool GDAPI godot_input_event_is_action_pressed(const godot_input_event *p_ie, const godot_string *p_action);
+godot_bool GDAPI godot_input_event_is_action_released(const godot_input_event *p_ie, const godot_string *p_action);
+godot_bool GDAPI godot_input_event_is_echo(const godot_input_event *p_ie);
+void GDAPI godot_input_event_set_as_action(godot_input_event *p_ie, const godot_string *p_action, const godot_bool p_pressed);
+
+godot_string GDAPI godot_input_event_as_string(const godot_input_event *p_ie);
+
+// Note:
+// We're returning pointers to the fields in the unions.
+// This is because I'm too lazy to write setter functions
+
+uint32_t GDAPI *godot_input_event_get_id(godot_input_event *p_ie);
+godot_input_event_type GDAPI *godot_input_event_get_type(godot_input_event *p_ie);
+godot_int GDAPI *godot_input_event_get_device(godot_input_event *p_ie);
+
+godot_bool GDAPI *godot_input_event_mod_get_alt(godot_input_event *p_event);
+godot_bool GDAPI *godot_input_event_mod_get_ctrl(godot_input_event *p_event);
+godot_bool GDAPI *godot_input_event_mod_get_command(godot_input_event *p_event);
+godot_bool GDAPI *godot_input_event_mod_get_shift(godot_input_event *p_event);
+godot_bool GDAPI *godot_input_event_mod_get_meta(godot_input_event *p_event);
+
+uint32_t GDAPI *godot_input_event_key_get_scancode(godot_input_event *p_event);
+uint32_t GDAPI *godot_input_event_key_get_unicode(godot_input_event *p_event);
+godot_bool GDAPI *godot_input_event_key_get_pressed(godot_input_event *p_event);
+godot_bool GDAPI *godot_input_event_key_get_echo(godot_input_event *p_event);
+
+float GDAPI *godot_input_event_mouse_get_x(godot_input_event *p_event);
+float GDAPI *godot_input_event_mouse_get_y(godot_input_event *p_event);
+float GDAPI *godot_input_event_mouse_get_global_x(godot_input_event *p_event);
+float GDAPI *godot_input_event_mouse_get_global_y(godot_input_event *p_event);
+godot_int GDAPI *godot_input_event_mouse_get_button_mask(godot_input_event *p_event);
+
+godot_int GDAPI *godot_input_event_mouse_button_get_button_index(godot_input_event *p_event);
+godot_bool GDAPI *godot_input_event_mouse_button_get_pressed(godot_input_event *p_event);
+godot_bool GDAPI *godot_input_event_mouse_button_get_doubleclick(godot_input_event *p_event);
+
+float GDAPI *godot_input_event_mouse_motion_get_relative_x(godot_input_event *p_event);
+float GDAPI *godot_input_event_mouse_motion_get_relative_y(godot_input_event *p_event);
+float GDAPI *godot_input_event_mouse_motion_get_speed_x(godot_input_event *p_event);
+float GDAPI *godot_input_event_mouse_motion_get_speed_y(godot_input_event *p_event);
+
+godot_int GDAPI *godot_input_event_joypad_motion_get_axis(godot_input_event *p_event);
+float GDAPI *godot_input_event_joypad_motion_get_axis_value(godot_input_event *p_event);
+
+godot_int GDAPI *godot_input_event_joypad_button_get_button_index(godot_input_event *p_event);
+godot_bool GDAPI *godot_input_event_joypad_button_get_pressed(godot_input_event *p_event);
+float GDAPI *godot_input_event_joypad_button_get_pressure(godot_input_event *p_event);
+
+godot_int GDAPI *godot_input_event_screen_touch_get_index(godot_input_event *p_event);
+float GDAPI *godot_input_event_screen_touch_get_x(godot_input_event *p_event);
+float GDAPI *godot_input_event_screen_touch_get_y(godot_input_event *p_event);
+godot_bool GDAPI *godot_input_event_screen_touch_get_pressed(godot_input_event *p_event);
+
+godot_int GDAPI *godot_input_event_screen_drag_get_index(godot_input_event *p_event);
+float GDAPI *godot_input_event_screen_drag_get_x(godot_input_event *p_event);
+float GDAPI *godot_input_event_screen_drag_get_y(godot_input_event *p_event);
+float GDAPI *godot_input_event_screen_drag_get_relative_x(godot_input_event *p_event);
+float GDAPI *godot_input_event_screen_drag_get_relative_y(godot_input_event *p_event);
+float GDAPI *godot_input_event_screen_drag_get_speed_x(godot_input_event *p_event);
+float GDAPI *godot_input_event_screen_drag_get_speed_y(godot_input_event *p_event);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_DLSCRIPT_INPUT_EVENT_H
diff --git a/modules/dlscript/godot/godot_node_path.cpp b/modules/dlscript/godot/godot_node_path.cpp
new file mode 100644
index 0000000000..8b79175e44
--- /dev/null
+++ b/modules/dlscript/godot/godot_node_path.cpp
@@ -0,0 +1,91 @@
+#include "godot_node_path.h"
+
+#include "path_db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _node_path_api_anchor() {
+}
+
+#define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr)
+
+// @Bug ?
+// Do I need to memnew_placement when returning strings?
+
+void GDAPI godot_node_path_new(godot_node_path *p_np, const godot_string *p_from) {
+ NodePath *np = (NodePath *)p_np;
+ String *from = (String *)p_from;
+ memnew_placement_custom(np, NodePath, NodePath(*from));
+}
+
+void GDAPI godot_node_path_copy(godot_node_path *p_np, const godot_node_path *p_from) {
+ NodePath *np = (NodePath *)p_np;
+ NodePath *from = (NodePath *)p_from;
+ *np = *from;
+}
+
+godot_string GDAPI godot_node_path_get_name(const godot_node_path *p_np, const godot_int p_idx) {
+ const NodePath *np = (const NodePath *)p_np;
+ godot_string str;
+ String *s = (String *)&str;
+ memnew_placement(s, String);
+ *s = np->get_name(p_idx);
+ return str;
+}
+
+godot_int GDAPI godot_node_path_get_name_count(const godot_node_path *p_np) {
+ const NodePath *np = (const NodePath *)p_np;
+ return np->get_name_count();
+}
+
+godot_string GDAPI godot_node_path_get_property(const godot_node_path *p_np) {
+ const NodePath *np = (const NodePath *)p_np;
+ godot_string str;
+ String *s = (String *)&str;
+ memnew_placement(s, String);
+ *s = np->get_property();
+ return str;
+}
+
+godot_string GDAPI godot_node_path_get_subname(const godot_node_path *p_np, const godot_int p_idx) {
+ const NodePath *np = (const NodePath *)p_np;
+ godot_string str;
+ String *s = (String *)&str;
+ memnew_placement(s, String);
+ *s = np->get_subname(p_idx);
+ return str;
+}
+
+godot_int GDAPI godot_node_path_get_subname_count(const godot_node_path *p_np) {
+ const NodePath *np = (const NodePath *)p_np;
+ return np->get_subname_count();
+}
+
+godot_bool GDAPI godot_node_path_is_absolute(const godot_node_path *p_np) {
+ const NodePath *np = (const NodePath *)p_np;
+ return np->is_absolute();
+}
+
+godot_bool GDAPI godot_node_path_is_empty(const godot_node_path *p_np) {
+ const NodePath *np = (const NodePath *)p_np;
+ return np->is_empty();
+}
+
+godot_string GDAPI godot_node_path_as_string(const godot_node_path *p_np) {
+ const NodePath *np = (const NodePath *)p_np;
+ godot_string str;
+ String *s = (String *)&str;
+ memnew_placement(s, String);
+ *s = *np;
+ return str;
+}
+
+void GDAPI godot_node_path_destroy(godot_node_path *p_np) {
+ ((NodePath *)p_np)->~NodePath();
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_node_path.h b/modules/dlscript/godot/godot_node_path.h
new file mode 100644
index 0000000000..04f1e70c1d
--- /dev/null
+++ b/modules/dlscript/godot/godot_node_path.h
@@ -0,0 +1,39 @@
+#ifndef GODOT_DLSCRIPT_NODE_PATH_H
+#define GODOT_DLSCRIPT_NODE_PATH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_NODE_PATH_TYPE_DEFINED
+typedef struct godot_node_path {
+ uint8_t _dont_touch_that[8];
+} godot_node_path;
+#endif
+
+#include "../godot.h"
+
+void GDAPI godot_node_path_new(godot_node_path *p_np, const godot_string *p_from);
+void GDAPI godot_node_path_copy(godot_node_path *p_np, const godot_node_path *p_from);
+
+godot_string GDAPI godot_node_path_get_name(const godot_node_path *p_np, const godot_int p_idx);
+godot_int GDAPI godot_node_path_get_name_count(const godot_node_path *p_np);
+
+godot_string GDAPI godot_node_path_get_property(const godot_node_path *p_np);
+godot_string GDAPI godot_node_path_get_subname(const godot_node_path *p_np, const godot_int p_idx);
+godot_int GDAPI godot_node_path_get_subname_count(const godot_node_path *p_np);
+
+godot_bool GDAPI godot_node_path_is_absolute(const godot_node_path *p_np);
+godot_bool GDAPI godot_node_path_is_empty(const godot_node_path *p_np);
+
+godot_string GDAPI godot_node_path_as_string(const godot_node_path *p_np);
+
+void GDAPI godot_node_path_destroy(godot_node_path *p_np);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_DLSCRIPT_NODE_PATH_H
diff --git a/modules/dlscript/godot/godot_plane.cpp b/modules/dlscript/godot/godot_plane.cpp
new file mode 100644
index 0000000000..883aeb6282
--- /dev/null
+++ b/modules/dlscript/godot/godot_plane.cpp
@@ -0,0 +1,48 @@
+#include "godot_plane.h"
+
+#include "math/plane.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _plane_api_anchor() {
+}
+
+void GDAPI godot_plane_new(godot_plane *p_pl) {
+ Plane *pl = (Plane *)p_pl;
+ *pl = Plane();
+}
+
+void GDAPI godot_plane_new_with_normal(godot_plane *p_pl, const godot_vector3 *p_normal, const godot_real p_d) {
+ Plane *pl = (Plane *)p_pl;
+ const Vector3 *normal = (const Vector3 *)p_normal;
+ *pl = Plane(*normal, p_d);
+}
+
+void GDAPI godot_plane_set_normal(godot_plane *p_pl, const godot_vector3 *p_normal) {
+ Plane *pl = (Plane *)p_pl;
+ const Vector3 *normal = (const Vector3 *)p_normal;
+ pl->set_normal(*normal);
+}
+
+godot_vector3 godot_plane_get_normal(const godot_plane *p_pl) {
+ const Plane *pl = (const Plane *)p_pl;
+ const Vector3 normal = pl->get_normal();
+ godot_vector3 *v3 = (godot_vector3 *)&normal;
+ return *v3;
+}
+
+void GDAPI godot_plane_set_d(godot_plane *p_pl, const godot_real p_d) {
+ Plane *pl = (Plane *)p_pl;
+ pl->d = p_d;
+}
+
+godot_real GDAPI godot_plane_get_d(const godot_plane *p_pl) {
+ const Plane *pl = (const Plane *)p_pl;
+ return pl->d;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_plane.h b/modules/dlscript/godot/godot_plane.h
new file mode 100644
index 0000000000..1323ef4075
--- /dev/null
+++ b/modules/dlscript/godot/godot_plane.h
@@ -0,0 +1,37 @@
+#ifndef GODOT_DLSCRIPT_PLANE_H
+#define GODOT_DLSCRIPT_PLANE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_PLANE_TYPE_DEFINED
+typedef struct godot_plane {
+ uint8_t _dont_touch_that[16];
+} godot_plane;
+#endif
+
+#include "godot_vector3.h"
+
+void GDAPI godot_plane_new(godot_plane *p_pl);
+void GDAPI godot_plane_new_with_normal(godot_plane *p_pl, const godot_vector3 *p_normal, const godot_real p_d);
+
+// @Incomplete
+// These are additional valid constructors
+// _FORCE_INLINE_ Plane(const Vector3 &p_normal, real_t p_d);
+// _FORCE_INLINE_ Plane(const Vector3 &p_point, const Vector3& p_normal);
+// _FORCE_INLINE_ Plane(const Vector3 &p_point1, const Vector3 &p_point2,const Vector3 &p_point3,ClockDirection p_dir = CLOCKWISE);
+
+void GDAPI godot_plane_set_normal(godot_plane *p_pl, const godot_vector3 *p_normal);
+godot_vector3 GDAPI godot_plane_get_normal(const godot_plane *p_pl);
+
+godot_real GDAPI godot_plane_get_d(const godot_plane *p_pl);
+void GDAPI godot_plane_set_d(godot_plane *p_pl, const godot_real p_d);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_DLSCRIPT_PLANE_H
diff --git a/modules/dlscript/godot/godot_pool_arrays.cpp b/modules/dlscript/godot/godot_pool_arrays.cpp
new file mode 100644
index 0000000000..3fb030f835
--- /dev/null
+++ b/modules/dlscript/godot/godot_pool_arrays.cpp
@@ -0,0 +1,558 @@
+#include "godot_pool_arrays.h"
+
+#include "array.h"
+#include "dvector.h"
+#include "variant.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _pool_arrays_api_anchor() {
+}
+
+#define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr)
+
+// byte
+
+void GDAPI godot_pool_byte_array_new(godot_pool_byte_array *p_pba) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ memnew_placement(pba, PoolVector<uint8_t>);
+}
+
+void GDAPI godot_pool_byte_array_new_with_array(godot_pool_byte_array *p_pba, const godot_array *p_a) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ Array *a = (Array *)p_a;
+ memnew_placement(pba, PoolVector<uint8_t>);
+
+ pba->resize(a->size());
+ for (size_t i = 0; i < a->size(); i++) {
+ pba->set(i, (*a)[i]);
+ }
+}
+
+void GDAPI godot_pool_byte_array_append(godot_pool_byte_array *p_pba, const uint8_t p_data) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ pba->append(p_data);
+}
+
+void GDAPI godot_pool_byte_array_append_array(godot_pool_byte_array *p_pba, const godot_pool_byte_array *p_array) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ PoolVector<uint8_t> *array = (PoolVector<uint8_t> *)p_array;
+ pba->append_array(*array);
+}
+
+int GDAPI godot_pool_byte_array_insert(godot_pool_byte_array *p_pba, const godot_int p_idx, const uint8_t p_data) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ return pba->insert(p_idx, p_data);
+}
+
+void GDAPI godot_pool_byte_array_invert(godot_pool_byte_array *p_pba) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ pba->invert();
+}
+
+void GDAPI godot_pool_byte_array_push_back(godot_pool_byte_array *p_pba, const uint8_t p_data) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ pba->push_back(p_data);
+}
+
+void GDAPI godot_pool_byte_array_remove(godot_pool_byte_array *p_pba, const godot_int p_idx) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ pba->remove(p_idx);
+}
+
+void GDAPI godot_pool_byte_array_resize(godot_pool_byte_array *p_pba, const godot_int p_size) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ pba->resize(p_size);
+}
+
+void GDAPI godot_pool_byte_array_set(godot_pool_byte_array *p_pba, const godot_int p_idx, const uint8_t p_data) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ pba->set(p_idx, p_data);
+}
+
+uint8_t GDAPI godot_pool_byte_array_get(godot_pool_byte_array *p_pba, const godot_int p_idx) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ return pba->get(p_idx);
+}
+
+godot_int GDAPI godot_pool_byte_array_size(godot_pool_byte_array *p_pba) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ return pba->size();
+}
+
+void GDAPI godot_pool_byte_array_destroy(godot_pool_byte_array *p_pba) {
+ ((PoolVector<uint8_t> *)p_pba)->~PoolVector();
+}
+
+// int
+
+void GDAPI godot_pool_int_array_new(godot_pool_int_array *p_pba) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ memnew_placement(pba, PoolVector<uint8_t>);
+}
+
+void GDAPI godot_pool_int_array_new_with_array(godot_pool_int_array *p_pba, const godot_array *p_a) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ Array *a = (Array *)p_a;
+ memnew_placement(pba, PoolVector<uint8_t>);
+
+ pba->resize(a->size());
+ for (size_t i = 0; i < a->size(); i++) {
+ pba->set(i, (*a)[i]);
+ }
+}
+
+void GDAPI godot_pool_int_array_append(godot_pool_int_array *p_pba, const godot_int p_data) {
+ PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
+ pba->append(p_data);
+}
+
+void GDAPI godot_pool_int_array_append_array(godot_pool_int_array *p_pba, const godot_pool_int_array *p_array) {
+ PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
+ PoolVector<godot_int> *array = (PoolVector<godot_int> *)p_array;
+ pba->append_array(*array);
+}
+
+int GDAPI godot_pool_int_array_insert(godot_pool_int_array *p_pba, const godot_int p_idx, const godot_int p_data) {
+ PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
+ return pba->insert(p_idx, p_data);
+}
+
+void GDAPI godot_pool_int_array_invert(godot_pool_int_array *p_pba) {
+ PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
+ pba->invert();
+}
+
+void GDAPI godot_pool_int_array_push_back(godot_pool_int_array *p_pba, const godot_int p_data) {
+ PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
+ pba->push_back(p_data);
+}
+
+void GDAPI godot_pool_int_array_remove(godot_pool_int_array *p_pba, const godot_int p_idx) {
+ PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
+ pba->remove(p_idx);
+}
+
+void GDAPI godot_pool_int_array_resize(godot_pool_int_array *p_pba, const godot_int p_size) {
+ PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
+ pba->resize(p_size);
+}
+
+void GDAPI godot_pool_int_array_set(godot_pool_int_array *p_pba, const godot_int p_idx, const godot_int p_data) {
+ PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
+ pba->set(p_idx, p_data);
+}
+
+godot_int GDAPI godot_pool_int_array_get(godot_pool_int_array *p_pba, const godot_int p_idx) {
+ PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
+ return pba->get(p_idx);
+}
+
+godot_int GDAPI godot_pool_int_array_size(godot_pool_int_array *p_pba) {
+ PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
+ return pba->size();
+}
+
+void GDAPI godot_pool_int_array_destroy(godot_pool_int_array *p_pba) {
+ ((PoolVector<godot_int> *)p_pba)->~PoolVector();
+}
+
+// real
+
+void GDAPI godot_pool_real_array_new(godot_pool_real_array *p_pba) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ memnew_placement(pba, PoolVector<uint8_t>);
+}
+
+void GDAPI godot_pool_real_array_new_with_array(godot_pool_real_array *p_pba, const godot_array *p_a) {
+ PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+ Array *a = (Array *)p_a;
+ memnew_placement(pba, PoolVector<uint8_t>);
+
+ pba->resize(a->size());
+ for (size_t i = 0; i < a->size(); i++) {
+ pba->set(i, (*a)[i]);
+ }
+}
+
+void GDAPI godot_pool_real_array_append(godot_pool_real_array *p_pba, const godot_real p_data) {
+ PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
+ pba->append(p_data);
+}
+
+void GDAPI godot_pool_real_array_append_array(godot_pool_real_array *p_pba, const godot_pool_real_array *p_array) {
+ PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
+ PoolVector<godot_real> *array = (PoolVector<godot_real> *)p_array;
+ pba->append_array(*array);
+}
+
+int GDAPI godot_pool_real_array_insert(godot_pool_real_array *p_pba, const godot_int p_idx, const godot_real p_data) {
+ PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
+ return pba->insert(p_idx, p_data);
+}
+
+void GDAPI godot_pool_real_array_invert(godot_pool_real_array *p_pba) {
+ PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
+ pba->invert();
+}
+
+void GDAPI godot_pool_real_array_push_back(godot_pool_real_array *p_pba, const godot_real p_data) {
+ PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
+ pba->push_back(p_data);
+}
+
+void GDAPI godot_pool_real_array_remove(godot_pool_real_array *p_pba, const godot_int p_idx) {
+ PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
+ pba->remove(p_idx);
+}
+
+void GDAPI godot_pool_real_array_resize(godot_pool_real_array *p_pba, const godot_int p_size) {
+ PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
+ pba->resize(p_size);
+}
+
+void GDAPI godot_pool_real_array_set(godot_pool_real_array *p_pba, const godot_int p_idx, const godot_real p_data) {
+ PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
+ pba->set(p_idx, p_data);
+}
+
+godot_real GDAPI godot_pool_real_array_get(godot_pool_real_array *p_pba, const godot_int p_idx) {
+ PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
+ return pba->get(p_idx);
+}
+
+godot_int GDAPI godot_pool_real_array_size(godot_pool_real_array *p_pba) {
+ PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
+ return pba->size();
+}
+
+void GDAPI godot_pool_real_array_destroy(godot_pool_real_array *p_pba) {
+ ((PoolVector<godot_real> *)p_pba)->~PoolVector();
+}
+
+// string
+
+void GDAPI godot_pool_string_array_new(godot_pool_string_array *p_pba) {
+ PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+ memnew_placement(pba, PoolVector<String>);
+}
+
+void GDAPI godot_pool_string_array_new_with_array(godot_pool_string_array *p_pba, const godot_array *p_a) {
+ PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+ Array *a = (Array *)p_a;
+ memnew_placement(pba, PoolVector<String>);
+
+ pba->resize(a->size());
+ for (size_t i = 0; i < a->size(); i++) {
+ pba->set(i, (*a)[i]);
+ }
+}
+
+void GDAPI godot_pool_string_array_append(godot_pool_string_array *p_pba, const godot_string *p_data) {
+ PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+ String &s = *(String *)p_data;
+ pba->append(s);
+}
+
+void GDAPI godot_pool_string_array_append_array(godot_pool_string_array *p_pba, const godot_pool_string_array *p_array) {
+ PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+ PoolVector<String> *array = (PoolVector<String> *)p_array;
+ pba->append_array(*array);
+}
+
+int GDAPI godot_pool_string_array_insert(godot_pool_string_array *p_pba, const godot_int p_idx, const godot_string *p_data) {
+ PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+ String &s = *(String *)p_data;
+ return pba->insert(p_idx, s);
+}
+
+void GDAPI godot_pool_string_array_invert(godot_pool_string_array *p_pba) {
+ PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+ pba->invert();
+}
+
+void GDAPI godot_pool_string_array_push_back(godot_pool_string_array *p_pba, const godot_string *p_data) {
+ PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+ String &s = *(String *)p_data;
+ pba->push_back(s);
+}
+
+void GDAPI godot_pool_string_array_remove(godot_pool_string_array *p_pba, const godot_int p_idx) {
+ PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+ pba->remove(p_idx);
+}
+
+void GDAPI godot_pool_string_array_resize(godot_pool_string_array *p_pba, const godot_int p_size) {
+ PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+ pba->resize(p_size);
+}
+
+void GDAPI godot_pool_string_array_set(godot_pool_string_array *p_pba, const godot_int p_idx, const godot_string *p_data) {
+ PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+ String &s = *(String *)p_data;
+ pba->set(p_idx, s);
+}
+
+godot_string GDAPI godot_pool_string_array_get(godot_pool_string_array *p_pba, const godot_int p_idx) {
+ PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+ godot_string str;
+ String *s = (String *)&str;
+ memnew_placement(s, String);
+ *s = pba->get(p_idx);
+ return str;
+}
+
+godot_int GDAPI godot_pool_string_array_size(godot_pool_string_array *p_pba) {
+ PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+ return pba->size();
+}
+
+void GDAPI godot_pool_string_array_destroy(godot_pool_string_array *p_pba) {
+ ((PoolVector<String> *)p_pba)->~PoolVector();
+}
+
+// vector2
+
+void GDAPI godot_pool_vector2_array_new(godot_pool_vector2_array *p_pba) {
+ PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+ memnew_placement(pba, PoolVector<Vector2>);
+}
+
+void GDAPI godot_pool_vector2_array_new_with_array(godot_pool_vector2_array *p_pba, const godot_array *p_a) {
+ PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+ Array *a = (Array *)p_a;
+ memnew_placement(pba, PoolVector<Vector2>);
+
+ pba->resize(a->size());
+ for (size_t i = 0; i < a->size(); i++) {
+ pba->set(i, (*a)[i]);
+ }
+}
+
+void GDAPI godot_pool_vector2_array_append(godot_pool_vector2_array *p_pba, const godot_vector2 *p_data) {
+ PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+ Vector2 &s = *(Vector2 *)p_data;
+ pba->append(s);
+}
+
+void GDAPI godot_pool_vector2_array_append_array(godot_pool_vector2_array *p_pba, const godot_pool_vector2_array *p_array) {
+ PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+ PoolVector<Vector2> *array = (PoolVector<Vector2> *)p_array;
+ pba->append_array(*array);
+}
+
+int GDAPI godot_pool_vector2_array_insert(godot_pool_vector2_array *p_pba, const godot_int p_idx, const godot_vector2 *p_data) {
+ PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+ Vector2 &s = *(Vector2 *)p_data;
+ return pba->insert(p_idx, s);
+}
+
+void GDAPI godot_pool_vector2_array_invert(godot_pool_vector2_array *p_pba) {
+ PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+ pba->invert();
+}
+
+void GDAPI godot_pool_vector2_array_push_back(godot_pool_vector2_array *p_pba, const godot_vector2 *p_data) {
+ PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+ Vector2 &s = *(Vector2 *)p_data;
+ pba->push_back(s);
+}
+
+void GDAPI godot_pool_vector2_array_remove(godot_pool_vector2_array *p_pba, const godot_int p_idx) {
+ PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+ pba->remove(p_idx);
+}
+
+void GDAPI godot_pool_vector2_array_resize(godot_pool_vector2_array *p_pba, const godot_int p_size) {
+ PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+ pba->resize(p_size);
+}
+
+void GDAPI godot_pool_vector2_array_set(godot_pool_vector2_array *p_pba, const godot_int p_idx, const godot_vector2 *p_data) {
+ PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+ Vector2 &s = *(Vector2 *)p_data;
+ pba->set(p_idx, s);
+}
+
+godot_vector2 GDAPI godot_pool_vector2_array_get(godot_pool_vector2_array *p_pba, const godot_int p_idx) {
+ PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+ godot_vector2 v;
+ Vector2 *s = (Vector2 *)&v;
+ *s = pba->get(p_idx);
+ return v;
+}
+
+godot_int GDAPI godot_pool_vector2_array_size(godot_pool_vector2_array *p_pba) {
+ PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+ return pba->size();
+}
+
+void GDAPI godot_pool_vector2_array_destroy(godot_pool_vector2_array *p_pba) {
+ ((PoolVector<Vector2> *)p_pba)->~PoolVector();
+}
+
+// vector3
+
+void GDAPI godot_pool_vector3_array_new(godot_pool_vector3_array *p_pba) {
+ PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+ memnew_placement(pba, PoolVector<Vector3>);
+}
+
+void GDAPI godot_pool_vector3_array_new_with_array(godot_pool_vector3_array *p_pba, const godot_array *p_a) {
+ PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+ Array *a = (Array *)p_a;
+ memnew_placement(pba, PoolVector<Vector3>);
+
+ pba->resize(a->size());
+ for (size_t i = 0; i < a->size(); i++) {
+ pba->set(i, (*a)[i]);
+ }
+}
+
+void GDAPI godot_pool_vector3_array_append(godot_pool_vector3_array *p_pba, const godot_vector3 *p_data) {
+ PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+ Vector3 &s = *(Vector3 *)p_data;
+ pba->append(s);
+}
+
+void GDAPI godot_pool_vector3_array_append_array(godot_pool_vector3_array *p_pba, const godot_pool_vector3_array *p_array) {
+ PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+ PoolVector<Vector3> *array = (PoolVector<Vector3> *)p_array;
+ pba->append_array(*array);
+}
+
+int GDAPI godot_pool_vector3_array_insert(godot_pool_vector3_array *p_pba, const godot_int p_idx, const godot_vector3 *p_data) {
+ PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+ Vector3 &s = *(Vector3 *)p_data;
+ return pba->insert(p_idx, s);
+}
+
+void GDAPI godot_pool_vector3_array_invert(godot_pool_vector3_array *p_pba) {
+ PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+ pba->invert();
+}
+
+void GDAPI godot_pool_vector3_array_push_back(godot_pool_vector3_array *p_pba, const godot_vector3 *p_data) {
+ PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+ Vector3 &s = *(Vector3 *)p_data;
+ pba->push_back(s);
+}
+
+void GDAPI godot_pool_vector3_array_remove(godot_pool_vector3_array *p_pba, const godot_int p_idx) {
+ PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+ pba->remove(p_idx);
+}
+
+void GDAPI godot_pool_vector3_array_resize(godot_pool_vector3_array *p_pba, const godot_int p_size) {
+ PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+ pba->resize(p_size);
+}
+
+void GDAPI godot_pool_vector3_array_set(godot_pool_vector3_array *p_pba, const godot_int p_idx, const godot_vector3 *p_data) {
+ PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+ Vector3 &s = *(Vector3 *)p_data;
+ pba->set(p_idx, s);
+}
+
+godot_vector3 GDAPI godot_pool_vector3_array_get(godot_pool_vector3_array *p_pba, const godot_int p_idx) {
+ PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+ godot_vector3 v;
+ Vector3 *s = (Vector3 *)&v;
+ *s = pba->get(p_idx);
+ return v;
+}
+
+godot_int GDAPI godot_pool_vector3_array_size(godot_pool_vector3_array *p_pba) {
+ PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+ return pba->size();
+}
+
+void GDAPI godot_pool_vector3_array_destroy(godot_pool_vector3_array *p_pba) {
+ ((PoolVector<Vector3> *)p_pba)->~PoolVector();
+}
+
+// color
+
+void GDAPI godot_pool_color_array_new(godot_pool_color_array *p_pba) {
+ PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+ memnew_placement(pba, PoolVector<Color>);
+}
+
+void GDAPI godot_pool_color_array_new_with_array(godot_pool_color_array *p_pba, const godot_array *p_a) {
+ PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+ Array *a = (Array *)p_a;
+ memnew_placement(pba, PoolVector<Color>);
+
+ pba->resize(a->size());
+ for (size_t i = 0; i < a->size(); i++) {
+ pba->set(i, (*a)[i]);
+ }
+}
+
+void GDAPI godot_pool_color_array_append(godot_pool_color_array *p_pba, const godot_color *p_data) {
+ PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+ Color &s = *(Color *)p_data;
+ pba->append(s);
+}
+
+void GDAPI godot_pool_color_array_append_array(godot_pool_color_array *p_pba, const godot_pool_color_array *p_array) {
+ PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+ PoolVector<Color> *array = (PoolVector<Color> *)p_array;
+ pba->append_array(*array);
+}
+
+int GDAPI godot_pool_color_array_insert(godot_pool_color_array *p_pba, const godot_int p_idx, const godot_color *p_data) {
+ PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+ Color &s = *(Color *)p_data;
+ return pba->insert(p_idx, s);
+}
+
+void GDAPI godot_pool_color_array_invert(godot_pool_color_array *p_pba) {
+ PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+ pba->invert();
+}
+
+void GDAPI godot_pool_color_array_push_back(godot_pool_color_array *p_pba, const godot_color *p_data) {
+ PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+ Color &s = *(Color *)p_data;
+ pba->push_back(s);
+}
+
+void GDAPI godot_pool_color_array_remove(godot_pool_color_array *p_pba, const godot_int p_idx) {
+ PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+ pba->remove(p_idx);
+}
+
+void GDAPI godot_pool_color_array_resize(godot_pool_color_array *p_pba, const godot_int p_size) {
+ PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+ pba->resize(p_size);
+}
+
+void GDAPI godot_pool_color_array_set(godot_pool_color_array *p_pba, const godot_int p_idx, const godot_color *p_data) {
+ PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+ Color &s = *(Color *)p_data;
+ pba->set(p_idx, s);
+}
+
+godot_color GDAPI godot_pool_color_array_get(godot_pool_color_array *p_pba, const godot_int p_idx) {
+ PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+ godot_color v;
+ Color *s = (Color *)&v;
+ *s = pba->get(p_idx);
+ return v;
+}
+
+godot_int GDAPI godot_pool_color_array_size(godot_pool_color_array *p_pba) {
+ PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+ return pba->size();
+}
+
+void GDAPI godot_pool_color_array_destroy(godot_pool_color_array *p_pba) {
+ ((PoolVector<Color> *)p_pba)->~PoolVector();
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_pool_arrays.h b/modules/dlscript/godot/godot_pool_arrays.h
new file mode 100644
index 0000000000..77b6c3dde0
--- /dev/null
+++ b/modules/dlscript/godot/godot_pool_arrays.h
@@ -0,0 +1,256 @@
+#ifndef GODOT_DLSCRIPT_POOL_ARRAYS_H
+#define GODOT_DLSCRIPT_POOL_ARRAYS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+/////// PoolByteArray
+
+#ifndef GODOT_CORE_API_GODOT_POOL_BYTE_ARRAY_TYPE_DEFINED
+typedef struct godot_pool_byte_array {
+ uint8_t _dont_touch_that[8];
+} godot_pool_byte_array;
+#endif
+
+/////// PoolIntArray
+
+#ifndef GODOT_CORE_API_GODOT_POOL_INT_ARRAY_TYPE_DEFINED
+typedef struct godot_pool_int_array {
+ uint8_t _dont_touch_that[8];
+} godot_pool_int_array;
+#endif
+
+/////// PoolRealArray
+
+#ifndef GODOT_CORE_API_GODOT_POOL_REAL_ARRAY_TYPE_DEFINED
+typedef struct godot_pool_real_array {
+ uint8_t _dont_touch_that[8];
+} godot_pool_real_array;
+#endif
+
+/////// PoolStringArray
+
+#ifndef GODOT_CORE_API_GODOT_POOL_STRING_ARRAY_TYPE_DEFINED
+typedef struct godot_pool_string_array {
+ uint8_t _dont_touch_that[8];
+} godot_pool_string_array;
+#endif
+
+/////// PoolVector2Array
+
+#ifndef GODOT_CORE_API_GODOT_POOL_VECTOR2_ARRAY_TYPE_DEFINED
+typedef struct godot_pool_vector2_array {
+ uint8_t _dont_touch_that[8];
+} godot_pool_vector2_array;
+#endif
+
+/////// PoolVector3Array
+
+#ifndef GODOT_CORE_API_GODOT_POOL_VECTOR3_ARRAY_TYPE_DEFINED
+typedef struct godot_pool_vector3_array {
+ uint8_t _dont_touch_that[8];
+} godot_pool_vector3_array;
+#endif
+
+/////// PoolColorArray
+
+#ifndef GODOT_CORE_API_GODOT_POOL_COLOR_ARRAY_TYPE_DEFINED
+typedef struct godot_pool_color_array {
+ uint8_t _dont_touch_that[8];
+} godot_pool_color_array;
+#endif
+
+#include "../godot.h"
+
+#include "godot_array.h"
+
+// byte
+
+void GDAPI godot_pool_byte_array_new(godot_pool_byte_array *p_pba);
+void GDAPI godot_pool_byte_array_new_with_array(godot_pool_byte_array *p_pba, const godot_array *p_a);
+
+void GDAPI godot_pool_byte_array_append(godot_pool_byte_array *p_pba, const uint8_t p_data);
+
+void GDAPI godot_pool_byte_array_append_array(godot_pool_byte_array *p_pba, const godot_pool_byte_array *p_array);
+
+int GDAPI godot_pool_byte_array_insert(godot_pool_byte_array *p_pba, const godot_int p_idx, const uint8_t p_data);
+
+void GDAPI godot_pool_byte_array_invert(godot_pool_byte_array *p_pba);
+
+void GDAPI godot_pool_byte_array_push_back(godot_pool_byte_array *p_pba, const uint8_t p_data);
+
+void GDAPI godot_pool_byte_array_remove(godot_pool_byte_array *p_pba, const godot_int p_idx);
+
+void GDAPI godot_pool_byte_array_resize(godot_pool_byte_array *p_pba, const godot_int p_size);
+
+void GDAPI godot_pool_byte_array_set(godot_pool_byte_array *p_pba, const godot_int p_idx, const uint8_t p_data);
+uint8_t GDAPI godot_pool_byte_array_get(godot_pool_byte_array *p_pba, const godot_int p_idx);
+
+godot_int GDAPI godot_pool_byte_array_size(godot_pool_byte_array *p_pba);
+
+void GDAPI godot_pool_byte_array_destroy(godot_pool_byte_array *p_pba);
+
+// int
+
+void GDAPI godot_pool_int_array_new(godot_pool_int_array *p_pia);
+void GDAPI godot_pool_int_array_new_with_array(godot_pool_int_array *p_pia, const godot_array *p_a);
+
+void GDAPI godot_pool_int_array_append(godot_pool_int_array *p_pia, const godot_int p_data);
+
+void GDAPI godot_pool_int_array_append_array(godot_pool_int_array *p_pia, const godot_pool_int_array *p_array);
+
+int GDAPI godot_pool_int_array_insert(godot_pool_int_array *p_pia, const godot_int p_idx, const godot_int p_data);
+
+void GDAPI godot_pool_int_array_invert(godot_pool_int_array *p_pia);
+
+void GDAPI godot_pool_int_array_push_back(godot_pool_int_array *p_pia, const godot_int p_data);
+
+void GDAPI godot_pool_int_array_remove(godot_pool_int_array *p_pia, const godot_int p_idx);
+
+void GDAPI godot_pool_int_array_resize(godot_pool_int_array *p_pia, const godot_int p_size);
+
+void GDAPI godot_pool_int_array_set(godot_pool_int_array *p_pia, const godot_int p_idx, const godot_int p_data);
+godot_int GDAPI godot_pool_int_array_get(godot_pool_int_array *p_pia, const godot_int p_idx);
+
+godot_int GDAPI godot_pool_int_array_size(godot_pool_int_array *p_pia);
+
+void GDAPI godot_pool_int_array_destroy(godot_pool_int_array *p_pia);
+
+// real
+
+void GDAPI godot_pool_real_array_new(godot_pool_real_array *p_pra);
+void GDAPI godot_pool_real_array_new_with_array(godot_pool_real_array *p_pra, const godot_array *p_a);
+
+void GDAPI godot_pool_real_array_append(godot_pool_real_array *p_pra, const godot_real p_data);
+
+void GDAPI godot_pool_real_array_append_array(godot_pool_real_array *p_pra, const godot_pool_real_array *p_array);
+
+int GDAPI godot_pool_real_array_insert(godot_pool_real_array *p_pra, const godot_int p_idx, const godot_real p_data);
+
+void GDAPI godot_pool_real_array_invert(godot_pool_real_array *p_pra);
+
+void GDAPI godot_pool_real_array_push_back(godot_pool_real_array *p_pra, const godot_real p_data);
+
+void GDAPI godot_pool_real_array_remove(godot_pool_real_array *p_pra, const godot_int p_idx);
+
+void GDAPI godot_pool_real_array_resize(godot_pool_real_array *p_pra, const godot_int p_size);
+
+void GDAPI godot_pool_real_array_set(godot_pool_real_array *p_pra, const godot_int p_idx, const godot_real p_data);
+godot_real GDAPI godot_pool_real_array_get(godot_pool_real_array *p_pra, const godot_int p_idx);
+
+godot_int GDAPI godot_pool_real_array_size(godot_pool_real_array *p_pra);
+
+void GDAPI godot_pool_real_array_destroy(godot_pool_real_array *p_pra);
+
+// string
+
+void GDAPI godot_pool_string_array_new(godot_pool_string_array *p_psa);
+void GDAPI godot_pool_string_array_new_with_array(godot_pool_string_array *p_psa, const godot_array *p_a);
+
+void GDAPI godot_pool_string_array_append(godot_pool_string_array *p_psa, const godot_string *p_data);
+
+void GDAPI godot_pool_string_array_append_array(godot_pool_string_array *p_psa, const godot_pool_string_array *p_array);
+
+int GDAPI godot_pool_string_array_insert(godot_pool_string_array *p_psa, const godot_int p_idx, const godot_string *p_data);
+
+void GDAPI godot_pool_string_array_invert(godot_pool_string_array *p_psa);
+
+void GDAPI godot_pool_string_array_push_back(godot_pool_string_array *p_psa, const godot_string *p_data);
+
+void GDAPI godot_pool_string_array_remove(godot_pool_string_array *p_psa, const godot_int p_idx);
+
+void GDAPI godot_pool_string_array_resize(godot_pool_string_array *p_psa, const godot_int p_size);
+
+void GDAPI godot_pool_string_array_set(godot_pool_string_array *p_psa, const godot_int p_idx, const godot_string *p_data);
+godot_string GDAPI godot_pool_string_array_get(godot_pool_string_array *p_psa, const godot_int p_idx);
+
+godot_int GDAPI godot_pool_string_array_size(godot_pool_string_array *p_psa);
+
+void GDAPI godot_pool_string_array_destroy(godot_pool_string_array *p_psa);
+
+// vector2
+
+void GDAPI godot_pool_vector2_array_new(godot_pool_vector2_array *p_pv2a);
+void GDAPI godot_pool_vector2_array_new_with_array(godot_pool_vector2_array *p_pv2a, const godot_array *p_a);
+
+void GDAPI godot_pool_vector2_array_append(godot_pool_vector2_array *p_pv2a, const godot_vector2 *p_data);
+
+void GDAPI godot_pool_vector2_array_append_array(godot_pool_vector2_array *p_pv2a, const godot_pool_vector2_array *p_array);
+
+int GDAPI godot_pool_vector2_array_insert(godot_pool_vector2_array *p_pv2a, const godot_int p_idx, const godot_vector2 *p_data);
+
+void GDAPI godot_pool_vector2_array_invert(godot_pool_vector2_array *p_pv2a);
+
+void GDAPI godot_pool_vector2_array_push_back(godot_pool_vector2_array *p_pv2a, const godot_vector2 *p_data);
+
+void GDAPI godot_pool_vector2_array_remove(godot_pool_vector2_array *p_pv2a, const godot_int p_idx);
+
+void GDAPI godot_pool_vector2_array_resize(godot_pool_vector2_array *p_pv2a, const godot_int p_size);
+
+void GDAPI godot_pool_vector2_array_set(godot_pool_vector2_array *p_pv2a, const godot_int p_idx, const godot_vector2 *p_data);
+godot_vector2 GDAPI godot_pool_vector2_array_get(godot_pool_vector2_array *p_pv2a, const godot_int p_idx);
+
+godot_int GDAPI godot_pool_vector2_array_size(godot_pool_vector2_array *p_pv2a);
+
+void GDAPI godot_pool_vector2_array_destroy(godot_pool_vector2_array *p_pv2a);
+
+// vector3
+
+void GDAPI godot_pool_vector3_array_new(godot_pool_vector3_array *p_pv3a);
+void GDAPI godot_pool_vector3_array_new_with_array(godot_pool_vector3_array *p_pv3a, const godot_array *p_a);
+
+void GDAPI godot_pool_vector3_array_append(godot_pool_vector3_array *p_pv3a, const godot_vector3 *p_data);
+
+void GDAPI godot_pool_vector3_array_append_array(godot_pool_vector3_array *p_pv3a, const godot_pool_vector3_array *p_array);
+
+int GDAPI godot_pool_vector3_array_insert(godot_pool_vector3_array *p_pv3a, const godot_int p_idx, const godot_vector3 *p_data);
+
+void GDAPI godot_pool_vector3_array_invert(godot_pool_vector3_array *p_pv3a);
+
+void GDAPI godot_pool_vector3_array_push_back(godot_pool_vector3_array *p_pv3a, const godot_vector3 *p_data);
+
+void GDAPI godot_pool_vector3_array_remove(godot_pool_vector3_array *p_pv3a, const godot_int p_idx);
+
+void GDAPI godot_pool_vector3_array_resize(godot_pool_vector3_array *p_pv3a, const godot_int p_size);
+
+void GDAPI godot_pool_vector3_array_set(godot_pool_vector3_array *p_pv3a, const godot_int p_idx, const godot_vector3 *p_data);
+godot_vector3 GDAPI godot_pool_vector3_array_get(godot_pool_vector3_array *p_pv3a, const godot_int p_idx);
+
+godot_int GDAPI godot_pool_vector3_array_size(godot_pool_vector3_array *p_pv3a);
+
+void GDAPI godot_pool_vector3_array_destroy(godot_pool_vector3_array *p_pv3a);
+
+// color
+
+void GDAPI godot_pool_color_array_new(godot_pool_color_array *p_pca);
+void GDAPI godot_pool_color_array_new_with_array(godot_pool_color_array *p_pca, const godot_array *p_a);
+
+void GDAPI godot_pool_color_array_append(godot_pool_color_array *p_pca, const godot_color *p_data);
+
+void GDAPI godot_pool_color_array_append_array(godot_pool_color_array *p_pca, const godot_pool_color_array *p_array);
+
+int GDAPI godot_pool_color_array_insert(godot_pool_color_array *p_pca, const godot_int p_idx, const godot_color *p_data);
+
+void GDAPI godot_pool_color_array_invert(godot_pool_color_array *p_pca);
+
+void GDAPI godot_pool_color_array_push_back(godot_pool_color_array *p_pca, const godot_color *p_data);
+
+void GDAPI godot_pool_color_array_remove(godot_pool_color_array *p_pca, const godot_int p_idx);
+
+void GDAPI godot_pool_color_array_resize(godot_pool_color_array *p_pca, const godot_int p_size);
+
+void GDAPI godot_pool_color_array_set(godot_pool_color_array *p_pca, const godot_int p_idx, const godot_color *p_data);
+godot_color GDAPI godot_pool_color_array_get(godot_pool_color_array *p_pca, const godot_int p_idx);
+
+godot_int GDAPI godot_pool_color_array_size(godot_pool_color_array *p_pca);
+
+void GDAPI godot_pool_color_array_destroy(godot_pool_color_array *p_pca);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_DLSCRIPT_POOL_ARRAYS_H
diff --git a/modules/dlscript/godot/godot_quat.cpp b/modules/dlscript/godot/godot_quat.cpp
new file mode 100644
index 0000000000..9bd2eb0639
--- /dev/null
+++ b/modules/dlscript/godot/godot_quat.cpp
@@ -0,0 +1,77 @@
+#include "godot_quat.h"
+
+#include "math/quat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _quat_api_anchor() {
+}
+
+void GDAPI godot_quat_new(godot_quat *p_quat) {
+ Quat *quat = (Quat *)p_quat;
+ *quat = Quat();
+}
+
+void GDAPI godot_quat_new_with_elements(godot_quat *p_quat, const godot_real x, const godot_real y, const godot_real z, const godot_real w) {
+ Quat *quat = (Quat *)p_quat;
+ *quat = Quat(x, y, z, w);
+}
+
+void GDAPI godot_quat_new_with_rotation(godot_quat *p_quat, const godot_vector3 *p_axis, const godot_real p_angle) {
+ Quat *quat = (Quat *)p_quat;
+ const Vector3 *axis = (const Vector3 *)p_axis;
+ *quat = Quat(*axis, p_angle);
+}
+
+void GDAPI godot_quat_new_with_shortest_arc(godot_quat *p_quat, const godot_vector3 *p_v0, const godot_vector3 *p_v1) {
+ Quat *quat = (Quat *)p_quat;
+ const Vector3 *v0 = (const Vector3 *)p_v0;
+ const Vector3 *v1 = (const Vector3 *)p_v1;
+ *quat = Quat(*v0, *v1);
+}
+
+godot_vector3 GDAPI godot_quat_get_euler(const godot_quat *p_quat) {
+ Quat *quat = (Quat *)p_quat;
+ Vector3 euler = quat->get_euler();
+ return *(godot_vector3 *)&euler;
+}
+
+void GDAPI godot_quat_set_euler(godot_quat *p_quat, const godot_vector3 *p_euler) {
+ Quat *quat = (Quat *)p_quat;
+ const Vector3 *euler = (const Vector3 *)p_euler;
+ quat->set_euler(*euler);
+}
+
+godot_real GDAPI *godot_quat_index(godot_quat *p_quat, const godot_int p_idx) {
+ Quat *quat = (Quat *)p_quat;
+ switch (p_idx) {
+ case 0:
+ return &quat->x;
+ case 1:
+ return &quat->y;
+ case 2:
+ return &quat->z;
+ default:
+ return &quat->y;
+ }
+}
+
+godot_real GDAPI godot_quat_const_index(const godot_quat *p_quat, const godot_int p_idx) {
+ const Quat *quat = (const Quat *)p_quat;
+ switch (p_idx) {
+ case 0:
+ return quat->x;
+ case 1:
+ return quat->y;
+ case 2:
+ return quat->z;
+ default:
+ return quat->y;
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_quat.h b/modules/dlscript/godot/godot_quat.h
new file mode 100644
index 0000000000..4e3253c4e5
--- /dev/null
+++ b/modules/dlscript/godot/godot_quat.h
@@ -0,0 +1,33 @@
+#ifndef GODOT_DLSCRIPT_QUAT_H
+#define GODOT_DLSCRIPT_QUAT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_QUAT_TYPE_DEFINED
+typedef struct godot_quat {
+ uint8_t _dont_touch_that[16];
+} godot_quat;
+#endif
+
+#include "../godot.h"
+
+void GDAPI godot_quat_new(godot_quat *p_quat);
+void GDAPI godot_quat_new_with_elements(godot_quat *p_quat, const godot_real x, const godot_real y, const godot_real z, const godot_real w);
+void GDAPI godot_quat_new_with_rotation(godot_quat *p_quat, const godot_vector3 *p_axis, const godot_real p_angle);
+void GDAPI godot_quat_new_with_shortest_arc(godot_quat *p_quat, const godot_vector3 *p_v0, const godot_vector3 *p_v1);
+
+godot_vector3 GDAPI godot_quat_get_euler(const godot_quat *p_quat);
+void GDAPI godot_quat_set_euler(godot_quat *p_quat, const godot_vector3 *p_euler);
+
+godot_real GDAPI *godot_quat_index(godot_quat *p_quat, const godot_int p_idx);
+godot_real GDAPI godot_quat_const_index(const godot_quat *p_quat, const godot_int p_idx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_DLSCRIPT_QUAT_H
diff --git a/modules/dlscript/godot/godot_rect2.cpp b/modules/dlscript/godot/godot_rect2.cpp
new file mode 100644
index 0000000000..8e60811114
--- /dev/null
+++ b/modules/dlscript/godot/godot_rect2.cpp
@@ -0,0 +1,48 @@
+#include "godot_rect2.h"
+
+#include "math/math_2d.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _rect2_api_anchor() {
+}
+
+void GDAPI godot_rect2_new(godot_rect2 *p_rect) {
+ Rect2 *rect = (Rect2 *)p_rect;
+ *rect = Rect2();
+}
+
+void GDAPI godot_rect2_new_with_pos_and_size(godot_rect2 *p_rect, const godot_vector2 *p_pos, const godot_vector2 *p_size) {
+ Rect2 *rect = (Rect2 *)p_rect;
+ const Vector2 *pos = (const Vector2 *)p_pos;
+ const Vector2 *size = (const Vector2 *)p_size;
+ *rect = Rect2(*pos, *size);
+}
+
+godot_vector2 GDAPI *godot_rect2_get_pos(godot_rect2 *p_rect) {
+ Rect2 *rect = (Rect2 *)p_rect;
+ return (godot_vector2 *)&rect->pos;
+}
+
+void GDAPI godot_rect2_set_pos(godot_rect2 *p_rect, const godot_vector2 *p_pos) {
+ Rect2 *rect = (Rect2 *)p_rect;
+ const Vector2 *pos = (const Vector2 *)p_pos;
+ rect->pos = *pos;
+}
+
+godot_vector2 GDAPI *godot_rect2_get_size(godot_rect2 *p_rect) {
+ Rect2 *rect = (Rect2 *)p_rect;
+ return (godot_vector2 *)&rect->size;
+}
+
+void GDAPI godot_rect2_set_size(godot_rect2 *p_rect, const godot_vector2 *p_size) {
+ Rect2 *rect = (Rect2 *)p_rect;
+ const Vector2 *size = (const Vector2 *)p_size;
+ rect->size = *size;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_rect2.h b/modules/dlscript/godot/godot_rect2.h
new file mode 100644
index 0000000000..a3b19bdb7e
--- /dev/null
+++ b/modules/dlscript/godot/godot_rect2.h
@@ -0,0 +1,31 @@
+#ifndef GODOT_DLSCRIPT_RECT2_H
+#define GODOT_DLSCRIPT_RECT2_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_RECT2_TYPE_DEFINED
+typedef struct godot_rect2 {
+ uint8_t _dont_touch_that[16];
+} godot_rect2;
+#endif
+
+#include "../godot.h"
+
+void GDAPI godot_rect2_new(godot_rect2 *p_rect);
+void GDAPI godot_rect2_new_with_pos_and_size(godot_rect2 *p_rect, const godot_vector2 *p_pos, const godot_vector2 *p_size);
+
+godot_vector2 GDAPI *godot_rect2_get_pos(godot_rect2 *p_rect);
+void GDAPI godot_rect2_set_pos(godot_rect2 *p_rect, const godot_vector2 *p_pos);
+
+godot_vector2 GDAPI *godot_rect2_get_size(godot_rect2 *p_rect);
+void GDAPI godot_rect2_set_size(godot_rect2 *p_rect, const godot_vector2 *p_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_DLSCRIPT_RECT3_H
diff --git a/modules/dlscript/godot/godot_rect3.cpp b/modules/dlscript/godot/godot_rect3.cpp
new file mode 100644
index 0000000000..3c442a278b
--- /dev/null
+++ b/modules/dlscript/godot/godot_rect3.cpp
@@ -0,0 +1,48 @@
+#include "godot_rect3.h"
+
+#include "math/rect3.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _rect3_api_anchor() {
+}
+
+void GDAPI godot_rect3_new(godot_rect3 *p_rect) {
+ Rect3 *rect = (Rect3 *)p_rect;
+ *rect = Rect3();
+}
+
+void GDAPI godot_rect3_new_with_pos_and_size(godot_rect3 *p_rect, const godot_vector3 *p_pos, const godot_vector3 *p_size) {
+ Rect3 *rect = (Rect3 *)p_rect;
+ const Vector3 *pos = (const Vector3 *)p_pos;
+ const Vector3 *size = (const Vector3 *)p_size;
+ *rect = Rect3(*pos, *size);
+}
+
+godot_vector3 GDAPI *godot_rect3_get_pos(godot_rect3 *p_rect) {
+ Rect3 *rect = (Rect3 *)p_rect;
+ return (godot_vector3 *)&rect->pos;
+}
+
+void GDAPI godot_rect3_set_pos(godot_rect3 *p_rect, const godot_vector3 *p_pos) {
+ Rect3 *rect = (Rect3 *)p_rect;
+ const Vector3 *pos = (const Vector3 *)p_pos;
+ rect->pos = *pos;
+}
+
+godot_vector3 GDAPI *godot_rect3_get_size(godot_rect3 *p_rect) {
+ Rect3 *rect = (Rect3 *)p_rect;
+ return (godot_vector3 *)&rect->size;
+}
+
+void GDAPI godot_rect3_set_size(godot_rect3 *p_rect, const godot_vector3 *p_size) {
+ Rect3 *rect = (Rect3 *)p_rect;
+ const Vector3 *size = (const Vector3 *)p_size;
+ rect->size = *size;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_rect3.h b/modules/dlscript/godot/godot_rect3.h
new file mode 100644
index 0000000000..b9279616d1
--- /dev/null
+++ b/modules/dlscript/godot/godot_rect3.h
@@ -0,0 +1,31 @@
+#ifndef GODOT_DLSCRIPT_RECT3_H
+#define GODOT_DLSCRIPT_RECT3_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_RECT3_TYPE_DEFINED
+typedef struct godot_rect3 {
+ uint8_t _dont_touch_that[24];
+} godot_rect3;
+#endif
+
+#include "../godot.h"
+
+void GDAPI godot_rect3_new(godot_rect3 *p_rect);
+void GDAPI godot_rect3_new_with_pos_and_size(godot_rect3 *p_rect, const godot_vector3 *p_pos, const godot_vector3 *p_size);
+
+godot_vector3 GDAPI *godot_rect3_get_pos(godot_rect3 *p_rect);
+void GDAPI godot_rect3_set_pos(godot_rect3 *p_rect, const godot_vector3 *p_pos);
+
+godot_vector3 GDAPI *godot_rect3_get_size(godot_rect3 *p_rect);
+void GDAPI godot_rect3_set_size(godot_rect3 *p_rect, const godot_vector3 *p_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_DLSCRIPT_RECT3_H
diff --git a/modules/dlscript/godot/godot_rid.cpp b/modules/dlscript/godot/godot_rid.cpp
new file mode 100644
index 0000000000..a36a2e64a3
--- /dev/null
+++ b/modules/dlscript/godot/godot_rid.cpp
@@ -0,0 +1,36 @@
+#include "godot_rid.h"
+
+#include "object.h"
+#include "resource.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _rid_api_anchor() {
+}
+
+void GDAPI godot_rid_new(godot_rid *p_rid, godot_object *p_from) {
+
+ Resource *res_from = ((Object *)p_from)->cast_to<Resource>();
+
+ RID *rid = (RID *)p_rid;
+ memnew_placement(rid, RID);
+
+ if (res_from) {
+ *rid = RID(res_from->get_rid());
+ }
+}
+
+uint32_t GDAPI godot_rid_get_rid(const godot_rid *p_rid) {
+ RID *rid = (RID *)p_rid;
+ return rid->get_id();
+}
+
+void GDAPI godot_rid_destroy(godot_rid *p_rid) {
+ ((RID *)p_rid)->~RID();
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_rid.h b/modules/dlscript/godot/godot_rid.h
new file mode 100644
index 0000000000..f20c0d4dae
--- /dev/null
+++ b/modules/dlscript/godot/godot_rid.h
@@ -0,0 +1,28 @@
+#ifndef GODOT_DLSCRIPT_RID_H
+#define GODOT_DLSCRIPT_RID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_RID_TYPE_DEFINED
+typedef struct godot_rid {
+ uint8_t _dont_touch_that[8];
+} godot_rid;
+#endif
+
+#include "../godot.h"
+
+void GDAPI godot_rid_new(godot_rid *p_rid, godot_object *p_from);
+
+uint32_t GDAPI godot_rid_get_rid(const godot_rid *p_rid);
+
+void GDAPI godot_rid_destroy(godot_rid *p_rid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_DLSCRIPT_RID_H
diff --git a/modules/dlscript/godot/godot_string.cpp b/modules/dlscript/godot/godot_string.cpp
new file mode 100644
index 0000000000..97d0985a50
--- /dev/null
+++ b/modules/dlscript/godot/godot_string.cpp
@@ -0,0 +1,83 @@
+#include "godot_string.h"
+
+#include "string_db.h"
+#include "ustring.h"
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _string_api_anchor() {
+}
+
+void GDAPI godot_string_new(godot_string *p_str) {
+ String *p = (String *)p_str;
+ memnew_placement(p, String);
+ // *p = String(); // useless here
+}
+
+void GDAPI godot_string_new_data(godot_string *p_str, const char *p_contents, const int p_size) {
+ String *p = (String *)p_str;
+ memnew_placement(p, String);
+ *p = String::utf8(p_contents, p_size);
+}
+
+void GDAPI godot_string_get_data(const godot_string *p_str, wchar_t *p_dest, int *p_size) {
+ String *p = (String *)p_str;
+ if (p_size != NULL) {
+ *p_size = p->length();
+ }
+ if (p_dest != NULL) {
+ memcpy(p_dest, p->ptr(), *p_size * sizeof(CharType));
+ }
+}
+
+void GDAPI godot_string_copy_string(const godot_string *p_dest, const godot_string *p_src) {
+ String *dest = (String *)p_dest;
+ String *src = (String *)p_src;
+
+ *dest = *src;
+}
+
+wchar_t GDAPI *godot_string_operator_index(godot_string *p_str, const godot_int p_idx) {
+ String *s = (String *)p_str;
+ return &(s->operator[](p_idx));
+}
+
+const wchar_t GDAPI *godot_string_c_str(const godot_string *p_str) {
+ const String *s = (const String *)p_str;
+ return s->c_str();
+}
+
+godot_bool GDAPI godot_string_operator_equal(const godot_string *p_a, const godot_string *p_b) {
+ String *a = (String *)p_a;
+ String *b = (String *)p_b;
+ return *a == *b;
+}
+
+godot_bool GDAPI godot_string_operator_less(const godot_string *p_a, const godot_string *p_b) {
+ String *a = (String *)p_a;
+ String *b = (String *)p_b;
+ return *a < *b;
+}
+
+void GDAPI godot_string_operator_plus(godot_string *p_dest, const godot_string *p_a, const godot_string *p_b) {
+ String *dest = (String *)p_dest;
+ const String *a = (String *)p_a;
+ const String *b = (String *)p_b;
+
+ String tmp = *a + *b;
+ godot_string_new(p_dest);
+ *dest = tmp;
+}
+
+void GDAPI godot_string_destroy(godot_string *p_str) {
+ String *p = (String *)p_str;
+ p->~String();
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_string.h b/modules/dlscript/godot/godot_string.h
new file mode 100644
index 0000000000..73b366d9cd
--- /dev/null
+++ b/modules/dlscript/godot/godot_string.h
@@ -0,0 +1,42 @@
+#ifndef GODOT_DLSCRIPT_STRING_H
+#define GODOT_DLSCRIPT_STRING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED
+typedef struct godot_string {
+ uint8_t _dont_touch_that[8];
+} godot_string;
+#endif
+
+#include "../godot.h"
+
+void GDAPI godot_string_new(godot_string *p_str);
+void GDAPI godot_string_new_data(godot_string *p_str, const char *p_contents, const int p_size);
+
+void GDAPI godot_string_get_data(const godot_string *p_str, wchar_t *p_dest, int *p_size);
+
+void GDAPI godot_string_copy_string(const godot_string *p_dest, const godot_string *p_src);
+
+wchar_t GDAPI *godot_string_operator_index(godot_string *p_str, const godot_int p_idx);
+const wchar_t GDAPI *godot_string_c_str(const godot_string *p_str);
+
+godot_bool GDAPI godot_string_operator_equal(const godot_string *p_a, const godot_string *p_b);
+godot_bool GDAPI godot_string_operator_less(const godot_string *p_a, const godot_string *p_b);
+void GDAPI godot_string_operator_plus(godot_string *p_dest, const godot_string *p_a, const godot_string *p_b);
+
+// @Incomplete
+// hmm, I guess exposing the whole API doesn't make much sense
+// since the language used in the library has its own string funcs
+
+void GDAPI godot_string_destroy(godot_string *p_str);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_DLSCRIPT_STRING_H
diff --git a/modules/dlscript/godot/godot_transform.cpp b/modules/dlscript/godot/godot_transform.cpp
new file mode 100644
index 0000000000..c8da519f6b
--- /dev/null
+++ b/modules/dlscript/godot/godot_transform.cpp
@@ -0,0 +1,42 @@
+#include "godot_transform.h"
+
+#include "math/transform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _transform_api_anchor() {
+}
+
+void GDAPI godot_transform_new(godot_transform *p_trans) {
+ Transform *trans = (Transform *)p_trans;
+ *trans = Transform();
+}
+
+void GDAPI godot_transform_new_with_basis(godot_transform *p_trans, const godot_basis *p_basis) {
+ Transform *trans = (Transform *)p_trans;
+ const Basis *basis = (const Basis *)p_basis;
+ *trans = Transform(*basis);
+}
+
+void GDAPI godot_transform_new_with_basis_origin(godot_transform *p_trans, const godot_basis *p_basis, const godot_vector3 *p_origin) {
+ Transform *trans = (Transform *)p_trans;
+ const Basis *basis = (const Basis *)p_basis;
+ const Vector3 *origin = (const Vector3 *)p_origin;
+ *trans = Transform(*basis, *origin);
+}
+
+godot_basis GDAPI *godot_transform_get_basis(godot_transform *p_trans) {
+ Transform *trans = (Transform *)p_trans;
+ return (godot_basis *)&trans->basis;
+}
+
+godot_vector3 GDAPI *godot_transform_get_origin(godot_transform *p_trans) {
+ Transform *trans = (Transform *)p_trans;
+ return (godot_vector3 *)&trans->origin;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_transform.h b/modules/dlscript/godot/godot_transform.h
new file mode 100644
index 0000000000..54af78d5b9
--- /dev/null
+++ b/modules/dlscript/godot/godot_transform.h
@@ -0,0 +1,29 @@
+#ifndef GODOT_DLSCRIPT_TRANSFORM_H
+#define GODOT_DLSCRIPT_TRANSFORM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_TRANSFORM_TYPE_DEFINED
+typedef struct godot_transform {
+ uint8_t _dont_touch_that[48];
+} godot_transform;
+#endif
+
+#include "../godot.h"
+
+void GDAPI godot_transform_new(godot_transform *p_trans);
+void GDAPI godot_transform_new_with_basis(godot_transform *p_trans, const godot_basis *p_basis);
+void GDAPI godot_transform_new_with_basis_origin(godot_transform *p_trans, const godot_basis *p_basis, const godot_vector3 *p_origin);
+
+godot_basis GDAPI *godot_transform_get_basis(godot_transform *p_trans);
+godot_vector3 GDAPI *godot_transform_get_origin(godot_transform *p_trans);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_DLSCRIPT_TRANSFORM_H
diff --git a/modules/dlscript/godot/godot_transform2d.cpp b/modules/dlscript/godot/godot_transform2d.cpp
new file mode 100644
index 0000000000..39fa0e7363
--- /dev/null
+++ b/modules/dlscript/godot/godot_transform2d.cpp
@@ -0,0 +1,59 @@
+#include "godot_transform2d.h"
+
+#include "../godot.h"
+
+#include "math/math_2d.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _transform2d_api_anchor() {
+}
+
+void GDAPI godot_transform2d_new_identity(godot_transform2d *p_t) {
+ Transform2D *t = (Transform2D *)p_t;
+ *t = Transform2D();
+}
+
+void GDAPI godot_transform2d_new_elements(godot_transform2d *p_t, const godot_vector2 *p_a, const godot_vector2 *p_b, const godot_vector2 *p_c) {
+ Transform2D *t = (Transform2D *)p_t;
+ Vector2 *a = (Vector2 *)p_a;
+ Vector2 *b = (Vector2 *)p_b;
+ Vector2 *c = (Vector2 *)p_c;
+ *t = Transform2D(a->x, a->y, b->x, b->y, c->x, c->y);
+}
+
+void GDAPI godot_transform2d_new(godot_transform2d *p_t, const godot_real p_rot, const godot_vector2 *p_pos) {
+ Transform2D *t = (Transform2D *)p_t;
+ Vector2 *pos = (Vector2 *)p_pos;
+ *t = Transform2D(p_rot, *pos);
+}
+
+godot_vector2 const GDAPI *godot_transform2d_const_index(const godot_transform2d *p_t, const godot_int p_idx) {
+ const Transform2D *t = (const Transform2D *)p_t;
+ const Vector2 *e = &t->operator[](p_idx);
+ return (godot_vector2 const *)e;
+}
+
+godot_vector2 GDAPI *godot_transform2d_index(godot_transform2d *p_t, const godot_int p_idx) {
+ Transform2D *t = (Transform2D *)p_t;
+ Vector2 *e = &t->operator[](p_idx);
+ return (godot_vector2 *)e;
+}
+
+godot_vector2 GDAPI godot_transform2d_get_axis(const godot_transform2d *p_t, const godot_int p_axis) {
+ return *godot_transform2d_const_index(p_t, p_axis);
+}
+
+void GDAPI godot_transform2d_set_axis(godot_transform2d *p_t, const godot_int p_axis, const godot_vector2 *p_vec) {
+ godot_vector2 *origin_v = godot_transform2d_index(p_t, p_axis);
+ *origin_v = *p_vec;
+}
+
+// @Incomplete
+// See header file
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_transform2d.h b/modules/dlscript/godot/godot_transform2d.h
new file mode 100644
index 0000000000..7403954527
--- /dev/null
+++ b/modules/dlscript/godot/godot_transform2d.h
@@ -0,0 +1,48 @@
+#ifndef GODOT_TRANSFORM2D_H
+#define GODOT_TRANSFORM2D_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_TRANSFORM2D_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_TRANSFORM2D_TYPE_DEFINED
+typedef struct godot_transform2d {
+ uint8_t _dont_touch_that[24];
+} godot_transform2d;
+#endif
+
+#include "../godot.h"
+
+#include "godot_vector2.h"
+
+void GDAPI godot_transform2d_new_identity(godot_transform2d *p_t);
+void GDAPI godot_transform2d_new_elements(godot_transform2d *p_t, const godot_vector2 *p_a, const godot_vector2 *p_b, const godot_vector2 *p_c);
+void GDAPI godot_transform2d_new(godot_transform2d *p_t, const godot_real p_rot, const godot_vector2 *p_pos);
+
+/*
+godot_real GDAPI godot_transform2d_tdotx(const godot_transform2d *p_t, const godot_vector2 *p_v);
+godot_real GDAPI godot_transform2d_tdoty(const godot_transform2d *p_t, const godot_vector2 *p_v);
+*/
+
+godot_vector2 const GDAPI *godot_transform2d_const_index(const godot_transform2d *p_t, const godot_int p_idx);
+godot_vector2 GDAPI *godot_transform2d_index(godot_transform2d *p_t, const godot_int p_idx);
+
+godot_vector2 GDAPI godot_transform2d_get_axis(const godot_transform2d *p_t, const godot_int p_axis);
+void GDAPI godot_transform2d_set_axis(godot_transform2d *p_t, const godot_int p_axis, const godot_vector2 *p_vec);
+
+/*
+void GDAPI godot_transform2d_invert(godot_transform2d *p_t);
+godot_transform2d GDAPI godot_transform2d_inverse(const godot_transform2d *p_t);
+*/
+
+// @Incomplete
+// I feel like it should be enough to expose get and set, the whole logic can be done in the bindings.
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_TRANSFORM2D_H
diff --git a/modules/dlscript/godot/godot_variant.cpp b/modules/dlscript/godot/godot_variant.cpp
new file mode 100644
index 0000000000..3681f89753
--- /dev/null
+++ b/modules/dlscript/godot/godot_variant.cpp
@@ -0,0 +1,476 @@
+#include "godot_variant.h"
+
+#include "../godot.h"
+
+#include "variant.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _variant_api_anchor() {
+}
+
+#define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr)
+
+godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ return (godot_variant_type)v->get_type();
+}
+
+void GDAPI godot_variant_copy(godot_variant *p_dest, const godot_variant *p_src) {
+ Variant *dest = (Variant *)p_dest;
+ Variant *src = (Variant *)p_src;
+ *dest = *src;
+}
+
+void GDAPI godot_variant_new_nil(godot_variant *p_v) {
+ Variant *v = (Variant *)p_v;
+ memnew_placement(v, Variant);
+}
+
+void GDAPI godot_variant_new_bool(godot_variant *p_v, const godot_bool p_b) {
+ Variant *v = (Variant *)p_v;
+ memnew_placement_custom(v, Variant, Variant(p_b));
+}
+
+void GDAPI godot_variant_new_uint(godot_variant *p_v, const uint64_t p_i) {
+ Variant *v = (Variant *)p_v;
+ memnew_placement_custom(v, Variant, Variant(p_i));
+}
+
+void GDAPI godot_variant_new_int(godot_variant *p_v, const int64_t p_i) {
+ Variant *v = (Variant *)p_v;
+ memnew_placement_custom(v, Variant, Variant(p_i));
+}
+
+void GDAPI godot_variant_new_real(godot_variant *p_v, const double p_r) {
+ Variant *v = (Variant *)p_v;
+ memnew_placement_custom(v, Variant, Variant(p_r));
+}
+
+void GDAPI godot_variant_new_string(godot_variant *p_v, const godot_string *p_s) {
+ Variant *v = (Variant *)p_v;
+ String *s = (String *)p_s;
+ memnew_placement_custom(v, Variant, Variant(*s));
+}
+
+void GDAPI godot_variant_new_vector2(godot_variant *p_v, const godot_vector2 *p_v2) {
+ Variant *v = (Variant *)p_v;
+ Vector2 *v2 = (Vector2 *)p_v2;
+ memnew_placement_custom(v, Variant, Variant(*v2));
+}
+
+void GDAPI godot_variant_new_rect2(godot_variant *p_v, const godot_rect2 *p_rect2) {
+ Variant *v = (Variant *)p_v;
+ Rect2 *rect2 = (Rect2 *)p_rect2;
+ memnew_placement_custom(v, Variant, Variant(*rect2));
+}
+
+void GDAPI godot_variant_new_vector3(godot_variant *p_v, const godot_vector3 *p_v3) {
+ Variant *v = (Variant *)p_v;
+ Vector3 *v3 = (Vector3 *)p_v3;
+ memnew_placement_custom(v, Variant, Variant(*v3));
+}
+
+void GDAPI godot_variant_new_transform2d(godot_variant *p_v, const godot_transform2d *p_t2d) {
+ Variant *v = (Variant *)p_v;
+ Transform2D *t2d = (Transform2D *)p_t2d;
+ memnew_placement_custom(v, Variant, Variant(*t2d));
+}
+
+void GDAPI godot_variant_new_plane(godot_variant *p_v, const godot_plane *p_plane) {
+ Variant *v = (Variant *)p_v;
+ Plane *plane = (Plane *)p_plane;
+ memnew_placement_custom(v, Variant, Variant(*plane));
+}
+
+void GDAPI godot_variant_new_quat(godot_variant *p_v, const godot_quat *p_quat) {
+ Variant *v = (Variant *)p_v;
+ Quat *quat = (Quat *)p_quat;
+ memnew_placement_custom(v, Variant, Variant(*quat));
+}
+
+void GDAPI godot_variant_new_rect3(godot_variant *p_v, const godot_rect3 *p_rect3) {
+ Variant *v = (Variant *)p_v;
+ Rect3 *rect3 = (Rect3 *)p_rect3;
+ memnew_placement_custom(v, Variant, Variant(*rect3));
+}
+
+void GDAPI godot_variant_new_basis(godot_variant *p_v, const godot_basis *p_basis) {
+ Variant *v = (Variant *)p_v;
+ Basis *basis = (Basis *)p_basis;
+ memnew_placement_custom(v, Variant, Variant(*basis));
+}
+
+void GDAPI godot_variant_new_transform(godot_variant *p_v, const godot_transform *p_trans) {
+ Variant *v = (Variant *)p_v;
+ Transform *trans = (Transform *)p_trans;
+ memnew_placement_custom(v, Variant, Variant(*trans));
+}
+
+void GDAPI godot_variant_new_color(godot_variant *p_v, const godot_color *p_color) {
+ Variant *v = (Variant *)p_v;
+ Color *color = (Color *)p_color;
+ memnew_placement_custom(v, Variant, Variant(*color));
+}
+
+void GDAPI godot_variant_new_image(godot_variant *p_v, const godot_image *p_img) {
+ Variant *v = (Variant *)p_v;
+ Image *img = (Image *)p_img;
+ memnew_placement_custom(v, Variant, Variant(*img));
+}
+
+void GDAPI godot_variant_new_node_path(godot_variant *p_v, const godot_node_path *p_np) {
+ Variant *v = (Variant *)p_v;
+ NodePath *np = (NodePath *)p_np;
+ memnew_placement_custom(v, Variant, Variant(*np));
+}
+
+void GDAPI godot_variant_new_rid(godot_variant *p_v, const godot_rid *p_rid) {
+ Variant *v = (Variant *)p_v;
+ RID *rid = (RID *)p_rid;
+ memnew_placement_custom(v, Variant, Variant(*rid));
+}
+
+void GDAPI godot_variant_new_object(godot_variant *p_v, const godot_object *p_obj) {
+ Variant *v = (Variant *)p_v;
+ Object *obj = (Object *)p_obj;
+ memnew_placement_custom(v, Variant, Variant(obj));
+}
+
+void GDAPI godot_variant_new_input_event(godot_variant *p_v, const godot_input_event *p_event) {
+ Variant *v = (Variant *)p_v;
+ InputEvent *event = (InputEvent *)p_event;
+ memnew_placement_custom(v, Variant, Variant(*event));
+}
+
+void GDAPI godot_variant_new_dictionary(godot_variant *p_v, const godot_dictionary *p_dict) {
+ Variant *v = (Variant *)p_v;
+ Dictionary *dict = (Dictionary *)p_dict;
+ memnew_placement_custom(v, Variant, Variant(*dict));
+}
+
+void GDAPI godot_variant_new_array(godot_variant *p_v, const godot_array *p_arr) {
+ Variant *v = (Variant *)p_v;
+ Array *arr = (Array *)p_arr;
+ memnew_placement_custom(v, Variant, Variant(*arr));
+}
+
+void GDAPI godot_variant_new_pool_byte_array(godot_variant *p_v, const godot_pool_byte_array *p_pba) {
+ Variant *v = (Variant *)p_v;
+ PoolByteArray *pba = (PoolByteArray *)p_pba;
+ memnew_placement_custom(v, Variant, Variant(*pba));
+}
+
+void GDAPI godot_variant_new_pool_int_array(godot_variant *p_v, const godot_pool_int_array *p_pia) {
+ Variant *v = (Variant *)p_v;
+ PoolIntArray *pia = (PoolIntArray *)p_pia;
+ memnew_placement_custom(v, Variant, Variant(*pia));
+}
+
+void GDAPI godot_variant_new_pool_real_array(godot_variant *p_v, const godot_pool_real_array *p_pra) {
+ Variant *v = (Variant *)p_v;
+ PoolRealArray *pra = (PoolRealArray *)p_pra;
+ memnew_placement_custom(v, Variant, Variant(*pra));
+}
+
+void GDAPI godot_variant_new_pool_string_array(godot_variant *p_v, const godot_pool_string_array *p_psa) {
+ Variant *v = (Variant *)p_v;
+ PoolStringArray *psa = (PoolStringArray *)p_psa;
+ memnew_placement_custom(v, Variant, Variant(*psa));
+}
+
+void GDAPI godot_variant_new_pool_vector2_array(godot_variant *p_v, const godot_pool_vector2_array *p_pv2a) {
+ Variant *v = (Variant *)p_v;
+ PoolVector2Array *pv2a = (PoolVector2Array *)p_pv2a;
+ memnew_placement_custom(v, Variant, Variant(*pv2a));
+}
+
+void GDAPI godot_variant_new_pool_vector3_array(godot_variant *p_v, const godot_pool_vector3_array *p_pv3a) {
+ Variant *v = (Variant *)p_v;
+ PoolVector3Array *pv3a = (PoolVector3Array *)p_pv3a;
+ memnew_placement_custom(v, Variant, Variant(*pv3a));
+}
+
+void GDAPI godot_variant_new_pool_color_array(godot_variant *p_v, const godot_pool_color_array *p_pca) {
+ Variant *v = (Variant *)p_v;
+ PoolColorArray *pca = (PoolColorArray *)p_pca;
+ memnew_placement_custom(v, Variant, Variant(*pca));
+}
+
+godot_bool GDAPI godot_variant_as_bool(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ return v->operator bool();
+}
+
+uint64_t GDAPI godot_variant_as_uint(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ return v->operator uint64_t();
+}
+
+int64_t GDAPI godot_variant_as_int(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ return v->operator int64_t();
+}
+
+double GDAPI godot_variant_as_real(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ return v->operator double();
+}
+
+godot_string GDAPI godot_variant_as_string(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_string s;
+ godot_string_new(&s);
+ String *str = (String *)&s;
+ *str = v->operator String();
+ return s;
+}
+
+godot_vector2 GDAPI godot_variant_as_vector2(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_vector2 v2;
+ Vector2 *vec2 = (Vector2 *)&v2;
+ *vec2 = *v;
+ return v2;
+}
+
+godot_rect2 GDAPI godot_variant_as_rect2(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_rect2 r2;
+ Rect2 *rect2 = (Rect2 *)&r2;
+ *rect2 = *v;
+ return r2;
+}
+
+godot_vector3 GDAPI godot_variant_as_vector3(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_vector3 v3;
+ Vector3 *vec3 = (Vector3 *)&v3;
+ *vec3 = *v;
+ return v3;
+}
+
+godot_transform2d GDAPI godot_variant_as_transform2d(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_transform2d t2;
+ Transform2D *t = (Transform2D *)&t2;
+ *t = *v;
+ return t2;
+}
+
+godot_plane GDAPI godot_variant_as_plane(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_plane p;
+ Plane *pl = (Plane *)&p;
+ *pl = *v;
+ return p;
+}
+
+godot_quat GDAPI godot_variant_as_quat(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_quat q;
+ Quat *qt = (Quat *)&q;
+ *qt = *v;
+ return q;
+}
+
+godot_rect3 GDAPI godot_variant_as_rect3(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_rect3 r;
+ Rect3 *r3 = (Rect3 *)&r;
+ *r3 = *v;
+ return r;
+}
+
+godot_basis GDAPI godot_variant_as_basis(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_basis b;
+ Basis *bs = (Basis *)&b;
+ *bs = *v;
+ return b;
+}
+
+godot_transform GDAPI godot_variant_as_transform(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_transform t;
+ Transform *tr = (Transform *)&t;
+ *tr = *v;
+ return t;
+}
+
+godot_color GDAPI godot_variant_as_color(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_color c;
+ Color *col = (Color *)&c;
+ *col = *v;
+ return c;
+}
+
+godot_image GDAPI godot_variant_as_image(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_image img;
+ godot_image_new(&img);
+ Image *i = (Image *)&img;
+ *i = *v;
+ return img;
+}
+
+godot_node_path GDAPI godot_variant_as_node_path(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_node_path np;
+ memnew_placement_custom((NodePath *)&np, NodePath, NodePath((String)*v));
+ return np;
+}
+
+godot_rid GDAPI godot_variant_as_rid(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_rid rid;
+ memnew_placement_custom((RID *)&rid, RID, RID(*v));
+ return rid;
+}
+
+godot_object GDAPI *godot_variant_as_object(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_object *p = NULL;
+ Object **op = (Object **)&p;
+ *op = *v;
+ return p;
+}
+
+godot_input_event GDAPI godot_variant_as_input_event(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_input_event ev;
+ InputEvent *event = (InputEvent *)&ev;
+ *event = *v;
+ return ev;
+}
+
+godot_dictionary GDAPI godot_variant_as_dictionary(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_dictionary dict;
+ godot_dictionary_new(&dict);
+ Dictionary *d = (Dictionary *)&dict;
+ *d = *v;
+ return dict;
+}
+
+godot_array GDAPI godot_variant_as_array(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_array array;
+ godot_array_new(&array);
+ Array *a = (Array *)&array;
+ *a = *v;
+ return array;
+}
+
+godot_pool_byte_array GDAPI godot_variant_as_pool_byte_array(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_pool_byte_array pba;
+ godot_pool_byte_array_new(&pba);
+ PoolByteArray *p = (PoolByteArray *)&pba;
+ *p = *v;
+ return pba;
+}
+
+godot_pool_int_array GDAPI godot_variant_as_pool_int_array(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_pool_int_array pba;
+ godot_pool_int_array_new(&pba);
+ PoolIntArray *p = (PoolIntArray *)&pba;
+ *p = *v;
+ return pba;
+}
+
+godot_pool_real_array GDAPI godot_variant_as_pool_real_array(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_pool_real_array pba;
+ godot_pool_real_array_new(&pba);
+ PoolRealArray *p = (PoolRealArray *)&pba;
+ *p = *v;
+ return pba;
+}
+
+godot_pool_string_array GDAPI godot_variant_as_pool_string_array(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_pool_string_array pba;
+ godot_pool_string_array_new(&pba);
+ PoolStringArray *p = (PoolStringArray *)&pba;
+ *p = *v;
+ return pba;
+}
+
+godot_pool_vector2_array GDAPI godot_variant_as_pool_vector2_array(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_pool_vector2_array pba;
+ godot_pool_vector2_array_new(&pba);
+ PoolVector2Array *p = (PoolVector2Array *)&pba;
+ *p = *v;
+ return pba;
+}
+
+godot_pool_vector3_array GDAPI godot_variant_as_pool_vector3_array(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_pool_vector3_array pba;
+ godot_pool_vector3_array_new(&pba);
+ PoolVector3Array *p = (PoolVector3Array *)&pba;
+ *p = *v;
+ return pba;
+}
+
+godot_pool_color_array GDAPI godot_variant_as_pool_color_array(const godot_variant *p_v) {
+ const Variant *v = (const Variant *)p_v;
+ godot_pool_color_array pba;
+ godot_pool_color_array_new(&pba);
+ PoolColorArray *p = (PoolColorArray *)&pba;
+ *p = *v;
+ return pba;
+}
+
+godot_variant GDAPI godot_variant_call(godot_variant *p_v, const godot_string *p_method, const godot_variant **p_args, const godot_int p_argcount /*, godot_variant_call_error *r_error */) {
+ Variant *v = (Variant *)p_v;
+ String *method = (String *)p_method;
+ Variant **args = (Variant **)p_args;
+ godot_variant res;
+ memnew_placement_custom((Variant *)&res, Variant, Variant(v->call(*method, args, p_argcount)));
+ return res;
+}
+
+godot_bool GDAPI godot_variant_has_method(godot_variant *p_v, const godot_string *p_method) {
+ Variant *v = (Variant *)p_v;
+ String *method = (String *)p_method;
+ return v->has_method(*method);
+}
+
+godot_bool GDAPI godot_variant_operator_equal(const godot_variant *p_a, const godot_variant *p_b) {
+ const Variant *a = (const Variant *)p_a;
+ const Variant *b = (const Variant *)p_b;
+ return a->operator==(*b);
+}
+
+godot_bool GDAPI godot_variant_operator_less(const godot_variant *p_a, const godot_variant *p_b) {
+ const Variant *a = (const Variant *)p_a;
+ const Variant *b = (const Variant *)p_b;
+ return a->operator<(*b);
+}
+
+godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_a, const godot_variant *p_b) {
+ const Variant *a = (const Variant *)p_a;
+ const Variant *b = (const Variant *)p_b;
+ return a->hash_compare(*b);
+}
+
+godot_bool GDAPI godot_variant_booleanize(const godot_variant *p_v, godot_bool *p_valid) {
+ const Variant *v = (const Variant *)p_v;
+ bool &valid = *p_valid;
+ return v->booleanize(valid);
+}
+
+void GDAPI godot_variant_destroy(godot_variant *p_v) {
+ ((Variant *)p_v)->~Variant();
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_variant.h b/modules/dlscript/godot/godot_variant.h
new file mode 100644
index 0000000000..1ff5ba4a57
--- /dev/null
+++ b/modules/dlscript/godot/godot_variant.h
@@ -0,0 +1,150 @@
+#ifndef GODOT_VARIANT_H
+#define GODOT_VARIANT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED
+typedef struct godot_variant {
+ uint8_t _dont_touch_that[24];
+} godot_variant;
+#endif
+
+struct godot_transform2d;
+typedef struct godot_transform2d godot_transform2d;
+
+#include "godot_array.h"
+#include "godot_dictionary.h"
+#include "godot_input_event.h"
+#include "godot_node_path.h"
+#include "godot_rid.h"
+#include "godot_transform2d.h"
+
+typedef enum godot_variant_type {
+ GODOT_VARIANT_TYPE_NIL,
+
+ // atomic types
+ GODOT_VARIANT_TYPE_BOOL,
+ GODOT_VARIANT_TYPE_INT,
+ GODOT_VARIANT_TYPE_REAL,
+ GODOT_VARIANT_TYPE_STRING,
+
+ // math types
+
+ GODOT_VARIANT_TYPE_VECTOR2, // 5
+ GODOT_VARIANT_TYPE_RECT2,
+ GODOT_VARIANT_TYPE_VECTOR3,
+ GODOT_VARIANT_TYPE_TRANSFORM2D,
+ GODOT_VARIANT_TYPE_PLANE,
+ GODOT_VARIANT_TYPE_QUAT, // 10
+ GODOT_VARIANT_TYPE_RECT3, //sorry naming convention fail :( not like it's used often
+ GODOT_VARIANT_TYPE_BASIS,
+ GODOT_VARIANT_TYPE_TRANSFORM,
+
+ // misc types
+ GODOT_VARIANT_TYPE_COLOR,
+ GODOT_VARIANT_TYPE_IMAGE, // 15
+ GODOT_VARIANT_TYPE_NODE_PATH,
+ GODOT_VARIANT_TYPE_RID,
+ GODOT_VARIANT_TYPE_OBJECT,
+ GODOT_VARIANT_TYPE_INPUT_EVENT,
+ GODOT_VARIANT_TYPE_DICTIONARY, // 20
+ GODOT_VARIANT_TYPE_ARRAY,
+
+ // arrays
+ GODOT_VARIANT_TYPE_POOL_BYTE_ARRAY,
+ GODOT_VARIANT_TYPE_POOL_INT_ARRAY,
+ GODOT_VARIANT_TYPE_POOL_REAL_ARRAY,
+ GODOT_VARIANT_TYPE_POOL_STRING_ARRAY, // 25
+ GODOT_VARIANT_TYPE_POOL_VECTOR2_ARRAY,
+ GODOT_VARIANT_TYPE_POOL_VECTOR3_ARRAY,
+ GODOT_VARIANT_TYPE_POOL_COLOR_ARRAY,
+} godot_variant_type;
+
+godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_v);
+
+void GDAPI godot_variant_copy(godot_variant *p_dest, const godot_variant *p_src);
+
+void GDAPI godot_variant_new_nil(godot_variant *p_v);
+
+void GDAPI godot_variant_new_bool(godot_variant *p_v, const godot_bool p_b);
+void GDAPI godot_variant_new_uint(godot_variant *p_v, const uint64_t p_i);
+void GDAPI godot_variant_new_int(godot_variant *p_v, const int64_t p_i);
+void GDAPI godot_variant_new_real(godot_variant *p_v, const double p_r);
+void GDAPI godot_variant_new_string(godot_variant *p_v, const godot_string *p_s);
+void GDAPI godot_variant_new_vector2(godot_variant *p_v, const godot_vector2 *p_v2);
+void GDAPI godot_variant_new_rect2(godot_variant *p_v, const godot_rect2 *p_rect2);
+void GDAPI godot_variant_new_vector3(godot_variant *p_v, const godot_vector3 *p_v3);
+void GDAPI godot_variant_new_transform2d(godot_variant *p_v, const godot_transform2d *p_t2d);
+void GDAPI godot_variant_new_plane(godot_variant *p_v, const godot_plane *p_plane);
+void GDAPI godot_variant_new_quat(godot_variant *p_v, const godot_quat *p_quat);
+void GDAPI godot_variant_new_rect3(godot_variant *p_v, const godot_rect3 *p_rect3);
+void GDAPI godot_variant_new_basis(godot_variant *p_v, const godot_basis *p_basis);
+void GDAPI godot_variant_new_transform(godot_variant *p_v, const godot_transform *p_trans);
+void GDAPI godot_variant_new_color(godot_variant *p_v, const godot_color *p_color);
+void GDAPI godot_variant_new_image(godot_variant *p_v, const godot_image *p_img);
+void GDAPI godot_variant_new_node_path(godot_variant *p_v, const godot_node_path *p_np);
+void GDAPI godot_variant_new_rid(godot_variant *p_v, const godot_rid *p_rid);
+void GDAPI godot_variant_new_object(godot_variant *p_v, const godot_object *p_obj);
+void GDAPI godot_variant_new_input_event(godot_variant *p_v, const godot_input_event *p_event);
+void GDAPI godot_variant_new_dictionary(godot_variant *p_v, const godot_dictionary *p_dict);
+void GDAPI godot_variant_new_array(godot_variant *p_v, const godot_array *p_arr);
+void GDAPI godot_variant_new_pool_byte_array(godot_variant *p_v, const godot_pool_byte_array *p_pba);
+void GDAPI godot_variant_new_pool_int_array(godot_variant *p_v, const godot_pool_int_array *p_pia);
+void GDAPI godot_variant_new_pool_real_array(godot_variant *p_v, const godot_pool_real_array *p_pra);
+void GDAPI godot_variant_new_pool_string_array(godot_variant *p_v, const godot_pool_string_array *p_psa);
+void GDAPI godot_variant_new_pool_vector2_array(godot_variant *p_v, const godot_pool_vector2_array *p_pv2a);
+void GDAPI godot_variant_new_pool_vector3_array(godot_variant *p_v, const godot_pool_vector3_array *p_pv3a);
+void GDAPI godot_variant_new_pool_color_array(godot_variant *p_v, const godot_pool_color_array *p_pca);
+
+godot_bool GDAPI godot_variant_as_bool(const godot_variant *p_v);
+uint64_t GDAPI godot_variant_as_uint(const godot_variant *p_v);
+int64_t GDAPI godot_variant_as_int(const godot_variant *p_v);
+double GDAPI godot_variant_as_real(const godot_variant *p_v);
+godot_string GDAPI godot_variant_as_string(const godot_variant *p_v);
+godot_vector2 GDAPI godot_variant_as_vector2(const godot_variant *p_v);
+godot_rect2 GDAPI godot_variant_as_rect2(const godot_variant *p_v);
+godot_vector3 GDAPI godot_variant_as_vector3(const godot_variant *p_v);
+godot_transform2d GDAPI godot_variant_as_transform2d(const godot_variant *p_v);
+godot_plane GDAPI godot_variant_as_plane(const godot_variant *p_v);
+godot_quat GDAPI godot_variant_as_quat(const godot_variant *p_v);
+godot_rect3 GDAPI godot_variant_as_rect3(const godot_variant *p_v);
+godot_basis GDAPI godot_variant_as_basis(const godot_variant *p_v);
+godot_transform GDAPI godot_variant_as_transform(const godot_variant *p_v);
+godot_color GDAPI godot_variant_as_color(const godot_variant *p_v);
+godot_image GDAPI godot_variant_as_image(const godot_variant *p_v);
+godot_node_path GDAPI godot_variant_as_node_path(const godot_variant *p_v);
+godot_rid GDAPI godot_variant_as_rid(const godot_variant *p_v);
+godot_object GDAPI *godot_variant_as_object(const godot_variant *p_v);
+godot_input_event GDAPI godot_variant_as_input_event(const godot_variant *p_v);
+godot_dictionary GDAPI godot_variant_as_dictionary(const godot_variant *p_v);
+godot_array GDAPI godot_variant_as_array(const godot_variant *p_v);
+godot_pool_byte_array GDAPI godot_variant_as_pool_byte_array(const godot_variant *p_v);
+godot_pool_int_array GDAPI godot_variant_as_pool_int_array(const godot_variant *p_v);
+godot_pool_real_array GDAPI godot_variant_as_pool_real_array(const godot_variant *p_v);
+godot_pool_string_array GDAPI godot_variant_as_pool_string_array(const godot_variant *p_v);
+godot_pool_vector2_array GDAPI godot_variant_as_pool_vector2_array(const godot_variant *p_v);
+godot_pool_vector3_array GDAPI godot_variant_as_pool_vector3_array(const godot_variant *p_v);
+godot_pool_color_array GDAPI godot_variant_as_pool_color_array(const godot_variant *p_v);
+
+godot_variant GDAPI godot_variant_call(godot_variant *p_v, const godot_string *p_method, const godot_variant **p_args, const godot_int p_argcount /*, godot_variant_call_error *r_error */);
+
+godot_bool GDAPI godot_variant_has_method(godot_variant *p_v, const godot_string *p_method);
+
+godot_bool GDAPI godot_variant_operator_equal(const godot_variant *p_a, const godot_variant *p_b);
+godot_bool GDAPI godot_variant_operator_less(const godot_variant *p_a, const godot_variant *p_b);
+
+godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_a, const godot_variant *p_b);
+
+godot_bool GDAPI godot_variant_booleanize(const godot_variant *p_v, godot_bool *p_valid);
+
+void GDAPI godot_variant_destroy(godot_variant *p_v);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/modules/dlscript/godot/godot_vector2.cpp b/modules/dlscript/godot/godot_vector2.cpp
new file mode 100644
index 0000000000..0664da186e
--- /dev/null
+++ b/modules/dlscript/godot/godot_vector2.cpp
@@ -0,0 +1,124 @@
+#include "godot_vector2.h"
+
+#include "math/math_2d.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _vector2_api_anchor() {
+}
+
+void GDAPI godot_vector2_new(godot_vector2 *p_v, godot_real p_x, godot_real p_y) {
+ Vector2 *v = (Vector2 *)p_v;
+ v->x = p_x;
+ v->y = p_y;
+}
+
+void GDAPI godot_vector2_set_x(godot_vector2 *p_v, const godot_real p_x) {
+ Vector2 *v = (Vector2 *)p_v;
+ v->x = p_x;
+}
+
+void GDAPI godot_vector2_set_y(godot_vector2 *p_v, const godot_real p_y) {
+ Vector2 *v = (Vector2 *)p_v;
+ v->y = p_y;
+}
+
+godot_real GDAPI godot_vector2_get_x(const godot_vector2 *p_v) {
+ Vector2 *v = (Vector2 *)p_v;
+ return v->x;
+}
+godot_real GDAPI godot_vector2_get_y(const godot_vector2 *p_v) {
+ Vector2 *v = (Vector2 *)p_v;
+ return v->y;
+}
+
+void GDAPI godot_vector2_normalize(godot_vector2 *p_v) {
+ Vector2 *v = (Vector2 *)p_v;
+ v->normalize();
+}
+void GDAPI godot_vector2_normalized(godot_vector2 *p_dest, const godot_vector2 *p_src) {
+ Vector2 *v = (Vector2 *)p_src;
+ Vector2 *d = (Vector2 *)p_dest;
+
+ *d = v->normalized();
+}
+
+godot_real GDAPI godot_vector2_length(const godot_vector2 *p_v) {
+ Vector2 *v = (Vector2 *)p_v;
+ return v->length();
+}
+
+godot_real GDAPI godot_vector2_length_squared(const godot_vector2 *p_v) {
+ Vector2 *v = (Vector2 *)p_v;
+ return v->length_squared();
+}
+
+godot_real GDAPI godot_vector2_distance_to(const godot_vector2 *p_a, const godot_vector2 *p_b) {
+ Vector2 *a = (Vector2 *)p_a;
+ Vector2 *b = (Vector2 *)p_b;
+ return a->distance_to(*b);
+}
+
+godot_real GDAPI godot_vector2_distance_squared_to(const godot_vector2 *p_a, const godot_vector2 *p_b) {
+ Vector2 *a = (Vector2 *)p_a;
+ Vector2 *b = (Vector2 *)p_b;
+ return a->distance_squared_to(*b);
+}
+
+void GDAPI godot_vector2_operator_add(godot_vector2 *p_dest, const godot_vector2 *p_a, const godot_vector2 *p_b) {
+ Vector2 *dest = (Vector2 *)p_dest;
+ const Vector2 *a = (Vector2 *)p_a;
+ const Vector2 *b = (Vector2 *)p_b;
+ *dest = *a + *b;
+}
+
+void GDAPI godot_vector2_operator_subtract(godot_vector2 *p_dest, const godot_vector2 *p_a, const godot_vector2 *p_b) {
+ Vector2 *dest = (Vector2 *)p_dest;
+ const Vector2 *a = (Vector2 *)p_a;
+ const Vector2 *b = (Vector2 *)p_b;
+ *dest = *a - *b;
+}
+
+void GDAPI godot_vector2_operator_multiply_vector(godot_vector2 *p_dest, const godot_vector2 *p_a, const godot_vector2 *p_b) {
+ Vector2 *dest = (Vector2 *)p_dest;
+ const Vector2 *a = (Vector2 *)p_a;
+ const Vector2 *b = (Vector2 *)p_b;
+ *dest = *a * *b;
+}
+
+void GDAPI godot_vector2_operator_multiply_scalar(godot_vector2 *p_dest, const godot_vector2 *p_a, const godot_real p_b) {
+ Vector2 *dest = (Vector2 *)p_dest;
+ const Vector2 *a = (Vector2 *)p_a;
+ *dest = *a * p_b;
+}
+
+void GDAPI godot_vector2_operator_divide_vector(godot_vector2 *p_dest, const godot_vector2 *p_a, const godot_vector2 *p_b) {
+ Vector2 *dest = (Vector2 *)p_dest;
+ const Vector2 *a = (Vector2 *)p_a;
+ const Vector2 *b = (Vector2 *)p_b;
+ *dest = *a / *b;
+}
+
+void GDAPI godot_vector2_operator_divide_scalar(godot_vector2 *p_dest, const godot_vector2 *p_a, const godot_real p_b) {
+ Vector2 *dest = (Vector2 *)p_dest;
+ const Vector2 *a = (Vector2 *)p_a;
+ *dest = *a / p_b;
+}
+
+godot_bool GDAPI godot_vector2_operator_equal(const godot_vector2 *p_a, const godot_vector2 *p_b) {
+ const Vector2 *a = (Vector2 *)p_a;
+ const Vector2 *b = (Vector2 *)p_b;
+ return *a == *b;
+}
+
+godot_bool GDAPI godot_vector2_operator_less(const godot_vector2 *p_a, const godot_vector2 *p_b) {
+ const Vector2 *a = (Vector2 *)p_a;
+ const Vector2 *b = (Vector2 *)p_b;
+ return *a < *b;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_vector2.h b/modules/dlscript/godot/godot_vector2.h
new file mode 100644
index 0000000000..63da367e4f
--- /dev/null
+++ b/modules/dlscript/godot/godot_vector2.h
@@ -0,0 +1,78 @@
+#ifndef GODOT_VECTOR2_H
+#define GODOT_VECTOR2_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_VECTOR2_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_VECTOR2_TYPE_DEFINED
+typedef struct godot_vector2 {
+ uint8_t _dont_touch_that[8];
+} godot_vector2;
+#endif
+
+#include "../godot.h"
+
+void GDAPI godot_vector2_new(godot_vector2 *p_v, const godot_real p_x, const godot_real p_y);
+
+void GDAPI godot_vector2_set_x(godot_vector2 *p_v, const godot_real p_x);
+void GDAPI godot_vector2_set_y(godot_vector2 *p_v, const godot_real p_y);
+godot_real GDAPI godot_vector2_get_x(const godot_vector2 *p_v);
+godot_real GDAPI godot_vector2_get_y(const godot_vector2 *p_v);
+
+void GDAPI godot_vector2_normalize(godot_vector2 *p_v);
+void GDAPI godot_vector2_normalized(godot_vector2 *p_dest, const godot_vector2 *p_src);
+
+godot_real GDAPI godot_vector2_length(const godot_vector2 *p_v);
+godot_real GDAPI godot_vector2_length_squared(const godot_vector2 *p_v);
+
+godot_real GDAPI godot_vector2_distance_to(const godot_vector2 *p_a, const godot_vector2 *p_b);
+godot_real GDAPI godot_vector2_distance_squared_to(const godot_vector2 *p_a, const godot_vector2 *p_b);
+
+// @Incomplete
+/*
+ * missing:
+ *
+ * angle_to
+ * angle_to_point
+ * dot
+ * cross_vector
+ * cross_scalar
+ * project
+ * plane_project
+ * clamped
+ * linear_interpolate
+ * cubic_interpolate
+ * cubic_interpolate_soft
+ * slide
+ * reflect
+ * angle
+ * abs
+ * rotated
+ * tangent
+ * floor
+ * snapped
+ * aspect
+ *
+ *
+ * to_string
+ */
+
+void GDAPI godot_vector2_operator_add(godot_vector2 *p_dest, const godot_vector2 *p_a, const godot_vector2 *p_b);
+void GDAPI godot_vector2_operator_subtract(godot_vector2 *p_dest, const godot_vector2 *p_a, const godot_vector2 *p_b);
+void GDAPI godot_vector2_operator_multiply_vector(godot_vector2 *p_dest, const godot_vector2 *p_a, const godot_vector2 *p_b);
+void GDAPI godot_vector2_operator_multiply_scalar(godot_vector2 *p_dest, const godot_vector2 *p_a, const godot_real p_b);
+void GDAPI godot_vector2_operator_divide_vector(godot_vector2 *p_dest, const godot_vector2 *p_a, const godot_vector2 *p_b);
+void GDAPI godot_vector2_operator_divide_scalar(godot_vector2 *p_dest, const godot_vector2 *p_a, const godot_real p_b);
+
+godot_bool GDAPI godot_vector2_operator_equal(const godot_vector2 *p_a, const godot_vector2 *p_b);
+godot_bool GDAPI godot_vector2_operator_less(const godot_vector2 *p_a, const godot_vector2 *p_b);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_VECTOR2_H
diff --git a/modules/dlscript/godot/godot_vector3.cpp b/modules/dlscript/godot/godot_vector3.cpp
new file mode 100644
index 0000000000..34005cbcb8
--- /dev/null
+++ b/modules/dlscript/godot/godot_vector3.cpp
@@ -0,0 +1,150 @@
+#include "godot_vector3.h"
+
+#include "math/vector3.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _vector3_api_anchor() {
+}
+
+void GDAPI godot_vector3_new(godot_vector3 *p_v, const godot_real p_x, const godot_real p_y, const godot_real p_z) {
+ Vector3 *v = (Vector3 *)p_v;
+ *v = Vector3(p_x, p_y, p_z);
+}
+
+void GDAPI godot_vector3_set_axis(godot_vector3 *p_v, const godot_int p_axis, const godot_real p_val) {
+ Vector3 *v = (Vector3 *)p_v;
+ v->set_axis(p_axis, p_val);
+}
+
+godot_real GDAPI godot_vector3_get_axis(const godot_vector3 *p_v, const godot_int p_axis) {
+ Vector3 *v = (Vector3 *)p_v;
+ return v->get_axis(p_axis);
+}
+
+godot_int GDAPI godot_vector3_min_axis(const godot_vector3 *p_v) {
+ Vector3 *v = (Vector3 *)p_v;
+ return v->min_axis();
+}
+
+godot_int GDAPI godot_vector3_max_axis(const godot_vector3 *p_v) {
+ Vector3 *v = (Vector3 *)p_v;
+ return v->max_axis();
+}
+
+godot_real GDAPI godot_vector3_length(const godot_vector3 *p_v) {
+ Vector3 *v = (Vector3 *)p_v;
+ return v->length();
+}
+
+godot_real GDAPI godot_vector3_length_squared(const godot_vector3 *p_v) {
+ Vector3 *v = (Vector3 *)p_v;
+ return v->length_squared();
+}
+
+void GDAPI godot_vector3_normalize(godot_vector3 *p_v) {
+ Vector3 *v = (Vector3 *)p_v;
+ v->normalize();
+}
+
+void GDAPI godot_vector3_normalized(godot_vector3 *p_dest, const godot_vector3 *p_src) {
+ Vector3 *src = (Vector3 *)p_src;
+ Vector3 *dest = (Vector3 *)p_dest;
+ *dest = src->normalized();
+}
+
+/*
+ * inverse
+ * zero
+ * snap
+ * snapped
+ * rotate
+ * rotated
+ *
+ *
+ * linear_interpolate
+ * cubic_interpolate
+ * cubic_interpolaten
+ * cross
+ * dot
+ * outer
+ * to_diagonal_matrix
+ * abs
+ * floor
+ * ceil
+ */
+
+godot_real GDAPI godot_vector3_distance_to(const godot_vector3 *p_a, const godot_vector3 *p_b) {
+ Vector3 *a = (Vector3 *)p_a;
+ Vector3 *b = (Vector3 *)p_b;
+ return a->distance_to(*b);
+}
+
+godot_real GDAPI godot_vector3_distance_squared_to(const godot_vector3 *p_a, const godot_vector3 *p_b) {
+ Vector3 *a = (Vector3 *)p_a;
+ Vector3 *b = (Vector3 *)p_b;
+ return a->distance_squared_to(*b);
+}
+
+/*
+ * slide
+ * reflect
+ */
+
+void GDAPI godot_vector3_operator_add(godot_vector3 *p_dest, const godot_vector3 *p_a, const godot_vector3 *p_b) {
+ Vector3 *dest = (Vector3 *)p_dest;
+ Vector3 *a = (Vector3 *)p_a;
+ Vector3 *b = (Vector3 *)p_b;
+ *dest = *a + *b;
+}
+
+void GDAPI godot_vector3_operator_subtract(godot_vector3 *p_dest, const godot_vector3 *p_a, const godot_vector3 *p_b) {
+ Vector3 *dest = (Vector3 *)p_dest;
+ Vector3 *a = (Vector3 *)p_a;
+ Vector3 *b = (Vector3 *)p_b;
+ *dest = *a - *b;
+}
+
+void GDAPI godot_vector3_operator_multiply_vector(godot_vector3 *p_dest, const godot_vector3 *p_a, const godot_vector3 *p_b) {
+ Vector3 *dest = (Vector3 *)p_dest;
+ Vector3 *a = (Vector3 *)p_a;
+ Vector3 *b = (Vector3 *)p_b;
+ *dest = *a * *b;
+}
+
+void GDAPI godot_vector3_operator_multiply_scalar(godot_vector3 *p_dest, const godot_vector3 *p_a, const godot_real p_b) {
+ Vector3 *dest = (Vector3 *)p_dest;
+ Vector3 *a = (Vector3 *)p_a;
+ *dest = *a * p_b;
+}
+
+void GDAPI godot_vector3_operator_divide_vector(godot_vector3 *p_dest, const godot_vector3 *p_a, const godot_vector3 *p_b) {
+ Vector3 *dest = (Vector3 *)p_dest;
+ Vector3 *a = (Vector3 *)p_a;
+ Vector3 *b = (Vector3 *)p_b;
+ *dest = *a / *b;
+}
+
+void GDAPI godot_vector3_operator_divide_scalar(godot_vector3 *p_dest, const godot_vector3 *p_a, const godot_real p_b) {
+ Vector3 *dest = (Vector3 *)p_dest;
+ Vector3 *a = (Vector3 *)p_a;
+ *dest = *a / p_b;
+}
+
+godot_bool GDAPI godot_vector3_operator_equal(const godot_vector3 *p_a, const godot_vector3 *p_b) {
+ Vector3 *a = (Vector3 *)p_a;
+ Vector3 *b = (Vector3 *)p_b;
+ return *a == *b;
+}
+
+godot_bool GDAPI godot_vector3_operator_less(const godot_vector3 *p_a, const godot_vector3 *p_b) {
+ Vector3 *a = (Vector3 *)p_a;
+ Vector3 *b = (Vector3 *)p_b;
+ return *a < *b;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/dlscript/godot/godot_vector3.h b/modules/dlscript/godot/godot_vector3.h
new file mode 100644
index 0000000000..7fe93e3fd5
--- /dev/null
+++ b/modules/dlscript/godot/godot_vector3.h
@@ -0,0 +1,82 @@
+#ifndef GODOT_VECTOR3_H
+#define GODOT_VECTOR3_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef GODOT_CORE_API_GODOT_VECTOR3_TYPE_DEFINED
+typedef struct godot_vector3 {
+ uint8_t _dont_touch_that[12];
+} godot_vector3;
+#endif
+
+#include "../godot.h"
+
+void GDAPI godot_vector3_new(godot_vector3 *p_v, const godot_real p_x, const godot_real p_y, const godot_real p_z);
+
+void GDAPI godot_vector3_set_axis(godot_vector3 *p_v, const godot_int p_axis, const godot_real p_val);
+godot_real GDAPI godot_vector3_get_axis(const godot_vector3 *p_v, const godot_int p_axis);
+
+godot_int GDAPI godot_vector3_min_axis(const godot_vector3 *p_v);
+godot_int GDAPI godot_vector3_max_axis(const godot_vector3 *p_v);
+
+godot_real GDAPI godot_vector3_length(const godot_vector3 *p_v);
+godot_real GDAPI godot_vector3_length_squared(const godot_vector3 *p_v);
+
+void GDAPI godot_vector3_normalize(godot_vector3 *p_v);
+void GDAPI godot_vector3_normalized(godot_vector3 *p_dest, const godot_vector3 *p_src);
+
+// @Incomplete
+
+/*
+ * inverse
+ * zero
+ * snap
+ * snapped
+ * rotate
+ * rotated
+ *
+ *
+ * linear_interpolate
+ * cubic_interpolate
+ * cubic_interpolaten
+ * cross
+ * dot
+ * outer
+ * to_diagonal_matrix
+ * abs
+ * floor
+ * ceil
+ */
+
+godot_real GDAPI godot_vector3_distance_to(const godot_vector3 *p_a, const godot_vector3 *p_b);
+godot_real GDAPI godot_vector3_distance_squared_to(const godot_vector3 *p_a, const godot_vector3 *p_b);
+
+// @Incomplete
+/*
+ * slide
+ * reflect
+ */
+
+void GDAPI godot_vector3_operator_add(godot_vector3 *p_dest, const godot_vector3 *p_a, const godot_vector3 *p_b);
+void GDAPI godot_vector3_operator_subtract(godot_vector3 *p_dest, const godot_vector3 *p_a, const godot_vector3 *p_b);
+void GDAPI godot_vector3_operator_multiply_vector(godot_vector3 *p_dest, const godot_vector3 *p_a, const godot_vector3 *p_b);
+void GDAPI godot_vector3_operator_multiply_scalar(godot_vector3 *p_dest, const godot_vector3 *p_a, const godot_real p_b);
+void GDAPI godot_vector3_operator_divide_vector(godot_vector3 *p_dest, const godot_vector3 *p_a, const godot_vector3 *p_b);
+void GDAPI godot_vector3_operator_divide_scalar(godot_vector3 *p_dest, const godot_vector3 *p_a, const godot_real p_b);
+
+godot_bool GDAPI godot_vector3_operator_equal(const godot_vector3 *p_a, const godot_vector3 *p_b);
+godot_bool GDAPI godot_vector3_operator_less(const godot_vector3 *p_a, const godot_vector3 *p_b);
+
+/*
+ * to_string
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_VECTOR3_H
diff --git a/modules/cscript/register_types.cpp b/modules/dlscript/register_types.cpp
index 2477bc51e2..1da00701a0 100644
--- a/modules/cscript/register_types.cpp
+++ b/modules/dlscript/register_types.cpp
@@ -27,8 +27,43 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "register_types.h"
+#include "dl_script.h"
-void register_cscript_types() {
+#include "io/resource_loader.h"
+#include "io/resource_saver.h"
+
+DLScriptLanguage *script_language_dl = NULL;
+ResourceFormatLoaderDLScript *resource_loader_dl = NULL;
+ResourceFormatSaverDLScript *resource_saver_dl = NULL;
+//ResourceFormatLoaderDLLibrary *resource_loader_dllib=NULL;
+
+void register_dlscript_types() {
+
+ ClassDB::register_class<DLLibrary>();
+ ClassDB::register_class<DLScript>();
+
+ script_language_dl = memnew(DLScriptLanguage);
+ //script_language_gd->init();
+ ScriptServer::register_language(script_language_dl);
+ resource_loader_dl = memnew(ResourceFormatLoaderDLScript);
+ ResourceLoader::add_resource_format_loader(resource_loader_dl);
+ resource_saver_dl = memnew(ResourceFormatSaverDLScript);
+ ResourceSaver::add_resource_format_saver(resource_saver_dl);
+
+ // resource_loader_dllib=memnew( ResourceFormatLoaderDLLibrary );
+ // ResourceLoader::add_resource_format_loader(resource_loader_gd);
}
-void unregister_cscript_types() {
+
+void unregister_dlscript_types() {
+
+ ScriptServer::unregister_language(script_language_dl);
+
+ if (script_language_dl)
+ memdelete(script_language_dl);
+
+ if (resource_loader_dl)
+ memdelete(resource_loader_dl);
+
+ if (resource_saver_dl)
+ memdelete(resource_saver_dl);
}
diff --git a/modules/cscript/register_types.h b/modules/dlscript/register_types.h
index 6614ee3a19..90aa1d87fc 100644
--- a/modules/cscript/register_types.h
+++ b/modules/dlscript/register_types.h
@@ -26,5 +26,5 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-void register_cscript_types();
-void unregister_cscript_types();
+void register_dlscript_types();
+void unregister_dlscript_types();
diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp
index 1540bb51f8..4c2965c8ec 100644
--- a/modules/gdscript/gd_parser.cpp
+++ b/modules/gdscript/gd_parser.cpp
@@ -2420,7 +2420,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) {
p_block->sub_blocks.push_back(cf_if->body);
if (!_enter_indent_block(cf_if->body)) {
- _set_error("Expected intended block after 'if'");
+ _set_error("Expected indented block after 'if'");
p_block->end_line = tokenizer->get_token_line();
return;
}
diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp
index 981924191f..dca34f923e 100644
--- a/modules/gdscript/gd_tokenizer.cpp
+++ b/modules/gdscript/gd_tokenizer.cpp
@@ -117,6 +117,7 @@ const char *GDTokenizer::token_names[TK_MAX] = {
"'.'",
"'?'",
"':'",
+ "'$'",
"'\\n'",
"PI",
"_",
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index a6a3a03503..64426298ef 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -834,9 +834,9 @@ void GridMapEditor::edit(GridMap *p_gridmap) {
//update grids
indicator_mat.instance();
- indicator_mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- indicator_mat->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- indicator_mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ indicator_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ indicator_mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ indicator_mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
indicator_mat->set_albedo(Color(0.8, 0.5, 0.1));
Vector<Vector3> grid_points[3];
@@ -1309,9 +1309,9 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
inner_mat.instance();
inner_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.3));
- inner_mat->set_flag(FixedSpatialMaterial::FLAG_ONTOP, true);
- inner_mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- inner_mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ inner_mat->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ inner_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ inner_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
d[VS::ARRAY_VERTEX] = triangles;
VisualServer::get_singleton()->mesh_add_surface_from_arrays(selection_mesh, VS::PRIMITIVE_TRIANGLES, d);
@@ -1319,10 +1319,10 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
outer_mat.instance();
outer_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.3));
- outer_mat->set_flag(FixedSpatialMaterial::FLAG_ONTOP, true);
- outer_mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
+ outer_mat->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ outer_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
outer_mat->set_line_width(3.0);
- outer_mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ outer_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
d[VS::ARRAY_VERTEX] = lines;
VisualServer::get_singleton()->mesh_add_surface_from_arrays(selection_mesh, VS::PRIMITIVE_LINES, d);
diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h
index 27a063ee41..947af0815f 100644
--- a/modules/gridmap/grid_map_editor_plugin.h
+++ b/modules/gridmap/grid_map_editor_plugin.h
@@ -112,9 +112,9 @@ class GridMapEditor : public VBoxContainer {
RID duplicate_mesh;
RID duplicate_instance;
- Ref<FixedSpatialMaterial> indicator_mat;
- Ref<FixedSpatialMaterial> inner_mat;
- Ref<FixedSpatialMaterial> outer_mat;
+ Ref<SpatialMaterial> indicator_mat;
+ Ref<SpatialMaterial> inner_mat;
+ Ref<SpatialMaterial> outer_mat;
bool updating;
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 0e78a4618d..8d2ed59f17 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -175,6 +175,8 @@ def configure(env):
if env['android_arch'] == 'x86':
can_vectorize = True
target_opts = ['-target', 'i686-none-linux-android']
+ # The NDK adds this if targeting API < 21, so we can drop it when Godot targets it at least
+ env.Append(CPPFLAGS=['-mstackrealign'])
elif env["android_arch"] == "armv6":
can_vectorize = False
target_opts = ['-target', 'armv6-none-linux-androideabi']
diff --git a/platform/iphone/rasterizer_iphone.cpp b/platform/iphone/rasterizer_iphone.cpp
index 14288e4ba0..9563df5a2f 100644
--- a/platform/iphone/rasterizer_iphone.cpp
+++ b/platform/iphone/rasterizer_iphone.cpp
@@ -447,7 +447,7 @@ RID RasterizerIPhone::material_create() {
return material_owner.make_rid(memnew(Material));
}
-void RasterizerIPhone::fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant &p_value) {
+void RasterizerIPhone::fixed_material_set_parameter(RID p_material, VS::SpatialMaterialParam p_parameter, const Variant &p_value) {
Material *m = material_owner.get(p_material);
ERR_FAIL_COND(!m);
@@ -455,7 +455,7 @@ void RasterizerIPhone::fixed_material_set_parameter(RID p_material, VS::FixedSpa
m->parameters[p_parameter] = p_value;
}
-Variant RasterizerIPhone::fixed_material_get_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const {
+Variant RasterizerIPhone::fixed_material_get_parameter(RID p_material, VS::SpatialMaterialParam p_parameter) const {
Material *m = material_owner.get(p_material);
ERR_FAIL_COND_V(!m, Variant());
@@ -464,7 +464,7 @@ Variant RasterizerIPhone::fixed_material_get_parameter(RID p_material, VS::Fixed
return m->parameters[p_parameter];
}
-void RasterizerIPhone::fixed_material_set_texture(RID p_material, VS::FixedSpatialMaterialParam p_parameter, RID p_texture) {
+void RasterizerIPhone::fixed_material_set_texture(RID p_material, VS::SpatialMaterialParam p_parameter, RID p_texture) {
Material *m = material_owner.get(p_material);
ERR_FAIL_COND(!m);
@@ -472,7 +472,7 @@ void RasterizerIPhone::fixed_material_set_texture(RID p_material, VS::FixedSpati
m->textures[p_parameter] = p_texture;
}
-RID RasterizerIPhone::fixed_material_get_texture(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const {
+RID RasterizerIPhone::fixed_material_get_texture(RID p_material, VS::SpatialMaterialParam p_parameter) const {
Material *m = material_owner.get(p_material);
ERR_FAIL_COND_V(!m, RID());
@@ -496,7 +496,7 @@ VS::MaterialBlendMode RasterizerIPhone::fixed_material_get_detail_blend_mode(RID
return m->detail_blend_mode;
}
-void RasterizerIPhone::fixed_material_set_texcoord_mode(RID p_material, VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode) {
+void RasterizerIPhone::fixed_material_set_texcoord_mode(RID p_material, VS::SpatialMaterialParam p_parameter, VS::SpatialMaterialTexCoordMode p_mode) {
Material *m = material_owner.get(p_material);
ERR_FAIL_COND(!m);
@@ -504,7 +504,7 @@ void RasterizerIPhone::fixed_material_set_texcoord_mode(RID p_material, VS::Fixe
m->texcoord_mode[p_parameter] = p_mode;
}
-VS::FixedSpatialMaterialTexCoordMode RasterizerIPhone::fixed_material_get_texcoord_mode(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const {
+VS::SpatialMaterialTexCoordMode RasterizerIPhone::fixed_material_get_texcoord_mode(RID p_material, VS::SpatialMaterialParam p_parameter) const {
Material *m = material_owner.get(p_material);
ERR_FAIL_COND_V(!m, VS::FIXED_MATERIAL_TEXCOORD_TEXGEN);
@@ -513,7 +513,7 @@ VS::FixedSpatialMaterialTexCoordMode RasterizerIPhone::fixed_material_get_texcoo
return m->texcoord_mode[p_parameter]; // for now
}
-void RasterizerIPhone::fixed_material_set_texgen_mode(RID p_material, VS::FixedSpatialMaterialTexGenMode p_mode) {
+void RasterizerIPhone::fixed_material_set_texgen_mode(RID p_material, VS::SpatialMaterialTexGenMode p_mode) {
Material *m = material_owner.get(p_material);
ERR_FAIL_COND(!m);
@@ -521,7 +521,7 @@ void RasterizerIPhone::fixed_material_set_texgen_mode(RID p_material, VS::FixedS
m->texgen_mode = p_mode;
};
-VS::FixedSpatialMaterialTexGenMode RasterizerIPhone::fixed_material_get_texgen_mode(RID p_material) const {
+VS::SpatialMaterialTexGenMode RasterizerIPhone::fixed_material_get_texgen_mode(RID p_material) const {
Material *m = material_owner.get(p_material);
ERR_FAIL_COND_V(!m, VS::FIXED_MATERIAL_TEXGEN_SPHERE);
diff --git a/platform/iphone/rasterizer_iphone.h b/platform/iphone/rasterizer_iphone.h
index 02cb985dc8..5fee149e79 100644
--- a/platform/iphone/rasterizer_iphone.h
+++ b/platform/iphone/rasterizer_iphone.h
@@ -100,11 +100,11 @@ class RasterizerIPhone : public Rasterizer {
RID textures[VisualServer::FIXED_MATERIAL_PARAM_MAX];
Transform uv_transform;
- VS::FixedSpatialMaterialTexCoordMode texcoord_mode[VisualServer::FIXED_MATERIAL_PARAM_MAX];
+ VS::SpatialMaterialTexCoordMode texcoord_mode[VisualServer::FIXED_MATERIAL_PARAM_MAX];
VS::MaterialBlendMode detail_blend_mode;
- VS::FixedSpatialMaterialTexGenMode texgen_mode;
+ VS::SpatialMaterialTexGenMode texgen_mode;
Material() {
@@ -614,20 +614,20 @@ public:
virtual RID material_create();
- virtual void fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant &p_value);
- virtual Variant fixed_material_get_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const;
+ virtual void fixed_material_set_parameter(RID p_material, VS::SpatialMaterialParam p_parameter, const Variant &p_value);
+ virtual Variant fixed_material_get_parameter(RID p_material, VS::SpatialMaterialParam p_parameter) const;
- virtual void fixed_material_set_texture(RID p_material, VS::FixedSpatialMaterialParam p_parameter, RID p_texture);
- virtual RID fixed_material_get_texture(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const;
+ virtual void fixed_material_set_texture(RID p_material, VS::SpatialMaterialParam p_parameter, RID p_texture);
+ virtual RID fixed_material_get_texture(RID p_material, VS::SpatialMaterialParam p_parameter) const;
virtual void fixed_material_set_detail_blend_mode(RID p_material, VS::MaterialBlendMode p_mode);
virtual VS::MaterialBlendMode fixed_material_get_detail_blend_mode(RID p_material) const;
- virtual void fixed_material_set_texgen_mode(RID p_material, VS::FixedSpatialMaterialTexGenMode p_mode);
- virtual VS::FixedSpatialMaterialTexGenMode fixed_material_get_texgen_mode(RID p_material) const;
+ virtual void fixed_material_set_texgen_mode(RID p_material, VS::SpatialMaterialTexGenMode p_mode);
+ virtual VS::SpatialMaterialTexGenMode fixed_material_get_texgen_mode(RID p_material) const;
- virtual void fixed_material_set_texcoord_mode(RID p_material, VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode);
- virtual VS::FixedSpatialMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const;
+ virtual void fixed_material_set_texcoord_mode(RID p_material, VS::SpatialMaterialParam p_parameter, VS::SpatialMaterialTexCoordMode p_mode);
+ virtual VS::SpatialMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material, VS::SpatialMaterialParam p_parameter) const;
virtual void fixed_material_set_uv_transform(RID p_material, const Transform &p_transform);
virtual Transform fixed_material_get_uv_transform(RID p_material) const;
diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp
index bb51474a8c..df1605ae9e 100644
--- a/platform/windows/export/export.cpp
+++ b/platform/windows/export/export.cpp
@@ -26,28 +26,25 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "export.h"
#include "editor/editor_export.h"
#include "platform/windows/logo.h"
void register_windows_exporter() {
-#if 0
+ Ref<EditorExportPlatformPC> platform;
+ platform.instance();
+
Image img(_windows_logo);
- Ref<ImageTexture> logo = memnew( ImageTexture );
+ Ref<ImageTexture> logo;
+ logo.instance();
logo->create_from_image(img);
+ platform->set_logo(logo);
+ platform->set_name("Windows Desktop");
+ platform->set_extension("exe");
+ platform->set_release_32("windows_32_release.exe");
+ platform->set_debug_32("windows_32_debug.exe");
+ platform->set_release_64("windows_64_release.exe");
+ platform->set_debug_64("windows_64_debug.exe");
- {
- Ref<EditorExportPlatformPC> exporter = Ref<EditorExportPlatformPC>( memnew(EditorExportPlatformPC) );
- exporter->set_binary_extension("exe");
- exporter->set_release_binary32("windows_32_release.exe");
- exporter->set_debug_binary32("windows_32_debug.exe");
- exporter->set_release_binary64("windows_64_release.exe");
- exporter->set_debug_binary64("windows_64_debug.exe");
- exporter->set_name("Windows Desktop");
- exporter->set_logo(logo);
- EditorImportExport::get_singleton()->add_export_platform(exporter);
- }
-
-#endif
+ EditorExport::get_singleton()->add_export_platform(platform);
}
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 83a6aa6079..cfc97d57da 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -1582,6 +1582,32 @@ bool OS_Windows::get_borderless_window() {
return video_mode.borderless_window;
}
+Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle) {
+ p_library_handle = (void *)LoadLibrary(p_path.utf8().get_data());
+ if (!p_library_handle) {
+ ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + String::num(GetLastError()));
+ ERR_FAIL_V(ERR_CANT_OPEN);
+ }
+ return OK;
+}
+
+Error OS_Windows::close_dynamic_library(void *p_library_handle) {
+ if (!FreeLibrary((HMODULE)p_library_handle)) {
+ return FAILED;
+ }
+ return OK;
+}
+
+Error OS_Windows::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle) {
+ char *error;
+ p_symbol_handle = (void *)GetProcAddress((HMODULE)p_library_handle, p_name.utf8().get_data());
+ if (!p_symbol_handle) {
+ ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + String::num(GetLastError()));
+ ERR_FAIL_V(ERR_CANT_RESOLVE);
+ }
+ return OK;
+}
+
void OS_Windows::request_attention() {
FLASHWINFO info;
@@ -2167,9 +2193,6 @@ void OS_Windows::run() {
if (!main_loop)
return;
- // Process all events before the main initialization so the cursor will get initialized properly
- process_events(); // get rid of pending events
-
main_loop->init();
uint64_t last_ticks = get_ticks_usec();
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 25c3102ee6..050067ad7d 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -222,6 +222,10 @@ public:
virtual void set_borderless_window(int p_borderless);
virtual bool get_borderless_window();
+ virtual Error open_dynamic_library(const String p_path, void *&p_library_handle);
+ virtual Error close_dynamic_library(void *p_library_handle);
+ virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle);
+
virtual MainLoop *get_main_loop() const;
virtual String get_name();
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 4606a90835..6aeab21c7f 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -1277,12 +1277,8 @@ void OS_X11::process_xevents() {
case EnterNotify: {
if (main_loop && !mouse_mode_grab)
main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
- if (input) {
- // Update mouse position. It is triggered before mouse motion.
- Point2i pos(event.xmotion.x, event.xmotion.y);
- input->set_mouse_pos(pos);
+ if (input)
input->set_mouse_in_window(true);
- }
} break;
case FocusIn:
minimized = false;
@@ -1904,9 +1900,6 @@ void OS_X11::run() {
if (!main_loop)
return;
- // Process all events before the main initialization so the cursor will get initialized properly
- process_xevents(); // get rid of pending events
-
main_loop->init();
//uint64_t last_ticks=get_ticks_usec();
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index b52dd8d660..9ac12de45e 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -37,124 +37,6 @@
#include "scene/scene_string_names.h"
#include "servers/visual_server.h"
-bool CanvasItemMaterial::_set(const StringName &p_name, const Variant &p_value) {
-
- if (p_name == SceneStringNames::get_singleton()->shader_shader) {
- set_shader(p_value);
- return true;
- } else {
-
- if (shader.is_valid()) {
-
- StringName pr = shader->remap_param(p_name);
- if (!pr) {
- String n = p_name;
- if (n.find("param/") == 0) { //backwards compatibility
- pr = n.substr(6, n.length());
- }
- }
- if (pr) {
- VisualServer::get_singleton()->material_set_param(_get_material(), pr, p_value);
- return true;
- }
- }
- }
-
- return false;
-}
-
-bool CanvasItemMaterial::_get(const StringName &p_name, Variant &r_ret) const {
-
- if (p_name == SceneStringNames::get_singleton()->shader_shader) {
-
- r_ret = get_shader();
- return true;
-
- } else {
-
- if (shader.is_valid()) {
-
- StringName pr = shader->remap_param(p_name);
- if (pr) {
- r_ret = VisualServer::get_singleton()->material_get_param(_get_material(), pr);
- return true;
- }
- }
- }
-
- return false;
-}
-
-void CanvasItemMaterial::_get_property_list(List<PropertyInfo> *p_list) const {
-
- p_list->push_back(PropertyInfo(Variant::OBJECT, "shader/shader", PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemShader,CanvasItemShaderGraph"));
-
- if (!shader.is_null()) {
-
- shader->get_param_list(p_list);
- }
-}
-
-void CanvasItemMaterial::set_shader(const Ref<Shader> &p_shader) {
-
- ERR_FAIL_COND(p_shader.is_valid() && p_shader->get_mode() != Shader::MODE_CANVAS_ITEM);
-
- shader = p_shader;
-
- RID rid;
- if (shader.is_valid())
- rid = shader->get_rid();
-
- VS::get_singleton()->material_set_shader(_get_material(), rid);
- _change_notify(); //properties for shader exposed
- emit_changed();
-}
-
-Ref<Shader> CanvasItemMaterial::get_shader() const {
-
- return shader;
-}
-
-void CanvasItemMaterial::set_shader_param(const StringName &p_param, const Variant &p_value) {
-
- VS::get_singleton()->material_set_param(_get_material(), p_param, p_value);
-}
-
-Variant CanvasItemMaterial::get_shader_param(const StringName &p_param) const {
-
- return VS::get_singleton()->material_get_param(_get_material(), p_param);
-}
-
-void CanvasItemMaterial::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_shader", "shader:Shader"), &CanvasItemMaterial::set_shader);
- ClassDB::bind_method(D_METHOD("get_shader:Shader"), &CanvasItemMaterial::get_shader);
- ClassDB::bind_method(D_METHOD("set_shader_param", "param", "value"), &CanvasItemMaterial::set_shader_param);
- ClassDB::bind_method(D_METHOD("get_shader_param", "param"), &CanvasItemMaterial::get_shader_param);
-}
-
-void CanvasItemMaterial::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
-
- String f = p_function.operator String();
- if ((f == "get_shader_param" || f == "set_shader_param") && p_idx == 0) {
-
- if (shader.is_valid()) {
- List<PropertyInfo> pl;
- shader->get_param_list(&pl);
- for (List<PropertyInfo>::Element *E = pl.front(); E; E = E->next()) {
- r_options->push_back("\"" + E->get().name.replace_first("shader_param/", "") + "\"");
- }
- }
- }
- Resource::get_argument_options(p_function, p_idx, r_options);
-}
-
-CanvasItemMaterial::CanvasItemMaterial() {
-}
-
-CanvasItemMaterial::~CanvasItemMaterial() {
-}
-
///////////////////////////////////////////////////////////////////
bool CanvasItem::is_visible_in_tree() const {
@@ -206,7 +88,7 @@ void CanvasItem::show() {
return;
_propagate_visibility_changed(true);
- _change_notify("visibility/visible");
+ _change_notify("visible");
}
void CanvasItem::hide() {
@@ -221,7 +103,7 @@ void CanvasItem::hide() {
return;
_propagate_visibility_changed(false);
- _change_notify("visibility/visible");
+ _change_notify("visible");
}
Variant CanvasItem::edit_get_state() const {
@@ -770,7 +652,7 @@ bool CanvasItem::is_draw_behind_parent_enabled() const {
return behind;
}
-void CanvasItem::set_material(const Ref<CanvasItemMaterial> &p_material) {
+void CanvasItem::set_material(const Ref<ShaderMaterial> &p_material) {
material = p_material;
RID rid;
@@ -791,7 +673,7 @@ bool CanvasItem::get_use_parent_material() const {
return use_parent_material;
}
-Ref<CanvasItemMaterial> CanvasItem::get_material() const {
+Ref<ShaderMaterial> CanvasItem::get_material() const {
return material;
}
@@ -801,7 +683,7 @@ Vector2 CanvasItem::make_canvas_pos_local(const Vector2 &screen_point) const {
ERR_FAIL_COND_V(!is_inside_tree(), screen_point);
Transform2D local_matrix = (get_canvas_transform() *
- get_global_transform())
+ get_global_transform())
.affine_inverse();
return local_matrix.xform(screen_point);
@@ -895,8 +777,8 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_world_2d"), &CanvasItem::get_world_2d);
//ClassDB::bind_method(D_METHOD("get_viewport"),&CanvasItem::get_viewport);
- ClassDB::bind_method(D_METHOD("set_material", "material:CanvasItemMaterial"), &CanvasItem::set_material);
- ClassDB::bind_method(D_METHOD("get_material:CanvasItemMaterial"), &CanvasItem::get_material);
+ ClassDB::bind_method(D_METHOD("set_material", "material:ShaderMaterial"), &CanvasItem::set_material);
+ ClassDB::bind_method(D_METHOD("get_material:ShaderMaterial"), &CanvasItem::get_material);
ClassDB::bind_method(D_METHOD("set_use_parent_material", "enable"), &CanvasItem::set_use_parent_material);
ClassDB::bind_method(D_METHOD("get_use_parent_material"), &CanvasItem::get_use_parent_material);
@@ -922,7 +804,7 @@ void CanvasItem::_bind_methods() {
ADD_PROPERTYNO(PropertyInfo(Variant::INT, "light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_light_mask", "get_light_mask");
ADD_GROUP("Material", "");
- ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial"), "set_material", "get_material");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial"), "set_material", "get_material");
ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "use_parent_material"), "set_use_parent_material", "get_use_parent_material");
//exporting these two things doesn't really make much sense i think
//ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transform/toplevel"), "set_as_toplevel","is_set_as_toplevel") ;
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index a188ce495a..a5074991da 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -41,38 +41,6 @@ class Font;
class StyleBox;
-class CanvasItemMaterial : public Material {
-
- GDCLASS(CanvasItemMaterial, Material);
- Ref<Shader> shader;
-
-public:
- /*enum ShadingMode {
- SHADING_NORMAL,
- SHADING_UNSHADED,
- SHADING_ONLY_LIGHT,
- };*/
-
-protected:
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
-
- static void _bind_methods();
-
- void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
-
-public:
- void set_shader(const Ref<Shader> &p_shader);
- Ref<Shader> get_shader() const;
-
- void set_shader_param(const StringName &p_param, const Variant &p_value);
- Variant get_shader_param(const StringName &p_param) const;
-
- CanvasItemMaterial();
- ~CanvasItemMaterial();
-};
-
class CanvasItem : public Node {
GDCLASS(CanvasItem, Node);
@@ -114,7 +82,7 @@ private:
bool notify_local_transform;
bool notify_transform;
- Ref<CanvasItemMaterial> material;
+ Ref<ShaderMaterial> material;
mutable Transform2D global_transform;
mutable bool global_invalid;
@@ -234,8 +202,8 @@ public:
RID get_canvas() const;
Ref<World2D> get_world_2d() const;
- void set_material(const Ref<CanvasItemMaterial> &p_material);
- Ref<CanvasItemMaterial> get_material() const;
+ void set_material(const Ref<ShaderMaterial> &p_material);
+ Ref<ShaderMaterial> get_material() const;
void set_use_parent_material(bool p_use_parent_material);
bool get_use_parent_material() const;
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index 1ba6ec46cf..16b6342299 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -63,9 +63,10 @@ void Node2D::edit_set_state(const Variant &p_state) {
angle = state[1];
_scale = state[2];
_update_transform();
- _change_notify("transform/rot");
- _change_notify("transform/scale");
- _change_notify("transform/pos");
+ _change_notify("rotation");
+ _change_notify("rotation_deg");
+ _change_notify("scale");
+ _change_notify("position");
}
void Node2D::edit_set_rect(const Rect2 &p_edit_rect) {
@@ -95,15 +96,16 @@ void Node2D::edit_set_rect(const Rect2 &p_edit_rect) {
_scale *= new_scale;
_update_transform();
- _change_notify("transform/scale");
- _change_notify("transform/pos");
+ _change_notify("scale");
+ _change_notify("position");
}
void Node2D::edit_rotate(float p_rot) {
angle += p_rot;
_update_transform();
- _change_notify("transform/rot");
+ _change_notify("rotation");
+ _change_notify("rotation_deg");
}
void Node2D::_update_xform_values() {
@@ -134,7 +136,7 @@ void Node2D::set_position(const Point2 &p_pos) {
((Node2D *)this)->_update_xform_values();
pos = p_pos;
_update_transform();
- _change_notify("transform/pos");
+ _change_notify("position");
}
void Node2D::set_rotation(float p_radians) {
@@ -143,7 +145,8 @@ void Node2D::set_rotation(float p_radians) {
((Node2D *)this)->_update_xform_values();
angle = p_radians;
_update_transform();
- _change_notify("transform/rot");
+ _change_notify("rotation");
+ _change_notify("rotation_deg");
}
void Node2D::set_rotation_in_degrees(float p_degrees) {
@@ -169,7 +172,7 @@ void Node2D::set_scale(const Size2 &p_scale) {
if (_scale.y == 0)
_scale.y = CMP_EPSILON;
_update_transform();
- _change_notify("transform/scale");
+ _change_notify("scale");
}
Point2 Node2D::get_position() const {
@@ -349,6 +352,7 @@ void Node2D::set_z(int p_z) {
ERR_FAIL_COND(p_z > VS::CANVAS_ITEM_Z_MAX);
z = p_z;
VS::get_singleton()->canvas_item_set_z(get_canvas_item(), z);
+ _change_notify("z");
}
void Node2D::set_z_as_relative(bool p_enabled) {
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 88845a7290..00187f28bc 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -1168,7 +1168,7 @@ Vector2 KinematicBody2D::move(const Vector2 &p_motion) {
#endif
}
-Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_bounces) {
+Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_bounces, float p_floor_max_angle) {
Vector2 motion = (move_and_slide_floor_velocity + p_linear_velocity) * get_fixed_process_delta_time();
Vector2 lv = p_linear_velocity;
@@ -1189,7 +1189,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
//all is a wall
move_and_slide_on_wall = true;
} else {
- if (get_collision_normal().dot(p_floor_direction) > Math::cos(Math::deg2rad((float)45))) { //floor
+ if (get_collision_normal().dot(p_floor_direction) >= Math::cos(p_floor_max_angle)) { //floor
move_and_slide_on_floor = true;
move_and_slide_floor_velocity = get_collider_velocity();
@@ -1198,15 +1198,16 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
revert_motion();
return Vector2();
}
- } else if (get_collision_normal().dot(p_floor_direction) < Math::cos(Math::deg2rad((float)45))) { //ceiling
+ } else if (get_collision_normal().dot(-p_floor_direction) <= Math::cos(p_floor_max_angle)) { //ceiling
move_and_slide_on_ceiling = true;
} else {
move_and_slide_on_wall = true;
}
}
- motion = get_collision_normal().slide(motion);
- lv = get_collision_normal().slide(lv);
+ Vector2 n = get_collision_normal();
+ motion = motion.slide(n);
+ lv = lv.slide(n);
Variant collider = _get_collider();
if (collider.get_type() != Variant::NIL) {
move_and_slide_colliders.push_back(collider);
@@ -1307,7 +1308,7 @@ void KinematicBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("move", "rel_vec"), &KinematicBody2D::move);
ClassDB::bind_method(D_METHOD("move_to", "position"), &KinematicBody2D::move_to);
- ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_bounces"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(5), DEFVAL(4));
+ ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec"), &KinematicBody2D::test_move);
ClassDB::bind_method(D_METHOD("get_travel"), &KinematicBody2D::get_travel);
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index e51b512302..6ce6f14d36 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -314,7 +314,7 @@ public:
void set_collision_margin(float p_margin);
float get_collision_margin() const;
- Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), float p_slope_stop_min_velocity = 5, int p_max_bounces = 4);
+ Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), float p_slope_stop_min_velocity = 5, int p_max_bounces = 4, float p_floor_max_angle = Math::deg2rad((float)45));
bool is_move_and_slide_on_floor() const;
bool is_move_and_slide_on_wall() const;
bool is_move_and_slide_on_ceiling() const;
diff --git a/scene/2d/screen_button.cpp b/scene/2d/screen_button.cpp
index db822ed306..804af7d9c6 100644
--- a/scene/2d/screen_button.cpp
+++ b/scene/2d/screen_button.cpp
@@ -65,12 +65,14 @@ Ref<BitMap> TouchScreenButton::get_bitmask() const {
void TouchScreenButton::set_shape(const Ref<Shape2D> &p_shape) {
+ if (shape.is_valid())
+ shape->disconnect("changed", this, "update");
+
shape = p_shape;
- if (!is_inside_tree())
- return;
- if (!get_tree()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint())
- return;
+ if (shape.is_valid())
+ shape->connect("changed", this, "update");
+
update();
}
@@ -82,11 +84,17 @@ Ref<Shape2D> TouchScreenButton::get_shape() const {
void TouchScreenButton::set_shape_centered(bool p_shape_centered) {
shape_centered = p_shape_centered;
+ update();
+}
- if (!is_inside_tree())
- return;
- if (!get_tree()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint())
- return;
+bool TouchScreenButton::is_shape_visible() const {
+
+ return shape_visible;
+}
+
+void TouchScreenButton::set_shape_visible(bool p_shape_visible) {
+
+ shape_visible = p_shape_visible;
update();
}
@@ -118,6 +126,8 @@ void TouchScreenButton::_notification(int p_what) {
draw_texture(texture, Point2());
}
+ if (!shape_visible)
+ return;
if (!get_tree()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint())
return;
if (shape.is_valid()) {
@@ -375,6 +385,9 @@ void TouchScreenButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shape_centered", "bool"), &TouchScreenButton::set_shape_centered);
ClassDB::bind_method(D_METHOD("is_shape_centered"), &TouchScreenButton::is_shape_centered);
+ ClassDB::bind_method(D_METHOD("set_shape_visible", "bool"), &TouchScreenButton::set_shape_visible);
+ ClassDB::bind_method(D_METHOD("is_shape_visible"), &TouchScreenButton::is_shape_visible);
+
ClassDB::bind_method(D_METHOD("set_action", "action"), &TouchScreenButton::set_action);
ClassDB::bind_method(D_METHOD("get_action"), &TouchScreenButton::get_action);
@@ -393,6 +406,7 @@ void TouchScreenButton::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "bitmask", PROPERTY_HINT_RESOURCE_TYPE, "BitMap"), "set_bitmask", "get_bitmask");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", "get_shape");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shape_centered"), "set_shape_centered", "is_shape_centered");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shape_visible"), "set_shape_visible", "is_shape_visible");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "passby_press"), "set_passby_press", "is_passby_press_enabled");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "action"), "set_action", "get_action");
ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_mode", PROPERTY_HINT_ENUM, "Always,TouchScreen Only"), "set_visibility_mode", "get_visibility_mode");
@@ -408,6 +422,7 @@ TouchScreenButton::TouchScreenButton() {
passby_press = false;
visibility = VISIBILITY_ALWAYS;
shape_centered = true;
+ shape_visible = true;
unit_rect = Ref<RectangleShape2D>(memnew(RectangleShape2D));
unit_rect->set_extents(Vector2(0.5, 0.5));
}
diff --git a/scene/2d/screen_button.h b/scene/2d/screen_button.h
index 201d908bf6..2262723ed3 100644
--- a/scene/2d/screen_button.h
+++ b/scene/2d/screen_button.h
@@ -50,6 +50,7 @@ private:
Ref<BitMap> bitmask;
Ref<Shape2D> shape;
bool shape_centered;
+ bool shape_visible;
Ref<RectangleShape2D> unit_rect;
@@ -85,6 +86,9 @@ public:
void set_shape_centered(bool p_shape_centered);
bool is_shape_centered() const;
+ void set_shape_visible(bool p_shape_visible);
+ bool is_shape_visible() const;
+
void set_action(const String &p_action);
String get_action() const;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 02b41fbd0c..8e57517175 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -304,7 +304,7 @@ void TileMap::_update_dirty_quadrants() {
VS::get_singleton()->free(E->get().id);
}
q.occluder_instances.clear();
- Ref<CanvasItemMaterial> prev_material;
+ Ref<ShaderMaterial> prev_material;
RID prev_canvas_item;
RID prev_debug_canvas_item;
@@ -324,7 +324,7 @@ void TileMap::_update_dirty_quadrants() {
if (!tex.is_valid())
continue;
- Ref<CanvasItemMaterial> mat = tile_set->tile_get_material(c.id);
+ Ref<ShaderMaterial> mat = tile_set->tile_get_material(c.id);
RID canvas_item;
RID debug_canvas_item;
diff --git a/scene/3d/baked_light_instance.cpp b/scene/3d/baked_light_instance.cpp
index ac424475ea..e887aac439 100644
--- a/scene/3d/baked_light_instance.cpp
+++ b/scene/3d/baked_light_instance.cpp
@@ -250,7 +250,7 @@ Vector<Color> BakedLight::_get_bake_texture(Image &p_image, const Color &p_color
BakedLight::MaterialCache BakedLight::_get_material_cache(Ref<Material> p_material) {
//this way of obtaining materials is inaccurate and also does not support some compressed formats very well
- Ref<FixedSpatialMaterial> mat = p_material;
+ Ref<SpatialMaterial> mat = p_material;
Ref<Material> material = mat; //hack for now
@@ -262,7 +262,7 @@ BakedLight::MaterialCache BakedLight::_get_material_cache(Ref<Material> p_materi
if (mat.is_valid()) {
- Ref<ImageTexture> albedo_tex = mat->get_texture(FixedSpatialMaterial::TEXTURE_ALBEDO);
+ Ref<ImageTexture> albedo_tex = mat->get_texture(SpatialMaterial::TEXTURE_ALBEDO);
Image img_albedo;
if (albedo_tex.is_valid()) {
@@ -272,7 +272,7 @@ BakedLight::MaterialCache BakedLight::_get_material_cache(Ref<Material> p_materi
mc.albedo = _get_bake_texture(img_albedo, mat->get_albedo());
- Ref<ImageTexture> emission_tex = mat->get_texture(FixedSpatialMaterial::TEXTURE_EMISSION);
+ Ref<ImageTexture> emission_tex = mat->get_texture(SpatialMaterial::TEXTURE_EMISSION);
Color emission_col = mat->get_emission();
emission_col.r *= mat->get_emission_energy();
@@ -1591,11 +1591,11 @@ void BakedLight::create_debug_mesh(DebugMode p_mode) {
}
{
- Ref<FixedSpatialMaterial> fsm;
+ Ref<SpatialMaterial> fsm;
fsm.instance();
- fsm->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- fsm->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- fsm->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
+ fsm->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ fsm->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ fsm->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
fsm->set_albedo(Color(1, 1, 1, 1));
mesh->surface_set_material(0, fsm);
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp
index cb1292a9d1..6cdd42ed65 100644
--- a/scene/3d/gi_probe.cpp
+++ b/scene/3d/gi_probe.cpp
@@ -919,7 +919,7 @@ Vector<Color> GIProbe::_get_bake_texture(Image &p_image, const Color &p_color) {
GIProbe::Baker::MaterialCache GIProbe::_get_material_cache(Ref<Material> p_material, Baker *p_baker) {
//this way of obtaining materials is inaccurate and also does not support some compressed formats very well
- Ref<FixedSpatialMaterial> mat = p_material;
+ Ref<SpatialMaterial> mat = p_material;
Ref<Material> material = mat; //hack for now
@@ -931,7 +931,7 @@ GIProbe::Baker::MaterialCache GIProbe::_get_material_cache(Ref<Material> p_mater
if (mat.is_valid()) {
- Ref<Texture> albedo_tex = mat->get_texture(FixedSpatialMaterial::TEXTURE_ALBEDO);
+ Ref<Texture> albedo_tex = mat->get_texture(SpatialMaterial::TEXTURE_ALBEDO);
Image img_albedo;
if (albedo_tex.is_valid()) {
@@ -942,7 +942,7 @@ GIProbe::Baker::MaterialCache GIProbe::_get_material_cache(Ref<Material> p_mater
mc.albedo = _get_bake_texture(img_albedo, mat->get_albedo());
- Ref<ImageTexture> emission_tex = mat->get_texture(FixedSpatialMaterial::TEXTURE_EMISSION);
+ Ref<ImageTexture> emission_tex = mat->get_texture(SpatialMaterial::TEXTURE_EMISSION);
Color emission_col = mat->get_emission();
emission_col.r *= mat->get_emission_energy();
@@ -1365,11 +1365,11 @@ void GIProbe::_create_debug_mesh(Baker *p_baker) {
}
{
- Ref<FixedSpatialMaterial> fsm;
+ Ref<SpatialMaterial> fsm;
fsm.instance();
- fsm->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- fsm->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- fsm->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
+ fsm->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ fsm->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ fsm->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
fsm->set_albedo(Color(1, 1, 1, 1));
mesh->surface_set_material(0, fsm);
diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp
index ea61253ac7..2a92d6652c 100644
--- a/scene/3d/particles.cpp
+++ b/scene/3d/particles.cpp
@@ -30,532 +30,1353 @@
#include "scene/resources/surface_tool.h"
#include "servers/visual_server.h"
-#if 0
-/*
-static const char* _var_names[Particles::VAR_MAX]={
- "vars/lifetime",
- "vars/spread",
- "vars/gravity",
- "vars/linear_vel",
- "vars/angular_vel",
- "vars/linear_accel",
- "vars/radial_accel",
- "vars/tan_accel",
- "vars/initial_size",
- "vars/final_size",
- "vars/initial_angle",
- "vars/height",
- "vars/height_speed_scale",
-};
-*/
-static const char* _rand_names[Particles::VAR_MAX]={
- "rand/lifetime",
- "rand/spread",
- "rand/gravity",
- "rand/linear_vel",
- "rand/angular_vel",
- "rand/linear_accel",
- "rand/radial_accel",
- "rand/tan_accel",
- "rand/damping",
- "rand/initial_size",
- "rand/final_size",
- "rand/initial_angle",
- "rand/height",
- "rand/height_speed_scale",
-};
-
-static const Particles::Variable _var_indices[Particles::VAR_MAX]={
- Particles::VAR_LIFETIME,
- Particles::VAR_SPREAD,
- Particles::VAR_GRAVITY,
- Particles::VAR_LINEAR_VELOCITY,
- Particles::VAR_ANGULAR_VELOCITY,
- Particles::VAR_LINEAR_ACCELERATION,
- Particles::VAR_DRAG,
- Particles::VAR_TANGENTIAL_ACCELERATION,
- Particles::VAR_DAMPING,
- Particles::VAR_INITIAL_SIZE,
- Particles::VAR_FINAL_SIZE,
- Particles::VAR_INITIAL_ANGLE,
- Particles::VAR_HEIGHT,
- Particles::VAR_HEIGHT_SPEED_SCALE,
-};
-
-
-
-AABB Particles::get_aabb() const {
-
- return AABB( Vector3(-1,-1,-1), Vector3(2, 2, 2 ) );
+Rect3 Particles::get_aabb() const {
+
+ return Rect3();
}
PoolVector<Face3> Particles::get_faces(uint32_t p_usage_flags) const {
return PoolVector<Face3>();
}
+void Particles::set_emitting(bool p_emitting) {
+
+ emitting = p_emitting;
+ VS::get_singleton()->particles_set_emitting(particles, emitting);
+}
void Particles::set_amount(int p_amount) {
- ERR_FAIL_INDEX(p_amount,1024);
- amount=p_amount;
- VisualServer::get_singleton()->particles_set_amount(particles,p_amount);
+ amount = p_amount;
+ VS::get_singleton()->particles_set_amount(particles, amount);
}
-int Particles::get_amount() const {
+void Particles::set_lifetime(float p_lifetime) {
- return amount;
+ lifetime = p_lifetime;
+ VS::get_singleton()->particles_set_lifetime(particles, lifetime);
}
+void Particles::set_pre_process_time(float p_time) {
-void Particles::set_emitting(bool p_emitting) {
+ pre_process_time = p_time;
+ VS::get_singleton()->particles_set_pre_process_time(particles, pre_process_time);
+}
+void Particles::set_explosiveness_ratio(float p_ratio) {
+
+ explosiveness_ratio = p_ratio;
+ VS::get_singleton()->particles_set_explosiveness_ratio(particles, explosiveness_ratio);
+}
+void Particles::set_randomness_ratio(float p_ratio) {
- emitting=p_emitting;
- VisualServer::get_singleton()->particles_set_emitting(particles,p_emitting);
+ randomness_ratio = p_ratio;
+ VS::get_singleton()->particles_set_randomness_ratio(particles, randomness_ratio);
+}
+void Particles::set_custom_aabb(const Rect3 &p_aabb) {
+
+ custom_aabb = p_aabb;
+ VS::get_singleton()->particles_set_custom_aabb(particles, custom_aabb);
+}
+void Particles::set_gravity(const Vector3 &p_gravity) {
+
+ gravity = p_gravity;
+ VS::get_singleton()->particles_set_gravity(particles, gravity);
+}
+void Particles::set_use_local_coordinates(bool p_enable) {
- setup_timer();
+ local_coords = p_enable;
+ VS::get_singleton()->particles_set_use_local_coordinates(particles, local_coords);
}
+void Particles::set_process_material(const Ref<Material> &p_material) {
+
+ process_material = p_material;
+ RID material_rid;
+ if (process_material.is_valid())
+ material_rid = process_material->get_rid();
+ VS::get_singleton()->particles_set_process_material(particles, material_rid);
+}
+
bool Particles::is_emitting() const {
return emitting;
}
+int Particles::get_amount() const {
-void Particles::set_visibility_aabb(const AABB& p_aabb) {
+ return amount;
+}
+float Particles::get_lifetime() const {
+
+ return lifetime;
+}
+float Particles::get_pre_process_time() const {
+
+ return pre_process_time;
+}
+float Particles::get_explosiveness_ratio() const {
- visibility_aabb=p_aabb;
- VisualServer::get_singleton()->particles_set_visibility_aabb(particles,p_aabb);
- update_gizmo();
+ return explosiveness_ratio;
+}
+float Particles::get_randomness_ratio() const {
+ return randomness_ratio;
}
-AABB Particles::get_visibility_aabb() const {
+Rect3 Particles::get_custom_aabb() const {
- return visibility_aabb;
+ return custom_aabb;
}
+Vector3 Particles::get_gravity() const {
+ return gravity;
+}
+bool Particles::get_use_local_coordinates() const {
-void Particles::set_emission_points(const PoolVector<Vector3>& p_points) {
+ return local_coords;
+}
+Ref<Material> Particles::get_process_material() const {
- using_points = p_points.size();
- VisualServer::get_singleton()->particles_set_emission_points(particles,p_points);
+ return process_material;
}
-PoolVector<Vector3> Particles::get_emission_points() const {
+void Particles::set_draw_order(DrawOrder p_order) {
- if (!using_points)
- return PoolVector<Vector3>();
+ draw_order = p_order;
+ VS::get_singleton()->particles_set_draw_order(particles, VS::ParticlesDrawOrder(p_order));
+}
- return VisualServer::get_singleton()->particles_get_emission_points(particles);
+Particles::DrawOrder Particles::get_draw_order() const {
+ return draw_order;
}
-void Particles::set_emission_half_extents(const Vector3& p_half_extents) {
+void Particles::set_draw_passes(int p_count) {
- emission_half_extents=p_half_extents;
- VisualServer::get_singleton()->particles_set_emission_half_extents(particles,p_half_extents);
+ ERR_FAIL_COND(p_count < 1);
+ draw_passes.resize(p_count);
+ VS::get_singleton()->particles_set_draw_passes(particles, p_count);
+ _change_notify();
+}
+int Particles::get_draw_passes() const {
+ return draw_passes.size();
}
-Vector3 Particles::get_emission_half_extents() const {
+void Particles::set_draw_pass_mesh(int p_pass, const Ref<Mesh> &p_mesh) {
- return emission_half_extents;
+ ERR_FAIL_INDEX(p_pass, draw_passes.size());
+
+ draw_passes[p_pass] = p_mesh;
+
+ RID mesh_rid;
+ if (p_mesh.is_valid())
+ mesh_rid = p_mesh->get_rid();
+
+ VS::get_singleton()->particles_set_draw_pass_mesh(particles, p_pass, mesh_rid);
}
-void Particles::set_emission_base_velocity(const Vector3& p_base_velocity) {
+Ref<Mesh> Particles::get_draw_pass_mesh(int p_pass) const {
- emission_base_velocity=p_base_velocity;
- VisualServer::get_singleton()->particles_set_emission_base_velocity(particles,p_base_velocity);
+ ERR_FAIL_INDEX_V(p_pass, draw_passes.size(), Ref<Mesh>());
+ return draw_passes[p_pass];
}
-Vector3 Particles::get_emission_base_velocity() const {
+void Particles::set_fixed_fps(int p_count) {
+ fixed_fps = p_count;
+ VS::get_singleton()->particles_set_fixed_fps(particles, p_count);
+}
- return emission_base_velocity;
+int Particles::get_fixed_fps() const {
+ return fixed_fps;
}
-void Particles::set_gravity_normal(const Vector3& p_normal) {
+void Particles::set_fractional_delta(bool p_enable) {
+ fractional_delta = p_enable;
+ VS::get_singleton()->particles_set_fractional_delta(particles, p_enable);
+}
- gravity_normal=p_normal;
- VisualServer::get_singleton()->particles_set_gravity_normal(particles,p_normal);
+bool Particles::get_fractional_delta() const {
+ return fractional_delta;
+}
+
+void Particles::_validate_property(PropertyInfo &property) const {
+
+ if (property.name.begins_with("draw_pass_")) {
+ int index = property.name.get_slicec('_', 2).to_int() - 1;
+ if (index >= draw_passes.size()) {
+ property.usage = 0;
+ return;
+ }
+ }
}
-Vector3 Particles::get_gravity_normal() const {
+void Particles::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &Particles::set_emitting);
+ ClassDB::bind_method(D_METHOD("set_amount", "amount"), &Particles::set_amount);
+ ClassDB::bind_method(D_METHOD("set_lifetime", "secs"), &Particles::set_lifetime);
+ ClassDB::bind_method(D_METHOD("set_pre_process_time", "secs"), &Particles::set_pre_process_time);
+ ClassDB::bind_method(D_METHOD("set_explosiveness_ratio", "ratio"), &Particles::set_explosiveness_ratio);
+ ClassDB::bind_method(D_METHOD("set_randomness_ratio", "ratio"), &Particles::set_randomness_ratio);
+ ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &Particles::set_custom_aabb);
+ ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &Particles::set_gravity);
+ ClassDB::bind_method(D_METHOD("set_use_local_coordinates", "enable"), &Particles::set_use_local_coordinates);
+ ClassDB::bind_method(D_METHOD("set_fixed_fps", "fps"), &Particles::set_fixed_fps);
+ ClassDB::bind_method(D_METHOD("set_fractional_delta", "enable"), &Particles::set_fractional_delta);
+ ClassDB::bind_method(D_METHOD("set_process_material", "material:Material"), &Particles::set_process_material);
+
+ ClassDB::bind_method(D_METHOD("is_emitting"), &Particles::is_emitting);
+ ClassDB::bind_method(D_METHOD("get_amount"), &Particles::get_amount);
+ ClassDB::bind_method(D_METHOD("get_lifetime"), &Particles::get_lifetime);
+ ClassDB::bind_method(D_METHOD("get_pre_process_time"), &Particles::get_pre_process_time);
+ ClassDB::bind_method(D_METHOD("get_explosiveness_ratio"), &Particles::get_explosiveness_ratio);
+ ClassDB::bind_method(D_METHOD("get_randomness_ratio"), &Particles::get_randomness_ratio);
+ ClassDB::bind_method(D_METHOD("get_custom_aabb"), &Particles::get_custom_aabb);
+ ClassDB::bind_method(D_METHOD("get_gravity"), &Particles::get_gravity);
+ ClassDB::bind_method(D_METHOD("get_use_local_coordinates"), &Particles::get_use_local_coordinates);
+ ClassDB::bind_method(D_METHOD("get_fixed_fps"), &Particles::get_fixed_fps);
+ ClassDB::bind_method(D_METHOD("get_fractional_delta"), &Particles::get_fractional_delta);
+ ClassDB::bind_method(D_METHOD("get_process_material:Material"), &Particles::get_process_material);
+
+ ClassDB::bind_method(D_METHOD("set_draw_order", "order"), &Particles::set_draw_order);
+
+ ClassDB::bind_method(D_METHOD("get_draw_order"), &Particles::get_draw_order);
+
+ ClassDB::bind_method(D_METHOD("set_draw_passes", "passes"), &Particles::set_draw_passes);
+ ClassDB::bind_method(D_METHOD("set_draw_pass_mesh", "pass", "mesh:Mesh"), &Particles::set_draw_pass_mesh);
+
+ ClassDB::bind_method(D_METHOD("get_draw_passes"), &Particles::get_draw_passes);
+ ClassDB::bind_method(D_METHOD("get_draw_pass_mesh:Mesh", "pass"), &Particles::get_draw_pass_mesh);
+
+ ADD_GROUP("Parameters", "");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,100000,1"), "set_amount", "get_amount");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01"), "set_lifetime", "get_lifetime");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio");
+ ADD_PROPERTY(PropertyInfo(Variant::RECT3, "custom_aabb"), "set_custom_aabb", "get_custom_aabb");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity"), "set_gravity", "get_gravity");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "local_coords"), "set_use_local_coordinates", "get_use_local_coordinates");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "process_material", PROPERTY_HINT_RESOURCE_TYPE, "ParticlesMaterial,ShaderMaterial"), "set_process_material", "get_process_material");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_order", PROPERTY_HINT_ENUM, "Index,Lifetime,View Depth"), "set_draw_order", "get_draw_order");
+ ADD_GROUP("Draw Passes", "draw_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_passes", PROPERTY_HINT_RANGE, "0," + itos(MAX_DRAW_PASSES) + ",1"), "set_draw_passes", "get_draw_passes");
+ for (int i = 0; i < MAX_DRAW_PASSES; i++) {
+
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "draw_pass_" + itos(i + 1), PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_draw_pass_mesh", "get_draw_pass_mesh", i);
+ }
+
+ BIND_CONSTANT(DRAW_ORDER_INDEX);
+ BIND_CONSTANT(DRAW_ORDER_LIFETIME);
+ BIND_CONSTANT(DRAW_ORDER_VIEW_DEPTH);
+ BIND_CONSTANT(MAX_DRAW_PASSES);
+}
- return gravity_normal;
+Particles::Particles() {
+ particles = VS::get_singleton()->particles_create();
+ set_base(particles);
+ set_emitting(true);
+ set_amount(100);
+ set_lifetime(1);
+ set_fixed_fps(0);
+ set_fractional_delta(true);
+ set_pre_process_time(0);
+ set_explosiveness_ratio(0);
+ set_randomness_ratio(0);
+ set_gravity(Vector3(0, -9.8, 0));
+ set_use_local_coordinates(true);
+ set_draw_passes(1);
}
-void Particles::set_variable(Variable p_variable,float p_value) {
+Particles::~Particles() {
- ERR_FAIL_INDEX(p_variable,VAR_MAX);
- var[p_variable]=p_value;
- VisualServer::get_singleton()->particles_set_variable(particles,(VS::ParticleVariable)p_variable,p_value);
- if (p_variable==VAR_SPREAD)
- update_gizmo();
+ VS::get_singleton()->free(particles);
}
-float Particles::get_variable(Variable p_variable) const {
+//////////////////////////////////////
- ERR_FAIL_INDEX_V(p_variable,VAR_MAX,-1);
- return var[p_variable];
+Mutex *ParticlesMaterial::material_mutex = NULL;
+SelfList<ParticlesMaterial>::List ParticlesMaterial::dirty_materials;
+Map<ParticlesMaterial::MaterialKey, ParticlesMaterial::ShaderData> ParticlesMaterial::shader_map;
+ParticlesMaterial::ShaderNames *ParticlesMaterial::shader_names = NULL;
+void ParticlesMaterial::init_shaders() {
+
+#ifndef NO_THREADS
+ material_mutex = Mutex::create();
+#endif
+
+ shader_names = memnew(ShaderNames);
+
+ shader_names->spread = "spread";
+ shader_names->flatness = "flatness";
+ shader_names->initial_linear_velocity = "initial_linear_velocity";
+ shader_names->initial_angle = "initial_angle";
+ shader_names->angular_velocity = "angular_velocity";
+ shader_names->orbit_velocity = "orbit_velocity";
+ shader_names->linear_accel = "linear_accel";
+ shader_names->radial_accel = "radial_accel";
+ shader_names->tangent_accel = "tangent_accel";
+ shader_names->damping = "damping";
+ shader_names->scale = "scale";
+ shader_names->hue_variation = "hue_variation";
+ shader_names->anim_speed = "anim_speed";
+ shader_names->anim_offset = "anim_offset";
+
+ shader_names->initial_linear_velocity = "initial_linear_velocity_random";
+ shader_names->initial_angle_random = "initial_angle_random";
+ shader_names->angular_velocity_random = "angular_velocity_random";
+ shader_names->orbit_velocity_random = "orbit_velocity_random";
+ shader_names->linear_accel_random = "linear_accel_random";
+ shader_names->radial_accel_random = "radial_accel_random";
+ shader_names->tangent_accel_random = "tangent_accel_random";
+ shader_names->damping_random = "damping_random";
+ shader_names->scale_random = "scale_random";
+ shader_names->hue_variation_random = "hue_variation_random";
+ shader_names->anim_speed_random = "anim_speed_random";
+ shader_names->anim_offset_random = "anim_offset_random";
+
+ shader_names->angle_texture = "angle_texture";
+ shader_names->angular_velocity_texture = "angular_velocity_texture";
+ shader_names->orbit_velocity_texture = "orbit_velocity_texture";
+ shader_names->linear_accel_texture = "linear_accel_texture";
+ shader_names->radial_accel_texture = "radial_accel_texture";
+ shader_names->tangent_accel_texture = "tangent_accel_texture";
+ shader_names->damping_texture = "damping_texture";
+ shader_names->scale_texture = "scale_texture";
+ shader_names->hue_variation_texture = "hue_variation_texture";
+ shader_names->anim_speed_texture = "anim_speed_texture";
+ shader_names->anim_offset_texture = "anim_offset_texture";
+
+ shader_names->color = "color_value";
+ shader_names->color_ramp = "color_ramp";
+
+ shader_names->emission_sphere_radius = "emission_sphere_radius";
+ shader_names->emission_box_extents = "emission_box_extents";
+ shader_names->emission_texture_point_count = "emission_texture_point_count";
+ shader_names->emission_texture_points = "emission_texture_points";
+ shader_names->emission_texture_normal = "emission_texture_normal";
+
+ shader_names->trail_divisor = "trail_divisor";
+ shader_names->trail_size_modifier = "trail_size_modifier";
+ shader_names->trail_color_modifier = "trail_color_modifier";
}
-void Particles::set_randomness(Variable p_variable,float p_randomness) {
+void ParticlesMaterial::finish_shaders() {
- ERR_FAIL_INDEX(p_variable,VAR_MAX);
- var_random[p_variable]=p_randomness;
- VisualServer::get_singleton()->particles_set_randomness(particles,(VS::ParticleVariable)p_variable,p_randomness);
+#ifndef NO_THREADS
+ memdelete(material_mutex);
+#endif
+ memdelete(shader_names);
}
-float Particles::get_randomness(Variable p_variable) const {
- ERR_FAIL_INDEX_V(p_variable,VAR_MAX,-1);
- return var_random[p_variable];
+void ParticlesMaterial::_update_shader() {
+
+ print_line("updating shader");
+
+ dirty_materials.remove(&element);
+
+ MaterialKey mk = _compute_key();
+ if (mk.key == current_key.key)
+ return; //no update required in the end
+
+ if (shader_map.has(current_key)) {
+ shader_map[current_key].users--;
+ if (shader_map[current_key].users == 0) {
+ //deallocate shader, as it's no longer in use
+ VS::get_singleton()->free(shader_map[current_key].shader);
+ shader_map.erase(current_key);
+ }
+ }
+ current_key = mk;
+
+ if (shader_map.has(mk)) {
+
+ VS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader);
+ shader_map[mk].users++;
+ return;
+ }
+
+ //must create a shader!
+
+ String code = "shader_type particles;\n";
+
+ code += "uniform float spread;\n";
+ code += "uniform float flatness;\n";
+ code += "uniform float initial_linear_velocity;\n";
+ code += "uniform float initial_angle;\n";
+ code += "uniform float angular_velocity;\n";
+ code += "uniform float orbit_velocity;\n";
+ code += "uniform float linear_accel;\n";
+ code += "uniform float radial_accel;\n";
+ code += "uniform float tangent_accel;\n";
+ code += "uniform float damping;\n";
+ code += "uniform float scale;\n";
+ code += "uniform float hue_variation;\n";
+ code += "uniform float anim_speed;\n";
+ code += "uniform float anim_offset;\n";
+
+ code += "uniform float initial_linear_velocity_random;\n";
+ code += "uniform float initial_angle_random;\n";
+ code += "uniform float angular_velocity_random;\n";
+ code += "uniform float orbit_velocity_random;\n";
+ code += "uniform float linear_accel_random;\n";
+ code += "uniform float radial_accel_random;\n";
+ code += "uniform float tangent_accel_random;\n";
+ code += "uniform float damping_random;\n";
+ code += "uniform float scale_random;\n";
+ code += "uniform float hue_variation_random;\n";
+ code += "uniform float anim_speed_random;\n";
+ code += "uniform float anim_offset_random;\n";
+
+ code += "uniform vec4 color_value : hint_color;\n";
+
+ code += "uniform int trail_divisor;\n";
+
+ if (color_ramp.is_valid())
+ code += "uniform sampler2D color_ramp;\n";
+
+ if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid())
+ code += "uniform sampler2D linear_velocity_texture;\n";
+ if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid())
+ code += "uniform sampler2D orbit_velocity_texture;\n";
+ if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid())
+ code += "uniform sampler2D angular_velocity_texture;\n";
+ if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid())
+ code += "uniform sampler2D linear_accel_texture;\n";
+ if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid())
+ code += "uniform sampler2D radial_accel_texture;\n";
+ if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid())
+ code += "uniform sampler2D tangent_accel_texture;\n";
+ if (tex_parameters[PARAM_DAMPING].is_valid())
+ code += "uniform sampler2D damping_texture;\n";
+ if (tex_parameters[PARAM_ANGLE].is_valid())
+ code += "uniform sampler2D angle_texture;\n";
+ if (tex_parameters[PARAM_SCALE].is_valid())
+ code += "uniform sampler2D scale_texture;\n";
+ if (tex_parameters[PARAM_HUE_VARIATION].is_valid())
+ code += "uniform sampler2D hue_variation_texture;\n";
+ if (tex_parameters[PARAM_ANIM_SPEED].is_valid())
+ code += "uniform sampler2D anim_speed_texture;\n";
+ if (tex_parameters[PARAM_ANIM_OFFSET].is_valid())
+ code += "uniform sampler2D anim_offset_texture;\n";
+
+ switch (emission_shape) {
+ case EMISSION_SHAPE_POINT: {
+ //do none
+ } break;
+ case EMISSION_SHAPE_SPHERE: {
+ code += "uniform float emission_sphere_radius;\n";
+ } break;
+ case EMISSION_SHAPE_BOX: {
+ code += "uniform vec3 emission_box_extents;\n";
+ } break;
+ case EMISSION_SHAPE_DIRECTED_POINTS: {
+ code += "uniform sampler2D emission_texture_normal : hint_black;\n";
+ } //fallthrough
+ case EMISSION_SHAPE_POINTS: {
+ code += "uniform sampler2D emission_texture_points : hint_black;\n";
+ code += "uniform int emission_texture_point_count;\n";
+ } break;
+ }
+
+ if (trail_size_modifier.is_valid()) {
+ code += "uniform sampler2D trail_size_modifier;\n";
+ }
+
+ if (trail_color_modifier.is_valid()) {
+ code += "uniform sampler2D trail_color_modifier;\n";
+ }
+
+ //need a random function
+ code += "\n\n";
+ code += "float rand_from_seed(inout uint seed) {\n";
+ code += " int k;\n";
+ code += " int s = int(seed);\n";
+ code += " if (s == 0)\n";
+ code += " s = 305420679;\n";
+ code += " k = s / 127773;\n";
+ code += " s = 16807 * (s - k * 127773) - 2836 * k;\n";
+ code += " if (s < 0)\n";
+ code += " s += 2147483647;\n";
+ code += " seed = uint(s);\n";
+ code += " return float(seed % uint(65536))/65535.0;\n";
+ code += "}\n";
+ //improve seed quality
+ code += "uint hash(uint x) {\n";
+ code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n";
+ code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n";
+ code += " x = (x >> uint(16)) ^ x;\n";
+ code += " return x;\n";
+ code += "}\n";
+ code += "void vertex() {\n\n";
+ code += "\n";
+
+ code += " uint base_number=NUMBER/uint(trail_divisor);\n";
+ code += " uint alt_seed=hash(base_number+uint(1));\n";
+ code += " float angle_rand=rand_from_seed(alt_seed);\n";
+ code += " float scale_rand=rand_from_seed(alt_seed);\n";
+ code += " float hue_rot_rand=rand_from_seed(alt_seed);\n";
+ code += " float anim_offset_rand=rand_from_seed(alt_seed);\n";
+ code += "\n";
+ code += "\n";
+ code += "\n";
+ code += "\n";
+ code += " if (RESTART) {\n";
+
+ if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid())
+ code += " float tex_linear_velocity = textureLod(linear_velocity_texture,vec2(0.0,0.0),0.0).r;\n";
+ else
+ code += " float tex_linear_velocity = 0.0;\n";
+
+ if (tex_parameters[PARAM_ANGLE].is_valid())
+ code += " float tex_angle = textureLod(angle_texture,vec2(0.0,0.0),0.0).r;\n";
+ else
+ code += " float tex_angle = 0.0;\n";
+
+ if (tex_parameters[PARAM_ANIM_OFFSET].is_valid())
+ code += " float tex_anim_offset = textureLod(anim_offset_texture,vec2(0.0,0.0),0.0).r;\n";
+ else
+ code += " float tex_anim_offset = 0.0;\n";
+
+ code += " float angle1 = rand_from_seed(alt_seed)*spread*3.1416;\n";
+ code += " float angle2 = rand_from_seed(alt_seed)*20.0*3.1416; // make it more random like\n";
+ code += " vec3 rot_xz=vec3( sin(angle1), 0.0, cos(angle1) );\n";
+ code += " vec3 rot = vec3( cos(angle2)*rot_xz.x,sin(angle2)*rot_xz.x, rot_xz.z);\n";
+ code += " VELOCITY=(rot*initial_linear_velocity+rot*initial_linear_velocity_random*rand_from_seed(alt_seed));\n";
+ code += " float base_angle=(initial_angle+tex_angle)*mix(1.0,angle_rand,initial_angle_random);\n";
+ code += " CUSTOM.x=base_angle*3.1416/180.0;\n"; //angle
+ code += " CUSTOM.y=0.0;\n"; //phase
+ code += " CUSTOM.z=(anim_offset+tex_anim_offset)*mix(1.0,anim_offset_rand,anim_offset_random);\n"; //animation offset (0-1)
+ switch (emission_shape) {
+ case EMISSION_SHAPE_POINT: {
+ //do none
+ } break;
+ case EMISSION_SHAPE_SPHERE: {
+ code += " TRANSFORM[3].xyz = normalize(vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0-1.0, rand_from_seed(alt_seed) * 2.0-1.0 ))*emission_sphere_radius;\n";
+ } break;
+ case EMISSION_SHAPE_BOX: {
+ code += " TRANSFORM[3].xyz = vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0-1.0, rand_from_seed(alt_seed) * 2.0-1.0)*emission_box_extents;\n";
+ } break;
+ case EMISSION_SHAPE_POINTS:
+ case EMISSION_SHAPE_DIRECTED_POINTS: {
+ code += " int point = min(emission_texture_point_count-1,int(rand_from_seed(alt_seed) * float(emission_texture_point_count)));\n";
+ code += " ivec2 tex_size = textureSize( emission_texture_points, 0 );\n";
+ code += " ivec2 tex_ofs = ivec2( point % tex_size.x, point / tex_size.x );\n";
+ code += " TRANSFORM[3].xyz = texelFetch(emission_texture_points, tex_ofs,0).xyz;\n";
+ if (emission_shape == EMISSION_SHAPE_DIRECTED_POINTS) {
+ code += " vec3 normal = texelFetch(emission_texture_normal, tex_ofs,0).xyz;\n";
+ code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0, 1.0, 0.0);\n";
+ code += " vec3 tangent = normalize(cross(v0, normal));\n";
+ code += " vec3 bitangent = normalize(cross(tangent, normal));\n";
+ code += " VELOCITY = mat3(tangent,bitangent,normal) * VELOCITY;\n";
+ }
+ } break;
+ }
+ code += " VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY,0.0)).xyz;\n";
+ code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n";
+
+ code += " } else {\n";
+
+ code += " CUSTOM.y+=DELTA/LIFETIME;\n";
+ if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid())
+ code += " float tex_linear_velocity = textureLod(linear_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ else
+ code += " float tex_linear_velocity = 0.0;\n";
+
+ if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid())
+ code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ else
+ code += " float tex_orbit_velocity = 0.0;\n";
+
+ if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid())
+ code += " float tex_angular_velocity = textureLod(angular_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ else
+ code += " float tex_angular_velocity = 0.0;\n";
+
+ if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid())
+ code += " float tex_linear_accel = textureLod(linear_accel_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ else
+ code += " float tex_linear_accel = 0.0;\n";
+
+ if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid())
+ code += " float tex_radial_accel = textureLod(radial_accel_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ else
+ code += " float tex_radial_accel = 0.0;\n";
+
+ if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid())
+ code += " float tex_tangent_accel = textureLod(tangent_accel_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ else
+ code += " float tex_tangent_accel = 0.0;\n";
+
+ if (tex_parameters[PARAM_DAMPING].is_valid())
+ code += " float tex_damping = textureLod(damping_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ else
+ code += " float tex_damping = 0.0;\n";
+
+ if (tex_parameters[PARAM_ANGLE].is_valid())
+ code += " float tex_angle = textureLod(angle_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ else
+ code += " float tex_angle = 0.0;\n";
+
+ if (tex_parameters[PARAM_ANIM_SPEED].is_valid())
+ code += " float tex_anim_speed = textureLod(anim_speed_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ else
+ code += " float tex_anim_speed = 0.0;\n";
+
+ if (tex_parameters[PARAM_ANIM_OFFSET].is_valid())
+ code += " float tex_anim_offset = textureLod(anim_offset_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ else
+ code += " float tex_anim_offset = 0.0;\n";
+
+ code += " vec3 force = vec3(0.0); \n";
+ code += " vec3 pos = TRANSFORM[3].xyz; \n";
+ code += " //apply linear acceleration\n";
+ code += " force+=normalize(VELOCITY) * (linear_accel+tex_linear_accel)*mix(1.0,rand_from_seed(alt_seed),linear_accel_random);\n";
+ code += " //apply radial acceleration\n";
+ code += " vec3 org = vec3(0.0);\n";
+ code += " // if (!p_system->local_coordinates)\n";
+ code += " //org=p_transform.origin;\n";
+ code += " force+=normalize(pos-org) * (radial_accel+tex_radial_accel)*mix(1.0,rand_from_seed(alt_seed),radial_accel_random);\n";
+ code += " //apply tangential acceleration;\n";
+ code += " force+=normalize(cross(normalize(pos-org),normalize(GRAVITY))) * ((tangent_accel+tex_tangent_accel)*mix(1.0,rand_from_seed(alt_seed),radial_accel_random));\n";
+ code += " //apply attractor forces\n";
+ code += " VELOCITY+=force * DELTA;\n";
+ if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid())
+ code += " VELOCITY=normalize(VELOCITY)*tex_linear_velocity;\n";
+ code += " if (damping+tex_damping>0.0) {\n";
+ code += " \n";
+ code += " float v = length(VELOCITY);\n";
+ code += " float damp = (damping+tex_damping)*mix(1.0,rand_from_seed(alt_seed),damping_random);\n";
+ code += " v -= damp * DELTA;\n";
+ code += " if (v<0.0) {\n";
+ code += " VELOCITY=vec3(0.0);\n";
+ code += " } else {\n";
+ code += " VELOCITY=normalize(VELOCITY) * v;\n";
+ code += " }\n";
+ code += " }\n";
+ code += " float base_angle=(initial_angle+tex_angle)*mix(1.0,angle_rand,initial_angle_random)*3.1416/180.0;\n";
+ code += " CUSTOM.x=((base_angle+tex_angle)+CUSTOM.y*LIFETIME*(angular_velocity+tex_angular_velocity)*mix(1.0,rand_from_seed(alt_seed)*2.0-1.0,angular_velocity_random))*3.1416/180.0;\n"; //angle
+ code += " CUSTOM.z=(anim_offset+tex_anim_offset)*mix(1.0,anim_offset_rand,anim_offset_random)+CUSTOM.y*LIFETIME*(anim_speed+tex_anim_speed)*mix(1.0,rand_from_seed(alt_seed),anim_speed_random);\n"; //angle
+ code += " }\n";
+ //apply color
+ //apply hue rotation
+ if (tex_parameters[PARAM_SCALE].is_valid())
+ code += " float tex_scale = textureLod(scale_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ else
+ code += " float tex_scale = 1.0;\n";
+
+ if (tex_parameters[PARAM_HUE_VARIATION].is_valid())
+ code += " float tex_hue_variation = textureLod(hue_variation_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ else
+ code += " float tex_hue_variation = 0.0;\n";
+
+ code += " float hue_rot_angle = (hue_variation+tex_hue_variation)*3.1416*2.0*mix(1.0,hue_rot_rand*2.0-1.0,hue_variation_random);\n";
+ code += " float hue_rot_c = cos(hue_rot_angle);\n";
+ code += " float hue_rot_s = sin(hue_rot_angle);\n";
+ code += " mat4 hue_rot_mat = mat4( vec4(0.299, 0.587, 0.114, 0.0),\n";
+ code += " vec4(0.299, 0.587, 0.114, 0.0),\n";
+ code += " vec4(0.299, 0.587, 0.114, 0.0),\n";
+ code += " vec4(0.000, 0.000, 0.000, 1.0)) +\n";
+ code += " \n";
+ code += " mat4( vec4(0.701, -0.587, -0.114, 0.0),\n";
+ code += " vec4(-0.299, 0.413, -0.114, 0.0),\n";
+ code += " vec4(-0.300, -0.588, 0.886, 0.0),\n";
+ code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_c +\n";
+ code += "\n";
+ code += " mat4( vec4(0.168, 0.330, -0.497, 0.0),\n";
+ code += " vec4(-0.328, 0.035, 0.292, 0.0),\n";
+ code += " vec4(1.250, -1.050, -0.203, 0.0),\n";
+ code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s;\n";
+ if (color_ramp.is_valid()) {
+ code += " COLOR = textureLod(color_ramp,vec2(CUSTOM.y,0.0),0.0) * hue_rot_mat;\n";
+ } else {
+ code += " COLOR = color_value * hue_rot_mat;\n";
+ }
+ if (trail_color_modifier.is_valid()) {
+ code += "if (trail_divisor>1) { COLOR*=textureLod(trail_color_modifier,vec2(float(int(NUMBER)%trail_divisor)/float(trail_divisor-1),0.0),0.0); }\n";
+ }
+ code += "\n";
+ //orient particle Y towards velocity
+ if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) {
+ code += " if (length(VELOCITY)>0.0) {TRANSFORM[1].xyz=normalize(VELOCITY);} else {TRANSFORM[1].xyz=normalize(TRANSFORM[1].xyz);}\n";
+ code += " if (TRANSFORM[1].xyz==normalize(TRANSFORM[0].xyz)) {\n";
+ code += "\tTRANSFORM[0].xyz=normalize(cross(normalize(TRANSFORM[1].xyz),normalize(TRANSFORM[2].xyz)));\n";
+ code += "\tTRANSFORM[2].xyz=normalize(cross(normalize(TRANSFORM[0].xyz),normalize(TRANSFORM[1].xyz)));\n";
+ code += " } else {\n";
+ code += "\tTRANSFORM[2].xyz=normalize(cross(normalize(TRANSFORM[0].xyz),normalize(TRANSFORM[1].xyz)));\n";
+ code += "\tTRANSFORM[0].xyz=normalize(cross(normalize(TRANSFORM[1].xyz),normalize(TRANSFORM[2].xyz)));\n";
+ code += " }\n";
+ } else {
+ code += "\tTRANSFORM[0].xyz=normalize(TRANSFORM[0].xyz);\n";
+ code += "\tTRANSFORM[1].xyz=normalize(TRANSFORM[1].xyz);\n";
+ code += "\tTRANSFORM[2].xyz=normalize(TRANSFORM[2].xyz);\n";
+ }
+ //turn particle by rotation in Y
+ if (flags[FLAG_ROTATE_Y]) {
+ code += "\tTRANSFORM = TRANSFORM * mat4( vec4(cos(CUSTOM.x),0.0,-sin(CUSTOM.x),0.0), vec4(0.0,1.0,0.0,0.0),vec4(sin(CUSTOM.x),0.0,cos(CUSTOM.x),0.0),vec4(0.0,0.0,0.0,1.0));\n";
+ }
+ //scale by scale
+ code += " float base_scale=mix(scale*tex_scale,1.0,scale_random*scale_rand);\n";
+ if (trail_size_modifier.is_valid()) {
+ code += "if (trail_divisor>1) { base_scale*=textureLod(trail_size_modifier,vec2(float(int(NUMBER)%trail_divisor)/float(trail_divisor-1),0.0),0.0).r; } \n";
+ }
+
+ code += " TRANSFORM[0].xyz*=base_scale;\n";
+ code += " TRANSFORM[1].xyz*=base_scale;\n";
+ code += " TRANSFORM[2].xyz*=base_scale;\n";
+ code += "}\n";
+ code += "\n";
+
+ ShaderData shader_data;
+ shader_data.shader = VS::get_singleton()->shader_create();
+ shader_data.users = 1;
+
+ VS::get_singleton()->shader_set_code(shader_data.shader, code);
+
+ shader_map[mk] = shader_data;
+
+ VS::get_singleton()->material_set_shader(_get_material(), shader_data.shader);
}
-void Particles::set_color_phase_pos(int p_phase, float p_pos) {
+void ParticlesMaterial::flush_changes() {
- ERR_FAIL_INDEX(p_phase,VS::MAX_PARTICLE_COLOR_PHASES);
- color_phase[p_phase].pos=p_pos;
- VisualServer::get_singleton()->particles_set_color_phase_pos(particles,p_phase,p_pos);
+ if (material_mutex)
+ material_mutex->lock();
+ while (dirty_materials.first()) {
+
+ dirty_materials.first()->self()->_update_shader();
+ }
+
+ if (material_mutex)
+ material_mutex->unlock();
}
-float Particles::get_color_phase_pos(int p_phase) const {
- ERR_FAIL_INDEX_V(p_phase,VS::MAX_PARTICLE_COLOR_PHASES,-1);
- return color_phase[p_phase].pos;
+void ParticlesMaterial::_queue_shader_change() {
+
+ if (material_mutex)
+ material_mutex->lock();
+
+ print_line("queuing change");
+ if (!element.in_list()) {
+ print_line("not in list, adding");
+ dirty_materials.add(&element);
+ }
+
+ if (material_mutex)
+ material_mutex->unlock();
}
-void Particles::set_color_phase_color(int p_phase, const Color& p_color) {
+bool ParticlesMaterial::_is_shader_dirty() const {
+
+ bool dirty = false;
+
+ if (material_mutex)
+ material_mutex->lock();
+
+ dirty = element.in_list();
- ERR_FAIL_INDEX(p_phase,VS::MAX_PARTICLE_COLOR_PHASES);
- color_phase[p_phase].color=p_color;
- VisualServer::get_singleton()->particles_set_color_phase_color(particles,p_phase,p_color);
+ if (material_mutex)
+ material_mutex->unlock();
+ return dirty;
}
-Color Particles::get_color_phase_color(int p_phase) const {
- ERR_FAIL_INDEX_V(p_phase,VS::MAX_PARTICLE_COLOR_PHASES,Color());
- return color_phase[p_phase].color;
+void ParticlesMaterial::set_spread(float p_spread) {
+ spread = p_spread;
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->spread, p_spread);
}
-void Particles::set_material(const Ref<Material>& p_material) {
+float ParticlesMaterial::get_spread() const {
- material=p_material;
- if(material.is_null()) {
- VisualServer::get_singleton()->particles_set_material(particles,RID());
- } else {
- VisualServer::get_singleton()->particles_set_material(particles,material->get_rid());
+ return spread;
+}
+
+void ParticlesMaterial::set_flatness(float p_flatness) {
+
+ flatness = p_flatness;
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->flatness, p_flatness);
+}
+float ParticlesMaterial::get_flatness() const {
+
+ return flatness;
+}
+
+void ParticlesMaterial::set_param(Parameter p_param, float p_value) {
+
+ ERR_FAIL_INDEX(p_param, PARAM_MAX);
+
+ parameters[p_param] = p_value;
+
+ switch (p_param) {
+ case PARAM_INITIAL_LINEAR_VELOCITY: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_linear_velocity, p_value);
+ } break;
+ case PARAM_ANGULAR_VELOCITY: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity, p_value);
+ } break;
+ case PARAM_ORBIT_VELOCITY: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity, p_value);
+ } break;
+ case PARAM_LINEAR_ACCEL: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel, p_value);
+ } break;
+ case PARAM_RADIAL_ACCEL: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel, p_value);
+ } break;
+ case PARAM_TANGENTIAL_ACCEL: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel, p_value);
+ } break;
+ case PARAM_DAMPING: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->damping, p_value);
+ } break;
+ case PARAM_ANGLE: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_angle, p_value);
+ } break;
+ case PARAM_SCALE: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->scale, p_value);
+ } break;
+ case PARAM_HUE_VARIATION: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation, p_value);
+ } break;
+ case PARAM_ANIM_SPEED: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed, p_value);
+ } break;
+ case PARAM_ANIM_OFFSET: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset, p_value);
+ } break;
+ case PARAM_MAX: {
+ };
}
+}
+float ParticlesMaterial::get_param(Parameter p_param) const {
+
+ ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
+ return parameters[p_param];
}
-void Particles::setup_timer() {
+void ParticlesMaterial::set_param_randomness(Parameter p_param, float p_value) {
+
+ ERR_FAIL_INDEX(p_param, PARAM_MAX);
+
+ randomness[p_param] = p_value;
+
+ switch (p_param) {
+ case PARAM_INITIAL_LINEAR_VELOCITY: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_linear_velocity_random, p_value);
+ } break;
+ case PARAM_ANGULAR_VELOCITY: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity_random, p_value);
+ } break;
+ case PARAM_ORBIT_VELOCITY: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_random, p_value);
+ } break;
+ case PARAM_LINEAR_ACCEL: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel_random, p_value);
+ } break;
+ case PARAM_RADIAL_ACCEL: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel_random, p_value);
+ } break;
+ case PARAM_TANGENTIAL_ACCEL: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel_random, p_value);
+ } break;
+ case PARAM_DAMPING: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->damping_random, p_value);
+ } break;
+ case PARAM_ANGLE: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_angle_random, p_value);
+ } break;
+ case PARAM_SCALE: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_random, p_value);
+ } break;
+ case PARAM_HUE_VARIATION: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_random, p_value);
+ } break;
+ case PARAM_ANIM_SPEED: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed_random, p_value);
+ } break;
+ case PARAM_ANIM_OFFSET: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_random, p_value);
+ } break;
+ case PARAM_MAX: {
+ };
+ }
+}
+float ParticlesMaterial::get_param_randomness(Parameter p_param) const {
- if (emitting && emit_timeout > 0) {
+ ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
- timer->set_wait_time(emit_timeout);
- timer->start();
- timer->set_one_shot(true);
- };
-};
+ return randomness[p_param];
+}
-void Particles::set_emit_timeout(float p_timeout) {
+static void _adjust_curve_range(const Ref<Texture> &p_texture, float p_min, float p_max) {
- emit_timeout = p_timeout;
- setup_timer();
-};
+ Ref<CurveTexture> curve = p_texture;
+ if (!curve.is_valid())
+ return;
-float Particles::get_emit_timeout() const {
+ if (curve->get_max() == 1.0) {
+ curve->set_max(p_max);
+ }
+ if (curve->get_min() == 0.0) {
+ curve->set_min(p_min);
+ }
+}
- return emit_timeout;
-};
+void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture> &p_texture) {
+
+ ERR_FAIL_INDEX(p_param, PARAM_MAX);
+
+ tex_parameters[p_param] = p_texture;
+
+ switch (p_param) {
+ case PARAM_INITIAL_LINEAR_VELOCITY: {
+ //do none for this one
+ } break;
+ case PARAM_ANGULAR_VELOCITY: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity_texture, p_texture);
+ _adjust_curve_range(p_texture, -360, 360);
+ } break;
+ case PARAM_ORBIT_VELOCITY: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_texture, p_texture);
+ _adjust_curve_range(p_texture, -500, 500);
+ } break;
+ case PARAM_LINEAR_ACCEL: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel_texture, p_texture);
+ _adjust_curve_range(p_texture, -200, 200);
+ } break;
+ case PARAM_RADIAL_ACCEL: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel_texture, p_texture);
+ _adjust_curve_range(p_texture, -200, 200);
+ } break;
+ case PARAM_TANGENTIAL_ACCEL: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel_texture, p_texture);
+ _adjust_curve_range(p_texture, -200, 200);
+ } break;
+ case PARAM_DAMPING: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->damping_texture, p_texture);
+ _adjust_curve_range(p_texture, 0, 100);
+ } break;
+ case PARAM_ANGLE: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->angle_texture, p_texture);
+ _adjust_curve_range(p_texture, -360, 360);
+ } break;
+ case PARAM_SCALE: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_texture, p_texture);
+
+ Ref<CurveTexture> curve = p_texture;
+ if (curve.is_valid()) {
+ if (curve->get_min() == 0 && curve->get_max() == 1) {
+
+ curve->set_max(32);
+ PoolVector<Vector2> points;
+ points.push_back(Vector2(0, 1));
+ points.push_back(Vector2(1, 1));
+ curve->set_points(points);
+ }
+ }
+ } break;
+ case PARAM_HUE_VARIATION: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_texture, p_texture);
+ _adjust_curve_range(p_texture, -1, 1);
+ } break;
+ case PARAM_ANIM_SPEED: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed_texture, p_texture);
+ _adjust_curve_range(p_texture, 0, 200);
+ } break;
+ case PARAM_ANIM_OFFSET: {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_texture, p_texture);
+ } break;
+ case PARAM_MAX: {
+ };
+ }
+
+ _queue_shader_change();
+}
+Ref<Texture> ParticlesMaterial::get_param_texture(Parameter p_param) const {
-Ref<Material> Particles::get_material() const {
+ ERR_FAIL_INDEX_V(p_param, PARAM_MAX, Ref<Texture>());
- return material;
+ return tex_parameters[p_param];
}
-void Particles::set_height_from_velocity(bool p_enable) {
+void ParticlesMaterial::set_color(const Color &p_color) {
- height_from_velocity=p_enable;
- VisualServer::get_singleton()->particles_set_height_from_velocity(particles,height_from_velocity);
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->color, p_color);
+ color = p_color;
}
-bool Particles::has_height_from_velocity() const {
+Color ParticlesMaterial::get_color() const {
- return height_from_velocity;
+ return color;
}
-void Particles::set_color_phases(int p_phases) {
+void ParticlesMaterial::set_color_ramp(const Ref<Texture> &p_texture) {
- color_phase_count=p_phases;
- VisualServer::get_singleton()->particles_set_color_phases(particles,p_phases);
+ color_ramp = p_texture;
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, p_texture);
+ _queue_shader_change();
+ _change_notify();
}
-int Particles::get_color_phases() const{
+Ref<Texture> ParticlesMaterial::get_color_ramp() const {
- return color_phase_count;
+ return color_ramp;
}
-bool Particles::_can_gizmo_scale() const {
+void ParticlesMaterial::set_flag(Flags p_flag, bool p_enable) {
+ ERR_FAIL_INDEX(p_flag, FLAG_MAX);
+ flags[p_flag] = p_enable;
+ _queue_shader_change();
+}
- return false;
+bool ParticlesMaterial::get_flag(Flags p_flag) const {
+ ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
+ return flags[p_flag];
}
-void Particles::set_use_local_coordinates(bool p_use) {
+void ParticlesMaterial::set_emission_shape(EmissionShape p_shape) {
- local_coordinates=p_use;
- VisualServer::get_singleton()->particles_set_use_local_coordinates(particles,local_coordinates);
+ emission_shape = p_shape;
+ _change_notify();
+ _queue_shader_change();
}
-bool Particles::is_using_local_coordinates() const{
+void ParticlesMaterial::set_emission_sphere_radius(float p_radius) {
- return local_coordinates;
+ emission_sphere_radius = p_radius;
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_sphere_radius, p_radius);
}
+void ParticlesMaterial::set_emission_box_extents(Vector3 p_extents) {
-RES Particles::_get_gizmo_geometry() const {
+ emission_box_extents = p_extents;
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_box_extents, p_extents);
+}
- Ref<SurfaceTool> surface_tool( memnew( SurfaceTool ));
+void ParticlesMaterial::set_emission_point_texture(const Ref<Texture> &p_points) {
- Ref<FixedSpatialMaterial> mat( memnew( FixedSpatialMaterial ));
+ emission_point_texture = p_points;
+ RID texture;
+ if (p_points.is_valid())
+ texture = p_points->get_rid();
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_points, texture);
+}
- mat->set_parameter( FixedSpatialMaterial::PARAM_DIFFUSE,Color(0.0,0.6,0.7,0.2) );
- mat->set_parameter( FixedSpatialMaterial::PARAM_EMISSION,Color(0.5,0.7,0.8) );
- mat->set_blend_mode( Material::BLEND_MODE_ADD );
- mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
- //mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
+void ParticlesMaterial::set_emission_normal_texture(const Ref<Texture> &p_normals) {
+ emission_normal_texture = p_normals;
+ RID texture;
+ if (p_normals.is_valid())
+ texture = p_normals->get_rid();
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_normal, texture);
+}
- surface_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
- surface_tool->set_material(mat);
+void ParticlesMaterial::set_emission_point_count(int p_count) {
- int sides=16;
- int sections=24;
+ emission_point_count = p_count;
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_point_count, p_count);
+}
- //float len=1;
- float deg=Math::deg2rad(var[VAR_SPREAD]*180);
- if (deg==180)
- deg=179.5;
+ParticlesMaterial::EmissionShape ParticlesMaterial::get_emission_shape() const {
- Vector3 to=Vector3(0,0,-1);
+ return emission_shape;
+}
- for(int j=0;j<sections;j++) {
+float ParticlesMaterial::get_emission_sphere_radius() const {
- Vector3 p1=Matrix3(Vector3(1,0,0),deg*j/sections).xform(to);
- Vector3 p2=Matrix3(Vector3(1,0,0),deg*(j+1)/sections).xform(to);
+ return emission_sphere_radius;
+}
+Vector3 ParticlesMaterial::get_emission_box_extents() const {
- for(int i=0;i<sides;i++) {
+ return emission_box_extents;
+}
+Ref<Texture> ParticlesMaterial::get_emission_point_texture() const {
- Vector3 p1r = Matrix3(Vector3(0,0,1),Math_PI*2*float(i)/sides).xform(p1);
- Vector3 p1s = Matrix3(Vector3(0,0,1),Math_PI*2*float(i+1)/sides).xform(p1);
- Vector3 p2s = Matrix3(Vector3(0,0,1),Math_PI*2*float(i+1)/sides).xform(p2);
- Vector3 p2r = Matrix3(Vector3(0,0,1),Math_PI*2*float(i)/sides).xform(p2);
+ return emission_point_texture;
+}
+Ref<Texture> ParticlesMaterial::get_emission_normal_texture() const {
- surface_tool->add_normal(p1r.normalized());
- surface_tool->add_vertex(p1r);
- surface_tool->add_normal(p1s.normalized());
- surface_tool->add_vertex(p1s);
- surface_tool->add_normal(p2s.normalized());
- surface_tool->add_vertex(p2s);
+ return emission_normal_texture;
+}
- surface_tool->add_normal(p1r.normalized());
- surface_tool->add_vertex(p1r);
- surface_tool->add_normal(p2s.normalized());
- surface_tool->add_vertex(p2s);
- surface_tool->add_normal(p2r.normalized());
- surface_tool->add_vertex(p2r);
+int ParticlesMaterial::get_emission_point_count() const {
- if (j==sections-1) {
+ return emission_point_count;
+}
- surface_tool->add_normal(p2r.normalized());
- surface_tool->add_vertex(p2r);
- surface_tool->add_normal(p2s.normalized());
- surface_tool->add_vertex(p2s);
- surface_tool->add_normal(Vector3(0,0,1));
- surface_tool->add_vertex(Vector3());
- }
- }
- }
+void ParticlesMaterial::set_trail_divisor(int p_divisor) {
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_divisor, p_divisor);
+ trail_divisor = p_divisor;
+ _change_notify();
+}
- Ref<Mesh> mesh = surface_tool->commit();
+int ParticlesMaterial::get_trail_divisor() const {
- Ref<FixedSpatialMaterial> mat_aabb( memnew( FixedSpatialMaterial ));
+ return trail_divisor;
+}
- mat_aabb->set_parameter( FixedSpatialMaterial::PARAM_DIFFUSE,Color(0.8,0.8,0.9,0.7) );
- mat_aabb->set_line_width(3);
- mat_aabb->set_flag( Material::FLAG_UNSHADED, true );
+void ParticlesMaterial::set_trail_size_modifier(const Ref<CurveTexture> &p_trail_size_modifier) {
- surface_tool->begin(Mesh::PRIMITIVE_LINES);
- surface_tool->set_material(mat_aabb);
+ trail_size_modifier = p_trail_size_modifier;
- for(int i=0;i<12;i++) {
+ Ref<CurveTexture> curve = trail_size_modifier;
+ if (curve.is_valid()) {
+ if (curve->get_min() == 0 && curve->get_max() == 1) {
- Vector3 f,t;
- visibility_aabb.get_edge(i,f,t);
- surface_tool->add_vertex(f);
- surface_tool->add_vertex(t);
+ curve->set_max(32);
+ PoolVector<Vector2> points;
+ points.push_back(Vector2(0, 1));
+ points.push_back(Vector2(1, 1));
+ curve->set_points(points);
+ }
}
- return surface_tool->commit(mesh);
-
+ RID texture;
+ if (p_trail_size_modifier.is_valid())
+ texture = p_trail_size_modifier->get_rid();
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_size_modifier, texture);
+ _queue_shader_change();
}
+Ref<CurveTexture> ParticlesMaterial::get_trail_size_modifier() const {
-void Particles::_bind_methods() {
+ return trail_size_modifier;
+}
- ClassDB::bind_method(D_METHOD("set_amount","amount"),&Particles::set_amount);
- ClassDB::bind_method(D_METHOD("get_amount"),&Particles::get_amount);
- ClassDB::bind_method(D_METHOD("set_emitting","enabled"),&Particles::set_emitting);
- ClassDB::bind_method(D_METHOD("is_emitting"),&Particles::is_emitting);
- ClassDB::bind_method(D_METHOD("set_visibility_aabb","aabb"),&Particles::set_visibility_aabb);
- ClassDB::bind_method(D_METHOD("get_visibility_aabb"),&Particles::get_visibility_aabb);
- ClassDB::bind_method(D_METHOD("set_emission_half_extents","half_extents"),&Particles::set_emission_half_extents);
- ClassDB::bind_method(D_METHOD("get_emission_half_extents"),&Particles::get_emission_half_extents);
- ClassDB::bind_method(D_METHOD("set_emission_base_velocity","base_velocity"),&Particles::set_emission_base_velocity);
- ClassDB::bind_method(D_METHOD("get_emission_base_velocity"),&Particles::get_emission_base_velocity);
- ClassDB::bind_method(D_METHOD("set_emission_points","points"),&Particles::set_emission_points);
- ClassDB::bind_method(D_METHOD("get_emission_points"),&Particles::get_emission_points);
- ClassDB::bind_method(D_METHOD("set_gravity_normal","normal"),&Particles::set_gravity_normal);
- ClassDB::bind_method(D_METHOD("get_gravity_normal"),&Particles::get_gravity_normal);
- ClassDB::bind_method(D_METHOD("set_variable","variable","value"),&Particles::set_variable);
- ClassDB::bind_method(D_METHOD("get_variable","variable"),&Particles::get_variable);
- ClassDB::bind_method(D_METHOD("set_randomness","variable","randomness"),&Particles::set_randomness);
- ClassDB::bind_method(D_METHOD("get_randomness","variable"),&Particles::get_randomness);
- ClassDB::bind_method(D_METHOD("set_color_phase_pos","phase","pos"),&Particles::set_color_phase_pos);
- ClassDB::bind_method(D_METHOD("get_color_phase_pos","phase"),&Particles::get_color_phase_pos);
- ClassDB::bind_method(D_METHOD("set_color_phase_color","phase","color"),&Particles::set_color_phase_color);
- ClassDB::bind_method(D_METHOD("get_color_phase_color","phase"),&Particles::get_color_phase_color);
- ClassDB::bind_method(D_METHOD("set_material","material:Material"),&Particles::set_material);
- ClassDB::bind_method(D_METHOD("get_material:Material"),&Particles::get_material);
- ClassDB::bind_method(D_METHOD("set_emit_timeout","timeout"),&Particles::set_emit_timeout);
- ClassDB::bind_method(D_METHOD("get_emit_timeout"),&Particles::get_emit_timeout);
- ClassDB::bind_method(D_METHOD("set_height_from_velocity","enable"),&Particles::set_height_from_velocity);
- ClassDB::bind_method(D_METHOD("has_height_from_velocity"),&Particles::has_height_from_velocity);
- ClassDB::bind_method(D_METHOD("set_use_local_coordinates","enable"),&Particles::set_use_local_coordinates);
- ClassDB::bind_method(D_METHOD("is_using_local_coordinates"),&Particles::is_using_local_coordinates);
-
- ClassDB::bind_method(D_METHOD("set_color_phases","count"),&Particles::set_color_phases);
- ClassDB::bind_method(D_METHOD("get_color_phases"),&Particles::get_color_phases);
-
- ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material" ), "set_material", "get_material") ;
-
- ADD_PROPERTY( PropertyInfo( Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,1024,1" ), "set_amount", "get_amount") ;
- ADD_PROPERTY( PropertyInfo( Variant::BOOL, "emitting" ), "set_emitting", "is_emitting") ;
- ADD_PROPERTY( PropertyInfo( Variant::_AABB, "visibility" ), "set_visibility_aabb", "get_visibility_aabb") ;
- ADD_PROPERTY( PropertyInfo( Variant::VECTOR3, "emission_extents" ), "set_emission_half_extents", "get_emission_half_extents") ;
- ADD_PROPERTY( PropertyInfo( Variant::VECTOR3, "emission_base_velocity" ), "set_emission_base_velocity", "get_emission_base_velocity") ;
- ADD_PROPERTY( PropertyInfo( Variant::VECTOR3_ARRAY, "emission_points" ), "set_emission_points", "get_emission_points") ;
- ADD_PROPERTY( PropertyInfo( Variant::VECTOR3, "gravity_normal" ), "set_gravity_normal", "get_gravity_normal") ;
- ADD_PROPERTY( PropertyInfo( Variant::BOOL, "local_coords" ), "set_use_local_coordinates", "is_using_local_coordinates") ;
- ADD_PROPERTY( PropertyInfo( Variant::REAL, "emit_timeout",PROPERTY_HINT_RANGE,"0,256,0.01"), "set_emit_timeout", "get_emit_timeout") ;
-
-
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/lifetime", PROPERTY_HINT_RANGE,"0.1,60,0.01"), "set_variable", "get_variable", VAR_LIFETIME );
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/spread", PROPERTY_HINT_RANGE,"0,1,0.01"), "set_variable", "get_variable", VAR_SPREAD );
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/gravity", PROPERTY_HINT_RANGE,"-48,48,0.01"), "set_variable", "get_variable", VAR_GRAVITY );
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/linear_vel", PROPERTY_HINT_RANGE,"-100,100,0.01"), "set_variable", "get_variable", VAR_LINEAR_VELOCITY );
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/angular_vel", PROPERTY_HINT_RANGE,"-100,100,0.01"), "set_variable", "get_variable", VAR_ANGULAR_VELOCITY );
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/linear_accel", PROPERTY_HINT_RANGE,"-100,100,0.01"), "set_variable", "get_variable", VAR_LINEAR_ACCELERATION );
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/radial_accel", PROPERTY_HINT_RANGE,"-100,100,0.01"), "set_variable", "get_variable", VAR_DRAG );
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/tan_accel", PROPERTY_HINT_RANGE,"-100,100,0.01"), "set_variable", "get_variable", VAR_TANGENTIAL_ACCELERATION );
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/damping", PROPERTY_HINT_RANGE,"0,128,0.01"), "set_variable", "get_variable", VAR_DAMPING );
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/initial_size", PROPERTY_HINT_RANGE,"0,100,0.01"), "set_variable", "get_variable", VAR_INITIAL_SIZE );
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/final_size", PROPERTY_HINT_RANGE,"0,100,0.01"), "set_variable", "get_variable", VAR_FINAL_SIZE );
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/initial_angle",PROPERTY_HINT_RANGE,"0,1,0.01"), "set_variable", "get_variable", VAR_INITIAL_ANGLE );
- ADD_PROPERTY( PropertyInfo( Variant::BOOL, "vars/height_from_velocity"), "set_height_from_velocity", "has_height_from_velocity") ;
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/height",PROPERTY_HINT_RANGE,"0,4096,0.01"), "set_variable", "get_variable", VAR_HEIGHT);
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/height_speed_scale",PROPERTY_HINT_RANGE,"0,4096,0.01"), "set_variable", "get_variable", VAR_HEIGHT_SPEED_SCALE );
-
- for(int i=0;i<VAR_MAX;i++)
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, _rand_names[i], PROPERTY_HINT_RANGE,"-16.0,16.0,0.01"),"set_randomness", "get_randomness",_var_indices[i] );
-
-
- ADD_PROPERTY( PropertyInfo( Variant::INT, "color_phases/count",PROPERTY_HINT_RANGE,"0,4,1"), "set_color_phases", "get_color_phases");
-
- for(int i=0;i<VS::MAX_PARTICLE_COLOR_PHASES;i++) {
- String phase="phase_"+itos(i)+"/";
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, phase+"pos", PROPERTY_HINT_RANGE,"0,1,0.01"),"set_color_phase_pos","get_color_phase_pos",i );
- ADD_PROPERTYI( PropertyInfo( Variant::COLOR, phase+"color"),"set_color_phase_color","get_color_phase_color",i );
- }
+void ParticlesMaterial::set_trail_color_modifier(const Ref<GradientTexture> &p_trail_color_modifier) {
+
+ trail_color_modifier = p_trail_color_modifier;
+ RID texture;
+ if (p_trail_color_modifier.is_valid())
+ texture = p_trail_color_modifier->get_rid();
+ VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_color_modifier, texture);
+ _queue_shader_change();
+}
- BIND_CONSTANT( VAR_LIFETIME );
- BIND_CONSTANT( VAR_SPREAD );
- BIND_CONSTANT( VAR_GRAVITY );
- BIND_CONSTANT( VAR_LINEAR_VELOCITY );
- BIND_CONSTANT( VAR_ANGULAR_VELOCITY );
- BIND_CONSTANT( VAR_LINEAR_ACCELERATION );
- BIND_CONSTANT( VAR_DRAG );
- BIND_CONSTANT( VAR_TANGENTIAL_ACCELERATION );
- BIND_CONSTANT( VAR_INITIAL_SIZE );
- BIND_CONSTANT( VAR_FINAL_SIZE );
- BIND_CONSTANT( VAR_INITIAL_ANGLE );
- BIND_CONSTANT( VAR_HEIGHT );
- BIND_CONSTANT( VAR_HEIGHT_SPEED_SCALE );
- BIND_CONSTANT( VAR_MAX );
+Ref<GradientTexture> ParticlesMaterial::get_trail_color_modifier() const {
+ return trail_color_modifier;
}
-Particles::Particles() {
+void ParticlesMaterial::_validate_property(PropertyInfo &property) const {
- particles = VisualServer::get_singleton()->particles_create();
- timer = memnew(Timer);
- add_child(timer);
- emit_timeout = 0;
+ if (property.name == "color" && color_ramp.is_valid()) {
+ property.usage = 0;
+ }
- set_amount(64);
- set_emitting(true);
- set_visibility_aabb(AABB( Vector3(-4,-4,-4), Vector3(8,8,8) ) );
+ if (property.name == "emission_sphere_radius" && emission_shape != EMISSION_SHAPE_SPHERE) {
+ property.usage = 0;
+ }
- for (int i=0;i<VAR_MAX;i++) {
- set_randomness((Variable)i,0.0);
+ if (property.name == "emission_box_extents" && emission_shape != EMISSION_SHAPE_BOX) {
+ property.usage = 0;
}
- set_variable( VAR_LIFETIME, 5.0);
- set_variable( VAR_SPREAD, 0.2);
- set_variable( VAR_GRAVITY, 9.8);
- set_variable( VAR_LINEAR_VELOCITY, 0.2);
- set_variable( VAR_ANGULAR_VELOCITY, 0.0);
- set_variable( VAR_LINEAR_ACCELERATION, 0.0);
- set_variable( VAR_DRAG, 0.0);
- set_variable( VAR_TANGENTIAL_ACCELERATION, 0.0);
- set_variable( VAR_DAMPING, 0.0);
- set_variable( VAR_INITIAL_SIZE, 1.0);
- set_variable( VAR_FINAL_SIZE, 1.0);
- set_variable( VAR_INITIAL_ANGLE, 0.0);
- set_variable( VAR_HEIGHT, 1.0);
- set_variable( VAR_HEIGHT_SPEED_SCALE, 0.0);
-
- color_phase_count=0;
-
- set_color_phase_pos(0,0.0);
- set_color_phase_pos(1,1.0);
- set_color_phase_pos(2,1.0);
- set_color_phase_pos(3,1.0);
-
- set_color_phase_color(0,Color(1,1,1));
- set_color_phase_color(1,Color(0,0,0));
- set_color_phase_color(2,Color(0,0,0));
- set_color_phase_color(3,Color(0,0,0));
-
- set_gravity_normal(Vector3(0,-1.0,0));
- set_emission_half_extents(Vector3(0.1,0.1,0.1));
-
- height_from_velocity=false;
-
- Vector<Variant> pars;
- pars.push_back(false);
- timer->connect("timeout", this, "set_emitting", pars);
- set_base(particles);
- local_coordinates=false;
+ if (property.name == "emission_point_texture" && (emission_shape != EMISSION_SHAPE_POINTS && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS)) {
+ property.usage = 0;
+ }
+
+ if (property.name == "emission_normal_texture" && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS) {
+ property.usage = 0;
+ }
+
+ if (property.name == "emission_point_count" && (emission_shape != EMISSION_SHAPE_POINTS && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS)) {
+ property.usage = 0;
+ }
}
+void ParticlesMaterial::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_spread", "degrees"), &ParticlesMaterial::set_spread);
+ ClassDB::bind_method(D_METHOD("get_spread"), &ParticlesMaterial::get_spread);
+
+ ClassDB::bind_method(D_METHOD("set_flatness", "amount"), &ParticlesMaterial::set_flatness);
+ ClassDB::bind_method(D_METHOD("get_flatness"), &ParticlesMaterial::get_flatness);
+
+ ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &ParticlesMaterial::set_param);
+ ClassDB::bind_method(D_METHOD("get_param", "param"), &ParticlesMaterial::get_param);
+
+ ClassDB::bind_method(D_METHOD("set_param_randomness", "param", "randomness"), &ParticlesMaterial::set_param_randomness);
+ ClassDB::bind_method(D_METHOD("get_param_randomness", "param"), &ParticlesMaterial::get_param_randomness);
+
+ ClassDB::bind_method(D_METHOD("set_param_texture", "param", "texture"), &ParticlesMaterial::set_param_texture);
+ ClassDB::bind_method(D_METHOD("get_param_texture", "param"), &ParticlesMaterial::get_param_texture);
+
+ ClassDB::bind_method(D_METHOD("set_color", "color"), &ParticlesMaterial::set_color);
+ ClassDB::bind_method(D_METHOD("get_color"), &ParticlesMaterial::get_color);
+
+ ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp:Texture"), &ParticlesMaterial::set_color_ramp);
+ ClassDB::bind_method(D_METHOD("get_color_ramp:Texture"), &ParticlesMaterial::get_color_ramp);
+
+ ClassDB::bind_method(D_METHOD("set_flag", "flag", "enable"), &ParticlesMaterial::set_flag);
+ ClassDB::bind_method(D_METHOD("get_flag", "flag"), &ParticlesMaterial::get_flag);
+
+ ClassDB::bind_method(D_METHOD("set_emission_shape", "shape"), &ParticlesMaterial::set_emission_shape);
+ ClassDB::bind_method(D_METHOD("get_emission_shape"), &ParticlesMaterial::get_emission_shape);
+
+ ClassDB::bind_method(D_METHOD("set_emission_sphere_radius", "radius"), &ParticlesMaterial::set_emission_sphere_radius);
+ ClassDB::bind_method(D_METHOD("get_emission_sphere_radius"), &ParticlesMaterial::get_emission_sphere_radius);
+
+ ClassDB::bind_method(D_METHOD("set_emission_box_extents", "extents"), &ParticlesMaterial::set_emission_box_extents);
+ ClassDB::bind_method(D_METHOD("get_emission_box_extents"), &ParticlesMaterial::get_emission_box_extents);
+
+ ClassDB::bind_method(D_METHOD("set_emission_point_texture", "texture:Texture"), &ParticlesMaterial::set_emission_point_texture);
+ ClassDB::bind_method(D_METHOD("get_emission_point_texture:Texture"), &ParticlesMaterial::get_emission_point_texture);
+
+ ClassDB::bind_method(D_METHOD("set_emission_normal_texture", "texture:Texture"), &ParticlesMaterial::set_emission_normal_texture);
+ ClassDB::bind_method(D_METHOD("get_emission_normal_texture:Texture"), &ParticlesMaterial::get_emission_normal_texture);
+
+ ClassDB::bind_method(D_METHOD("set_emission_point_count", "point_count"), &ParticlesMaterial::set_emission_point_count);
+ ClassDB::bind_method(D_METHOD("get_emission_point_count"), &ParticlesMaterial::get_emission_point_count);
+
+ ClassDB::bind_method(D_METHOD("set_trail_divisor", "divisor"), &ParticlesMaterial::set_trail_divisor);
+ ClassDB::bind_method(D_METHOD("get_trail_divisor"), &ParticlesMaterial::get_trail_divisor);
+
+ ClassDB::bind_method(D_METHOD("set_trail_size_modifier", "texture:CurveTexture"), &ParticlesMaterial::set_trail_size_modifier);
+ ClassDB::bind_method(D_METHOD("get_trail_size_modifier:CurveTexture"), &ParticlesMaterial::get_trail_size_modifier);
+
+ ClassDB::bind_method(D_METHOD("set_trail_color_modifier", "texture:GradientTexture"), &ParticlesMaterial::set_trail_color_modifier);
+ ClassDB::bind_method(D_METHOD("get_trail_color_modifier:GradientTexture"), &ParticlesMaterial::get_trail_color_modifier);
+
+ ADD_GROUP("Trail", "trail_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "trail_divisor", PROPERTY_HINT_RANGE, "1,1000000,1"), "set_trail_divisor", "get_trail_divisor");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trail_size_modifier", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_trail_size_modifier", "get_trail_size_modifier");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trail_color_modifier", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture"), "set_trail_color_modifier", "get_trail_color_modifier");
+ ADD_GROUP("Emission Shape", "emission_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points"), "set_emission_shape", "get_emission_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01"), "set_emission_sphere_radius", "get_emission_sphere_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "emission_box_extents"), "set_emission_box_extents", "get_emission_box_extents");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_point_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_emission_point_texture", "get_emission_point_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_emission_normal_texture", "get_emission_normal_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_point_count", PROPERTY_HINT_RANGE, "0,1000000,1"), "set_emission_point_count", "get_emission_point_count");
+ ADD_GROUP("Flags", "flag_");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_flag", "get_flag", FLAG_ALIGN_Y_TO_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_rotate_y"), "set_flag", "get_flag", FLAG_ROTATE_Y);
+ ADD_GROUP("Spread", "");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness");
+ ADD_GROUP("Initial Velocity", "initial_");
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY);
+ ADD_GROUP("Angular Velocity", "angular_");
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity", PROPERTY_HINT_RANGE, "-360,360,0.01"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANGULAR_VELOCITY);
+ ADD_GROUP("Orbit Velocity", "orbit_");
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01"), "set_param", "get_param", PARAM_ORBIT_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ORBIT_VELOCITY);
+ ADD_GROUP("Linear Accel", "linear_");
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01"), "set_param", "get_param", PARAM_LINEAR_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_LINEAR_ACCEL);
+ ADD_GROUP("Radial Accel", "radial_");
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01"), "set_param", "get_param", PARAM_RADIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_RADIAL_ACCEL);
+ ADD_GROUP("Tangential Accel", "tangential_");
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_TANGENTIAL_ACCEL);
+ ADD_GROUP("Damping", "");
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param", "get_param", PARAM_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_DAMPING);
+ ADD_GROUP("Angle", "");
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1"), "set_param", "get_param", PARAM_ANGLE);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANGLE);
+ ADD_GROUP("Scale", "");
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale", PROPERTY_HINT_RANGE, "0,1000,0.01"), "set_param", "get_param", PARAM_SCALE);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_SCALE);
+ ADD_GROUP("Color", "");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture"), "set_color_ramp", "get_color_ramp");
+
+ ADD_GROUP("Hue Variation", "hue_");
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.1"), "set_param", "get_param", PARAM_HUE_VARIATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_HUE_VARIATION);
+ ADD_GROUP("Animation", "anim_");
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_SPEED);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_SPEED);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_OFFSET);
+
+ BIND_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY);
+ BIND_CONSTANT(PARAM_ANGULAR_VELOCITY);
+ BIND_CONSTANT(PARAM_ORBIT_VELOCITY);
+ BIND_CONSTANT(PARAM_LINEAR_ACCEL);
+ BIND_CONSTANT(PARAM_RADIAL_ACCEL);
+ BIND_CONSTANT(PARAM_TANGENTIAL_ACCEL);
+ BIND_CONSTANT(PARAM_DAMPING);
+ BIND_CONSTANT(PARAM_ANGLE);
+ BIND_CONSTANT(PARAM_SCALE);
+ BIND_CONSTANT(PARAM_HUE_VARIATION);
+ BIND_CONSTANT(PARAM_ANIM_SPEED);
+ BIND_CONSTANT(PARAM_ANIM_OFFSET);
+ BIND_CONSTANT(PARAM_MAX);
+
+ BIND_CONSTANT(FLAG_ALIGN_Y_TO_VELOCITY);
+ BIND_CONSTANT(FLAG_ROTATE_Y);
+ BIND_CONSTANT(FLAG_MAX);
+
+ BIND_CONSTANT(EMISSION_SHAPE_POINT);
+ BIND_CONSTANT(EMISSION_SHAPE_SPHERE);
+ BIND_CONSTANT(EMISSION_SHAPE_BOX);
+ BIND_CONSTANT(EMISSION_SHAPE_POINTS);
+ BIND_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS);
+}
-Particles::~Particles() {
+ParticlesMaterial::ParticlesMaterial()
+ : element(this) {
+
+ set_spread(45);
+ set_flatness(0);
+ set_param(PARAM_INITIAL_LINEAR_VELOCITY, 1);
+ set_param(PARAM_ORBIT_VELOCITY, 0);
+ set_param(PARAM_LINEAR_ACCEL, 0);
+ set_param(PARAM_RADIAL_ACCEL, 0);
+ set_param(PARAM_TANGENTIAL_ACCEL, 0);
+ set_param(PARAM_DAMPING, 0);
+ set_param(PARAM_ANGLE, 0);
+ set_param(PARAM_SCALE, 1);
+ set_param(PARAM_HUE_VARIATION, 0);
+ set_param(PARAM_ANIM_SPEED, 0);
+ set_param(PARAM_ANIM_OFFSET, 0);
+ set_emission_shape(EMISSION_SHAPE_POINT);
+ set_emission_sphere_radius(1);
+ set_emission_box_extents(Vector3(1, 1, 1));
+ set_trail_divisor(1);
+ emission_point_count = 1;
+
+ for (int i = 0; i < PARAM_MAX; i++) {
+ set_param_randomness(Parameter(i), 0);
+ }
+
+ for (int i = 0; i < FLAG_MAX; i++) {
+ flags[i] = false;
+ }
- VisualServer::get_singleton()->free(particles);
+ set_color(Color(1, 1, 1, 1));
+
+ current_key.key = 0;
+ current_key.invalid_key = 1;
+
+ _queue_shader_change();
}
-#endif
+ParticlesMaterial::~ParticlesMaterial() {
+}
diff --git a/scene/3d/particles.h b/scene/3d/particles.h
index 6cb1caad3a..7ca3bab4db 100644
--- a/scene/3d/particles.h
+++ b/scene/3d/particles.h
@@ -37,130 +37,336 @@
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
-#if 0
+
class Particles : public GeometryInstance {
+private:
+ GDCLASS(Particles, GeometryInstance);
+
public:
+ enum DrawOrder {
+ DRAW_ORDER_INDEX,
+ DRAW_ORDER_LIFETIME,
+ DRAW_ORDER_VIEW_DEPTH,
+ };
- enum Variable {
- VAR_LIFETIME=VS::PARTICLE_LIFETIME,
- VAR_SPREAD=VS::PARTICLE_SPREAD,
- VAR_GRAVITY=VS::PARTICLE_GRAVITY,
- VAR_LINEAR_VELOCITY=VS::PARTICLE_LINEAR_VELOCITY,
- VAR_ANGULAR_VELOCITY=VS::PARTICLE_ANGULAR_VELOCITY,
- VAR_LINEAR_ACCELERATION=VS::PARTICLE_LINEAR_ACCELERATION,
- VAR_DRAG=VS::PARTICLE_RADIAL_ACCELERATION,
- VAR_TANGENTIAL_ACCELERATION=VS::PARTICLE_TANGENTIAL_ACCELERATION,
- VAR_DAMPING=VS::PARTICLE_DAMPING,
- VAR_INITIAL_SIZE=VS::PARTICLE_INITIAL_SIZE,
- VAR_FINAL_SIZE=VS::PARTICLE_FINAL_SIZE,
- VAR_INITIAL_ANGLE=VS::PARTICLE_INITIAL_ANGLE,
- VAR_HEIGHT=VS::PARTICLE_HEIGHT,
- VAR_HEIGHT_SPEED_SCALE=VS::PARTICLE_HEIGHT_SPEED_SCALE,
- VAR_MAX=VS::PARTICLE_VAR_MAX
+ enum {
+ MAX_DRAW_PASSES = 4
};
private:
- GDCLASS( Particles, GeometryInstance );
-
RID particles;
- int amount;
bool emitting;
- float emit_timeout;
- AABB visibility_aabb;
- Vector3 gravity_normal;
- Vector3 emission_half_extents;
- bool using_points;
- float var[VAR_MAX];
- float var_random[VAR_MAX];
- bool height_from_velocity;
- Vector3 emission_base_velocity;
- bool local_coordinates;
-
- struct ColorPhase {
-
- Color color;
- float pos;
- };
-
- virtual bool _can_gizmo_scale() const;
- virtual RES _get_gizmo_geometry() const;
-
- int color_phase_count;
+ int amount;
+ float lifetime;
+ float pre_process_time;
+ float explosiveness_ratio;
+ float randomness_ratio;
+ Rect3 custom_aabb;
+ Vector3 gravity;
+ bool local_coords;
+ int fixed_fps;
+ bool fractional_delta;
- ColorPhase color_phase[4];
+ Ref<Material> process_material;
- Ref<Material> material;
+ DrawOrder draw_order;
- Timer* timer;
- void setup_timer();
+ Vector<Ref<Mesh> > draw_passes;
protected:
-
static void _bind_methods();
+ virtual void _validate_property(PropertyInfo &property) const;
public:
-
-
- AABB get_aabb() const;
+ Rect3 get_aabb() const;
PoolVector<Face3> get_faces(uint32_t p_usage_flags) const;
+ void set_emitting(bool p_emitting);
void set_amount(int p_amount);
- int get_amount() const;
+ void set_lifetime(float p_lifetime);
+ void set_pre_process_time(float p_time);
+ void set_explosiveness_ratio(float p_ratio);
+ void set_randomness_ratio(float p_ratio);
+ void set_custom_aabb(const Rect3 &p_aabb);
+ void set_gravity(const Vector3 &p_gravity);
+ void set_use_local_coordinates(bool p_enable);
+ void set_process_material(const Ref<Material> &p_material);
- void set_emitting(bool p_emitting);
bool is_emitting() const;
+ int get_amount() const;
+ float get_lifetime() const;
+ float get_pre_process_time() const;
+ float get_explosiveness_ratio() const;
+ float get_randomness_ratio() const;
+ Rect3 get_custom_aabb() const;
+ Vector3 get_gravity() const;
+ bool get_use_local_coordinates() const;
+ Ref<Material> get_process_material() const;
- void set_visibility_aabb(const AABB& p_aabb);
- AABB get_visibility_aabb() const;
+ void set_fixed_fps(int p_count);
+ int get_fixed_fps() const;
- void set_emission_half_extents(const Vector3& p_half_extents);
- Vector3 get_emission_half_extents() const;
+ void set_fractional_delta(bool p_enable);
+ bool get_fractional_delta() const;
- void set_emission_base_velocity(const Vector3& p_base_velocity);
- Vector3 get_emission_base_velocity() const;
+ void set_draw_order(DrawOrder p_order);
+ DrawOrder get_draw_order() const;
- void set_emission_points(const PoolVector<Vector3>& p_points);
- PoolVector<Vector3> get_emission_points() const;
+ void set_draw_passes(int p_count);
+ int get_draw_passes() const;
- void set_gravity_normal(const Vector3& p_normal);
- Vector3 get_gravity_normal() const;
+ void set_draw_pass_mesh(int p_pass, const Ref<Mesh> &p_mesh);
+ Ref<Mesh> get_draw_pass_mesh(int p_pass) const;
- void set_variable(Variable p_variable,float p_value);
- float get_variable(Variable p_variable) const;
+ Particles();
+ ~Particles();
+};
- void set_randomness(Variable p_variable,float p_randomness);
- float get_randomness(Variable p_variable) const;
+VARIANT_ENUM_CAST(Particles::DrawOrder)
- void set_color_phases(int p_phases);
- int get_color_phases() const;
+class ParticlesMaterial : public Material {
- void set_color_phase_pos(int p_phase, float p_pos);
- float get_color_phase_pos(int p_phase) const;
+ GDCLASS(ParticlesMaterial, Material)
- void set_color_phase_color(int p_phase, const Color& p_color);
- Color get_color_phase_color(int p_phase) const;
+public:
+ enum Parameter {
+
+ PARAM_INITIAL_LINEAR_VELOCITY,
+ PARAM_ANGULAR_VELOCITY,
+ PARAM_ORBIT_VELOCITY,
+ PARAM_LINEAR_ACCEL,
+ PARAM_RADIAL_ACCEL,
+ PARAM_TANGENTIAL_ACCEL,
+ PARAM_DAMPING,
+ PARAM_ANGLE,
+ PARAM_SCALE,
+ PARAM_HUE_VARIATION,
+ PARAM_ANIM_SPEED,
+ PARAM_ANIM_OFFSET,
+ PARAM_MAX
+ };
- void set_height_from_velocity(bool p_enable);
- bool has_height_from_velocity() const;
+ enum Flags {
+ FLAG_ALIGN_Y_TO_VELOCITY,
+ FLAG_ROTATE_Y,
+ FLAG_MAX
+ };
- void set_material(const Ref<Material>& p_material);
- Ref<Material> get_material() const;
+ enum EmissionShape {
+ EMISSION_SHAPE_POINT,
+ EMISSION_SHAPE_SPHERE,
+ EMISSION_SHAPE_BOX,
+ EMISSION_SHAPE_POINTS,
+ EMISSION_SHAPE_DIRECTED_POINTS,
+ };
- void set_emit_timeout(float p_timeout);
- float get_emit_timeout() const;
+private:
+ union MaterialKey {
+
+ struct {
+ uint32_t texture_mask : 16;
+ uint32_t texture_color : 1;
+ uint32_t flags : 2;
+ uint32_t emission_shape : 2;
+ uint32_t trail_size_texture : 1;
+ uint32_t trail_color_texture : 1;
+ uint32_t invalid_key : 1;
+ };
+
+ uint32_t key;
+
+ bool operator<(const MaterialKey &p_key) const {
+ return key < p_key.key;
+ }
+ };
- void set_use_local_coordinates(bool p_use);
- bool is_using_local_coordinates() const;
+ struct ShaderData {
+ RID shader;
+ int users;
+ };
- void start_emitting(float p_time);
+ static Map<MaterialKey, ShaderData> shader_map;
+
+ MaterialKey current_key;
+
+ _FORCE_INLINE_ MaterialKey _compute_key() const {
+
+ MaterialKey mk;
+ mk.key = 0;
+ for (int i = 0; i < PARAM_MAX; i++) {
+ if (tex_parameters[i].is_valid()) {
+ mk.texture_mask |= (1 << i);
+ }
+ }
+ for (int i = 0; i < FLAG_MAX; i++) {
+ if (flags[i]) {
+ mk.flags |= (1 << i);
+ }
+ }
+
+ mk.texture_color = color_ramp.is_valid() ? 1 : 0;
+ mk.emission_shape = emission_shape;
+ mk.trail_color_texture = trail_color_modifier.is_valid() ? 1 : 0;
+ mk.trail_size_texture = trail_size_modifier.is_valid() ? 1 : 0;
+
+ return mk;
+ }
+
+ static Mutex *material_mutex;
+ static SelfList<ParticlesMaterial>::List dirty_materials;
+
+ struct ShaderNames {
+ StringName spread;
+ StringName flatness;
+ StringName initial_linear_velocity;
+ StringName initial_angle;
+ StringName angular_velocity;
+ StringName orbit_velocity;
+ StringName linear_accel;
+ StringName radial_accel;
+ StringName tangent_accel;
+ StringName damping;
+ StringName scale;
+ StringName hue_variation;
+ StringName anim_speed;
+ StringName anim_offset;
+
+ StringName initial_linear_velocity_random;
+ StringName initial_angle_random;
+ StringName angular_velocity_random;
+ StringName orbit_velocity_random;
+ StringName linear_accel_random;
+ StringName radial_accel_random;
+ StringName tangent_accel_random;
+ StringName damping_random;
+ StringName scale_random;
+ StringName hue_variation_random;
+ StringName anim_speed_random;
+ StringName anim_offset_random;
+
+ StringName angle_texture;
+ StringName angular_velocity_texture;
+ StringName orbit_velocity_texture;
+ StringName linear_accel_texture;
+ StringName radial_accel_texture;
+ StringName tangent_accel_texture;
+ StringName damping_texture;
+ StringName scale_texture;
+ StringName hue_variation_texture;
+ StringName anim_speed_texture;
+ StringName anim_offset_texture;
+
+ StringName color;
+ StringName color_ramp;
+
+ StringName emission_sphere_radius;
+ StringName emission_box_extents;
+ StringName emission_texture_point_count;
+ StringName emission_texture_points;
+ StringName emission_texture_normal;
+
+ StringName trail_divisor;
+ StringName trail_size_modifier;
+ StringName trail_color_modifier;
+ };
+ static ShaderNames *shader_names;
- Particles();
- ~Particles();
+ SelfList<ParticlesMaterial> element;
+ void _update_shader();
+ _FORCE_INLINE_ void _queue_shader_change();
+ _FORCE_INLINE_ bool _is_shader_dirty() const;
+
+ float spread;
+ float flatness;
+
+ float parameters[PARAM_MAX];
+ float randomness[PARAM_MAX];
+
+ Ref<Texture> tex_parameters[PARAM_MAX];
+ Color color;
+ Ref<Texture> color_ramp;
+
+ bool flags[FLAG_MAX];
+
+ EmissionShape emission_shape;
+ float emission_sphere_radius;
+ Vector3 emission_box_extents;
+ Ref<Texture> emission_point_texture;
+ Ref<Texture> emission_normal_texture;
+ int emission_point_count;
+
+ int trail_divisor;
+
+ Ref<CurveTexture> trail_size_modifier;
+ Ref<GradientTexture> trail_color_modifier;
+
+ //do not save emission points here
+
+protected:
+ static void _bind_methods();
+ virtual void _validate_property(PropertyInfo &property) const;
+
+public:
+ void set_spread(float p_spread);
+ float get_spread() const;
+
+ void set_flatness(float p_flatness);
+ float get_flatness() const;
+
+ void set_param(Parameter p_param, float p_value);
+ float get_param(Parameter p_param) const;
+
+ void set_param_randomness(Parameter p_param, float p_value);
+ float get_param_randomness(Parameter p_param) const;
+
+ void set_param_texture(Parameter p_param, const Ref<Texture> &p_texture);
+ Ref<Texture> get_param_texture(Parameter p_param) const;
+
+ void set_color(const Color &p_color);
+ Color get_color() const;
+
+ void set_color_ramp(const Ref<Texture> &p_texture);
+ Ref<Texture> get_color_ramp() const;
+
+ void set_flag(Flags p_flag, bool p_enable);
+ bool get_flag(Flags p_flag) const;
+
+ void set_emission_shape(EmissionShape p_shape);
+ void set_emission_sphere_radius(float p_radius);
+ void set_emission_box_extents(Vector3 p_extents);
+ void set_emission_point_texture(const Ref<Texture> &p_points);
+ void set_emission_normal_texture(const Ref<Texture> &p_normals);
+ void set_emission_point_count(int p_count);
+
+ EmissionShape get_emission_shape() const;
+ float get_emission_sphere_radius() const;
+ Vector3 get_emission_box_extents() const;
+ Ref<Texture> get_emission_point_texture() const;
+ Ref<Texture> get_emission_normal_texture() const;
+ int get_emission_point_count() const;
+
+ void set_trail_divisor(int p_divisor);
+ int get_trail_divisor() const;
+
+ void set_trail_size_modifier(const Ref<CurveTexture> &p_trail_size_modifier);
+ Ref<CurveTexture> get_trail_size_modifier() const;
+
+ void set_trail_color_modifier(const Ref<GradientTexture> &p_trail_color_modifier);
+ Ref<GradientTexture> get_trail_color_modifier() const;
+
+ static void init_shaders();
+ static void finish_shaders();
+ static void flush_changes();
+
+ ParticlesMaterial();
+ ~ParticlesMaterial();
};
-VARIANT_ENUM_CAST( Particles::Variable );
-#endif
+VARIANT_ENUM_CAST(ParticlesMaterial::Parameter)
+VARIANT_ENUM_CAST(ParticlesMaterial::Flags)
+VARIANT_ENUM_CAST(ParticlesMaterial::EmissionShape)
+
#endif
diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp
index 1125a7a4d2..1d399a426f 100644
--- a/scene/3d/spatial.cpp
+++ b/scene/3d/spatial.cpp
@@ -220,9 +220,10 @@ void Spatial::set_transform(const Transform &p_transform) {
data.local_transform = p_transform;
data.dirty |= DIRTY_VECTORS;
- _change_notify("transform/translation");
- _change_notify("transform/rotation");
- _change_notify("transform/scale");
+ _change_notify("translation");
+ _change_notify("rotation");
+ _change_notify("rotation_deg");
+ _change_notify("scale");
_propagate_transform_changed(this);
if (data.notify_local_transform) {
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
@@ -510,22 +511,11 @@ Ref<World> Spatial::get_world() const {
return data.viewport->find_world();
}
-#ifdef TOOLS_ENABLED
-void Spatial::set_import_transform(const Transform &p_transform) {
- data.import_transform = p_transform;
-}
-
-Transform Spatial::get_import_transform() const {
-
- return data.import_transform;
-}
-#endif
-
void Spatial::_propagate_visibility_changed() {
notification(NOTIFICATION_VISIBILITY_CHANGED);
emit_signal(SceneStringNames::get_singleton()->visibility_changed);
- _change_notify("visibility/visible");
+ _change_notify("visible");
#ifdef TOOLS_ENABLED
if (data.gizmo.is_valid())
_update_gizmo();
@@ -728,9 +718,6 @@ void Spatial::_bind_methods() {
#ifdef TOOLS_ENABLED
ClassDB::bind_method(D_METHOD("_update_gizmo"), &Spatial::_update_gizmo);
- ClassDB::bind_method(D_METHOD("_set_import_transform"), &Spatial::set_import_transform);
- ClassDB::bind_method(D_METHOD("_get_import_transform"), &Spatial::get_import_transform);
- ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "_import_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_import_transform", "_get_import_transform");
#endif
ClassDB::bind_method(D_METHOD("update_gizmo"), &Spatial::update_gizmo);
diff --git a/scene/3d/spatial.h b/scene/3d/spatial.h
index e5817883dd..a322060216 100644
--- a/scene/3d/spatial.h
+++ b/scene/3d/spatial.h
@@ -94,7 +94,6 @@ class Spatial : public Node {
Ref<SpatialGizmo> gizmo;
bool gizmo_disabled;
bool gizmo_dirty;
- Transform import_transform;
#endif
} data;
@@ -188,11 +187,6 @@ public:
void hide();
bool is_visible_in_tree() const;
-#ifdef TOOLS_ENABLED
- void set_import_transform(const Transform &p_transform);
- Transform get_import_transform() const;
-#endif
-
Spatial();
~Spatial();
};
diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp
index 852881abd4..0207868f66 100644
--- a/scene/3d/visual_instance.cpp
+++ b/scene/3d/visual_instance.cpp
@@ -318,9 +318,6 @@ void GeometryInstance::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_override", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_material_override", "get_material_override");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cast_shadow", PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only"), "set_cast_shadows_setting", "get_cast_shadows_setting");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "extra_cull_margin", PROPERTY_HINT_RANGE, "0,16384,0"), "set_extra_cull_margin", "get_extra_cull_margin");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_as_billboard"), "set_flag", "get_flag", FLAG_BILLBOARD);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_as_y_billboard"), "set_flag", "get_flag", FLAG_BILLBOARD_FIX_Y);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_depth_scale"), "set_flag", "get_flag", FLAG_DEPH_SCALE);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "visible_in_all_rooms"), "set_flag", "get_flag", FLAG_VISIBLE_IN_ALL_ROOMS);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_in_baked_light"), "set_flag", "get_flag", FLAG_USE_BAKED_LIGHT);
@@ -333,9 +330,6 @@ void GeometryInstance::_bind_methods() {
//ADD_SIGNAL( MethodInfo("visibility_changed"));
BIND_CONSTANT(FLAG_CAST_SHADOW);
- BIND_CONSTANT(FLAG_BILLBOARD);
- BIND_CONSTANT(FLAG_BILLBOARD_FIX_Y);
- BIND_CONSTANT(FLAG_DEPH_SCALE);
BIND_CONSTANT(FLAG_VISIBLE_IN_ALL_ROOMS);
BIND_CONSTANT(FLAG_MAX);
diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h
index 9f1cba923f..0c7ff10052 100644
--- a/scene/3d/visual_instance.h
+++ b/scene/3d/visual_instance.h
@@ -84,9 +84,6 @@ class GeometryInstance : public VisualInstance {
public:
enum Flags {
FLAG_CAST_SHADOW = VS::INSTANCE_FLAG_CAST_SHADOW,
- FLAG_BILLBOARD = VS::INSTANCE_FLAG_BILLBOARD,
- FLAG_BILLBOARD_FIX_Y = VS::INSTANCE_FLAG_BILLBOARD_FIX_Y,
- FLAG_DEPH_SCALE = VS::INSTANCE_FLAG_DEPH_SCALE,
FLAG_VISIBLE_IN_ALL_ROOMS = VS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS,
FLAG_USE_BAKED_LIGHT = VS::INSTANCE_FLAG_USE_BAKED_LIGHT,
FLAG_MAX = VS::INSTANCE_FLAG_MAX,
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index d2f3eea721..c249d3dd64 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -1347,12 +1347,12 @@ Control::AnchorType Control::get_anchor(Margin p_margin) const {
void Control::_change_notify_margins() {
// this avoids sending the whole object data again on a change
- _change_notify("margin/left");
- _change_notify("margin/top");
- _change_notify("margin/right");
- _change_notify("margin/bottom");
- _change_notify("rect/pos");
- _change_notify("rect/size");
+ _change_notify("margin_left");
+ _change_notify("margin_top");
+ _change_notify("margin_right");
+ _change_notify("margin_bottom");
+ _change_notify("rect_pos");
+ _change_notify("rect_size");
}
void Control::set_margin(Margin p_margin, float p_value) {
@@ -2158,7 +2158,7 @@ void Control::set_rotation(float p_radians) {
data.rotation = p_radians;
update();
_notify_transform();
- _change_notify("rect/rotation");
+ _change_notify("rect_rotation");
}
float Control::get_rotation() const {
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index 35d54d9843..df8bfcf691 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -177,7 +177,18 @@ void WindowDialog::_notification(int p_what) {
Size2 size = get_size();
Ref<StyleBox> panel = get_stylebox("panel", "WindowDialog");
- panel->draw(canvas, Rect2(Point2(), size));
+ int margin_left = static_cast<int>(panel->get_margin(MARGIN_LEFT));
+ int margin_top = static_cast<int>(panel->get_margin(MARGIN_TOP));
+ int margin_right = static_cast<int>(panel->get_margin(MARGIN_RIGHT));
+ int margin_bottom = static_cast<int>(panel->get_margin(MARGIN_BOTTOM));
+
+ Rect2 rect;
+ rect.pos.x = -margin_left;
+ rect.pos.y = -margin_top;
+ rect.size.width = size.width + margin_left + margin_right;
+ rect.size.height = size.height + margin_top + margin_bottom;
+
+ panel->draw(canvas, rect);
int title_height = get_constant("title_height", "WindowDialog");
Color title_color = get_color("title_color", "WindowDialog");
diff --git a/scene/gui/patch_9_rect.cpp b/scene/gui/patch_9_rect.cpp
index d0bd45e435..e1ac2be7e6 100644
--- a/scene/gui/patch_9_rect.cpp
+++ b/scene/gui/patch_9_rect.cpp
@@ -37,27 +37,13 @@ void NinePatchRect::_notification(int p_what) {
if (texture.is_null())
return;
- Size2 s = get_size();
+ Rect2 rect = Rect2(Point2(), get_size());
+ Rect2 src_rect = region_rect;
+
+ texture->get_rect_region(rect, src_rect, rect, src_rect);
+
RID ci = get_canvas_item();
- VS::get_singleton()->canvas_item_add_nine_patch(ci, Rect2(Point2(), s), region_rect, texture->get_rid(), Vector2(margin[MARGIN_LEFT], margin[MARGIN_TOP]), Vector2(margin[MARGIN_RIGHT], margin[MARGIN_BOTTOM]), VS::NINE_PATCH_STRETCH, VS::NINE_PATCH_STRETCH, draw_center);
- //draw_texture_rect(texture,Rect2(Point2(),s),false,modulate);
-
- /*
- Vector<Point2> points;
- points.resize(4);
- points[0]=Point2(0,0);
- points[1]=Point2(s.x,0);
- points[2]=Point2(s.x,s.y);
- points[3]=Point2(0,s.y);
- Vector<Point2> uvs;
- uvs.resize(4);
- uvs[0]=Point2(0,0);
- uvs[1]=Point2(1,0);
- uvs[2]=Point2(1,1);
- uvs[3]=Point2(0,1);
-
- VisualServer::get_singleton()->canvas_item_add_primitive(ci,points,Vector<Color>(),uvs,texture->get_rid());
-*/
+ VS::get_singleton()->canvas_item_add_nine_patch(ci, rect, src_rect, texture->get_rid(), Vector2(margin[MARGIN_LEFT], margin[MARGIN_TOP]), Vector2(margin[MARGIN_RIGHT], margin[MARGIN_BOTTOM]), VS::NINE_PATCH_STRETCH, VS::NINE_PATCH_STRETCH, draw_center);
}
}
@@ -116,16 +102,16 @@ void NinePatchRect::set_patch_margin(Margin p_margin, int p_size) {
minimum_size_changed();
switch (p_margin) {
case MARGIN_LEFT:
- _change_notify("patch_margin/left");
+ _change_notify("patch_margin_left");
break;
case MARGIN_TOP:
- _change_notify("patch_margin/top");
+ _change_notify("patch_margin_top");
break;
case MARGIN_RIGHT:
- _change_notify("patch_margin/right");
+ _change_notify("patch_margin_right");
break;
case MARGIN_BOTTOM:
- _change_notify("patch_margin/bottom");
+ _change_notify("patch_margin_bottom");
break;
}
}
diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp
index f15f3a6078..626d1d9663 100644
--- a/scene/gui/range.cpp
+++ b/scene/gui/range.cpp
@@ -33,7 +33,7 @@ void Range::_value_changed_notify() {
_value_changed(shared->val);
emit_signal("value_changed", shared->val);
update();
- _change_notify("range/value");
+ _change_notify("value");
}
void Range::Shared::emit_value_changed() {
@@ -87,26 +87,26 @@ void Range::set_min(double p_min) {
shared->min = p_min;
set_value(shared->val);
- shared->emit_changed("range/min");
+ shared->emit_changed("min");
}
void Range::set_max(double p_max) {
shared->max = p_max;
set_value(shared->val);
- shared->emit_changed("range/max");
+ shared->emit_changed("max");
}
void Range::set_step(double p_step) {
shared->step = p_step;
- shared->emit_changed("range/step");
+ shared->emit_changed("step");
}
void Range::set_page(double p_page) {
shared->page = p_page;
set_value(shared->val);
- shared->emit_changed("range/page");
+ shared->emit_changed("page");
}
double Range::get_value() const {
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index 5b6f17e0f7..11d068b048 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -185,7 +185,7 @@ void SplitContainer::_resort() {
}
update();
- _change_notify("split/offset");
+ _change_notify("split_offset");
}
Size2 SplitContainer::get_minimum_size() const {
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 3b7ad910d6..7a7ce57ef7 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -812,8 +812,8 @@ void TextEdit::_notification(int p_what) {
keyword_color = *col;
}
- if (select_identifiers_enabled && hilighted_word != String()) {
- if (hilighted_word == range) {
+ if (select_identifiers_enabled && highlighted_word != String()) {
+ if (highlighted_word == range) {
underlined = true;
}
}
@@ -1463,9 +1463,9 @@ void TextEdit::_gui_input(const InputEvent &p_gui_input) {
int row, col;
_get_mouse_pos(Point2i(mb.x, mb.y), row, col);
- if (mb.mod.command && hilighted_word != String()) {
+ if (mb.mod.command && highlighted_word != String()) {
- emit_signal("symbol_lookup", hilighted_word, row, col);
+ emit_signal("symbol_lookup", highlighted_word, row, col);
return;
}
@@ -1608,13 +1608,13 @@ void TextEdit::_gui_input(const InputEvent &p_gui_input) {
if (mm.mod.command && mm.button_mask == 0) {
String new_word = get_word_at_pos(Vector2(mm.x, mm.y));
- if (new_word != hilighted_word) {
- hilighted_word = new_word;
+ if (new_word != highlighted_word) {
+ highlighted_word = new_word;
update();
}
} else {
- if (hilighted_word != String()) {
- hilighted_word = String();
+ if (highlighted_word != String()) {
+ highlighted_word = String();
update();
}
}
@@ -1655,11 +1655,11 @@ void TextEdit::_gui_input(const InputEvent &p_gui_input) {
if (k.pressed) {
- hilighted_word = get_word_at_pos(get_local_mouse_pos());
+ highlighted_word = get_word_at_pos(get_local_mouse_pos());
update();
} else {
- hilighted_word = String();
+ highlighted_word = String();
update();
}
}
@@ -3174,7 +3174,7 @@ void TextEdit::insert_text_at_cursor(const String &p_text) {
}
Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
- if (hilighted_word != String())
+ if (highlighted_word != String())
return CURSOR_POINTING_HAND;
int gutter = cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width;
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index e38d484b0d..4032cf2533 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -252,7 +252,7 @@ class TextEdit : public Control {
bool raised_from_completion;
- String hilighted_word;
+ String highlighted_word;
uint64_t last_dblclk;
diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp
index 79ee4a6f75..fb40eec463 100644
--- a/scene/main/scene_main_loop.cpp
+++ b/scene/main/scene_main_loop.cpp
@@ -374,6 +374,10 @@ void SceneTree::input_text(const String &p_text) {
root_lock--;
}
+bool SceneTree::is_input_handled() {
+ return input_handled;
+}
+
void SceneTree::input_event(const InputEvent &p_event) {
if (is_editor_hint() && (p_event.type == InputEvent::JOYPAD_MOTION || p_event.type == InputEvent::JOYPAD_BUTTON))
@@ -761,12 +765,12 @@ Ref<Material> SceneTree::get_debug_navigation_material() {
if (navigation_material.is_valid())
return navigation_material;
- Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
+ Ref<SpatialMaterial> line_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
/* line_material->set_flag(Material::FLAG_UNSHADED, true);
line_material->set_line_width(3.0);
- line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
- line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
- line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_navigation_color());*/
+ line_material->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA, true);
+ line_material->set_fixed_flag(SpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
+ line_material->set_parameter(SpatialMaterial::PARAM_DIFFUSE,get_debug_navigation_color());*/
navigation_material = line_material;
@@ -778,12 +782,12 @@ Ref<Material> SceneTree::get_debug_navigation_disabled_material() {
if (navigation_disabled_material.is_valid())
return navigation_disabled_material;
- Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
+ Ref<SpatialMaterial> line_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
/* line_material->set_flag(Material::FLAG_UNSHADED, true);
line_material->set_line_width(3.0);
- line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
- line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
- line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_navigation_disabled_color());*/
+ line_material->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA, true);
+ line_material->set_fixed_flag(SpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
+ line_material->set_parameter(SpatialMaterial::PARAM_DIFFUSE,get_debug_navigation_disabled_color());*/
navigation_disabled_material = line_material;
@@ -794,12 +798,12 @@ Ref<Material> SceneTree::get_debug_collision_material() {
if (collision_material.is_valid())
return collision_material;
- Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
+ Ref<SpatialMaterial> line_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
/*line_material->set_flag(Material::FLAG_UNSHADED, true);
line_material->set_line_width(3.0);
- line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
- line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
- line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_collisions_color());*/
+ line_material->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA, true);
+ line_material->set_fixed_flag(SpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
+ line_material->set_parameter(SpatialMaterial::PARAM_DIFFUSE,get_debug_collisions_color());*/
collision_material = line_material;
@@ -813,11 +817,11 @@ Ref<Mesh> SceneTree::get_debug_contact_mesh() {
debug_contact_mesh = Ref<Mesh>(memnew(Mesh));
- Ref<FixedSpatialMaterial> mat = memnew(FixedSpatialMaterial);
+ Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
/*mat->set_flag(Material::FLAG_UNSHADED,true);
mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
- mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true);
- mat->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_collision_contact_color());*/
+ mat->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA,true);
+ mat->set_parameter(SpatialMaterial::PARAM_DIFFUSE,get_debug_collision_contact_color());*/
Vector3 diamond[6] = {
Vector3(-1, 0, 0),
@@ -2153,6 +2157,7 @@ void SceneTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pause", "enable"), &SceneTree::set_pause);
ClassDB::bind_method(D_METHOD("is_paused"), &SceneTree::is_paused);
ClassDB::bind_method(D_METHOD("set_input_as_handled"), &SceneTree::set_input_as_handled);
+ ClassDB::bind_method(D_METHOD("is_input_handled"), &SceneTree::is_input_handled);
ClassDB::bind_method(D_METHOD("create_timer:SceneTreeTimer", "time_sec", "pause_mode_process"), &SceneTree::create_timer, DEFVAL(true));
diff --git a/scene/main/scene_main_loop.h b/scene/main/scene_main_loop.h
index fadf77e30f..47220b9b63 100644
--- a/scene/main/scene_main_loop.h
+++ b/scene/main/scene_main_loop.h
@@ -350,6 +350,7 @@ public:
void quit();
void set_input_as_handled();
+ bool is_input_handled();
_FORCE_INLINE_ float get_fixed_process_time() const { return fixed_process_time; }
_FORCE_INLINE_ float get_idle_process_time() const { return idle_process_time; }
diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp
index 2263e82312..aeb72a6d1e 100755
--- a/scene/main/timer.cpp
+++ b/scene/main/timer.cpp
@@ -50,8 +50,7 @@ void Timer::_notification(int p_what) {
if (time_left < 0) {
if (!one_shot)
- //time_left=wait_time+time_left;
- time_left = wait_time;
+ time_left += wait_time;
else
stop();
@@ -66,8 +65,7 @@ void Timer::_notification(int p_what) {
if (time_left < 0) {
if (!one_shot)
- //time_left = wait_time + time_left;
- time_left = wait_time;
+ time_left += wait_time;
else
stop();
emit_signal("timeout");
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 06dae328f4..de00033a3b 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -423,7 +423,7 @@ void register_scene_types() {
ClassDB::register_class<GIProbeData>();
ClassDB::register_class<AnimationTreePlayer>();
ClassDB::register_class<Portal>();
- //ClassDB::register_type<Particles>();
+ ClassDB::register_class<Particles>();
ClassDB::register_class<Position3D>();
ClassDB::register_class<Quad>();
ClassDB::register_class<NavigationMeshInstance>();
@@ -471,7 +471,8 @@ void register_scene_types() {
ClassDB::register_class<MeshLibrary>();
AcceptDialog::set_swap_ok_cancel(GLOBAL_DEF("gui/common/swap_ok_cancel", bool(OS::get_singleton()->get_swap_ok_cancel())));
- ClassDB::register_class<CanvasItemMaterial>();
+ ClassDB::register_class<Shader>();
+ ClassDB::register_class<ShaderMaterial>();
ClassDB::register_virtual_class<CanvasItem>();
ClassDB::register_class<Node2D>();
ClassDB::register_class<Particles2D>();
@@ -519,21 +520,22 @@ void register_scene_types() {
/* REGISTER RESOURCES */
ClassDB::register_virtual_class<Shader>();
- //ClassDB::register_virtual_type<ShaderGraph>();
- ClassDB::register_class<CanvasItemShader>();
-//ClassDB::register_type<CanvasItemShaderGraph>();
#ifndef _3D_DISABLED
ClassDB::register_class<Mesh>();
+ ClassDB::register_class<QuadMesh>();
ClassDB::register_virtual_class<Material>();
- ClassDB::register_class<FixedSpatialMaterial>();
- SceneTree::add_idle_callback(FixedSpatialMaterial::flush_changes);
- FixedSpatialMaterial::init_shaders();
+ ClassDB::register_class<SpatialMaterial>();
+ ClassDB::add_compatibility_class("FixedSpatialMaterial", "SpatialMaterial");
+ SceneTree::add_idle_callback(SpatialMaterial::flush_changes);
+ SpatialMaterial::init_shaders();
+
+ ClassDB::register_class<ParticlesMaterial>();
+ SceneTree::add_idle_callback(ParticlesMaterial::flush_changes);
+ ParticlesMaterial::init_shaders();
+
//ClassDB::register_type<ShaderMaterial>();
ClassDB::register_class<RoomBounds>();
- //ClassDB::register_type<MaterialShaderGraph>();
- ClassDB::register_class<SpatialShader>();
- ClassDB::register_class<ParticlesShader>();
ClassDB::register_class<MultiMesh>();
ClassDB::register_class<MeshLibrary>();
@@ -564,6 +566,8 @@ void register_scene_types() {
ClassDB::register_class<ImageTexture>();
ClassDB::register_class<AtlasTexture>();
ClassDB::register_class<LargeTexture>();
+ ClassDB::register_class<CurveTexture>();
+ ClassDB::register_class<GradientTexture>();
ClassDB::register_class<CubeMap>();
ClassDB::register_class<Animation>();
ClassDB::register_virtual_class<Font>();
@@ -651,6 +655,7 @@ void unregister_scene_types() {
memdelete(resource_loader_text);
}
- FixedSpatialMaterial::finish_shaders();
+ SpatialMaterial::finish_shaders();
+ ParticlesMaterial::finish_shaders();
SceneStringNames::free();
}
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 60490d70ca..50f535fde9 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -120,7 +120,7 @@ static Ref<Texture> make_icon(T p_src) {
}
static Ref<Shader> make_shader(const char *vertex_code, const char *fragment_code, const char *lighting_code) {
- Ref<Shader> shader = (memnew(Shader(Shader::MODE_CANVAS_ITEM)));
+ Ref<Shader> shader = (memnew(Shader()));
//shader->set_code(vertex_code, fragment_code, lighting_code);
return shader;
@@ -544,7 +544,7 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
t->set_font("title_font", "WindowDialog", large_font);
t->set_color("title_color", "WindowDialog", Color(0, 0, 0));
- t->set_constant("title_height", "WindowDialog", 18 * scale);
+ t->set_constant("title_height", "WindowDialog", 20 * scale);
t->set_icon("close", "WindowDialog", make_icon(close_png));
t->set_icon("close_hilite", "WindowDialog", make_icon(close_hl_png));
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 410f4962fa..407357ea67 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -44,14 +44,132 @@ Material::~Material() {
VisualServer::get_singleton()->free(material);
}
+///////////////////////////////////
+
+bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
+
+ if (p_name == SceneStringNames::get_singleton()->shader_shader) {
+ set_shader(p_value);
+ return true;
+ } else {
+
+ if (shader.is_valid()) {
+
+ StringName pr = shader->remap_param(p_name);
+ if (!pr) {
+ String n = p_name;
+ if (n.find("param/") == 0) { //backwards compatibility
+ pr = n.substr(6, n.length());
+ }
+ }
+ if (pr) {
+ VisualServer::get_singleton()->material_set_param(_get_material(), pr, p_value);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const {
+
+ if (p_name == SceneStringNames::get_singleton()->shader_shader) {
+
+ r_ret = get_shader();
+ return true;
+
+ } else {
+
+ if (shader.is_valid()) {
+
+ StringName pr = shader->remap_param(p_name);
+ if (pr) {
+ r_ret = VisualServer::get_singleton()->material_get_param(_get_material(), pr);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const {
+
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "shader/shader", PROPERTY_HINT_RESOURCE_TYPE, "Shader,ShaderGraph"));
+
+ if (!shader.is_null()) {
+
+ shader->get_param_list(p_list);
+ }
+}
+
+void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) {
+
+ shader = p_shader;
+
+ RID rid;
+ if (shader.is_valid())
+ rid = shader->get_rid();
+
+ VS::get_singleton()->material_set_shader(_get_material(), rid);
+ _change_notify(); //properties for shader exposed
+ emit_changed();
+}
+
+Ref<Shader> ShaderMaterial::get_shader() const {
+
+ return shader;
+}
+
+void ShaderMaterial::set_shader_param(const StringName &p_param, const Variant &p_value) {
+
+ VS::get_singleton()->material_set_param(_get_material(), p_param, p_value);
+}
+
+Variant ShaderMaterial::get_shader_param(const StringName &p_param) const {
+
+ return VS::get_singleton()->material_get_param(_get_material(), p_param);
+}
+
+void ShaderMaterial::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_shader", "shader:Shader"), &ShaderMaterial::set_shader);
+ ClassDB::bind_method(D_METHOD("get_shader:Shader"), &ShaderMaterial::get_shader);
+ ClassDB::bind_method(D_METHOD("set_shader_param", "param", "value"), &ShaderMaterial::set_shader_param);
+ ClassDB::bind_method(D_METHOD("get_shader_param", "param"), &ShaderMaterial::get_shader_param);
+}
+
+void ShaderMaterial::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
+
+ String f = p_function.operator String();
+ if ((f == "get_shader_param" || f == "set_shader_param") && p_idx == 0) {
+
+ if (shader.is_valid()) {
+ List<PropertyInfo> pl;
+ shader->get_param_list(&pl);
+ for (List<PropertyInfo>::Element *E = pl.front(); E; E = E->next()) {
+ r_options->push_back("\"" + E->get().name.replace_first("shader_param/", "") + "\"");
+ }
+ }
+ }
+ Resource::get_argument_options(p_function, p_idx, r_options);
+}
+
+ShaderMaterial::ShaderMaterial() {
+}
+
+ShaderMaterial::~ShaderMaterial() {
+}
+
/////////////////////////////////
-Mutex *FixedSpatialMaterial::material_mutex = NULL;
-SelfList<FixedSpatialMaterial>::List FixedSpatialMaterial::dirty_materials;
-Map<FixedSpatialMaterial::MaterialKey, FixedSpatialMaterial::ShaderData> FixedSpatialMaterial::shader_map;
-FixedSpatialMaterial::ShaderNames *FixedSpatialMaterial::shader_names = NULL;
+Mutex *SpatialMaterial::material_mutex = NULL;
+SelfList<SpatialMaterial>::List SpatialMaterial::dirty_materials;
+Map<SpatialMaterial::MaterialKey, SpatialMaterial::ShaderData> SpatialMaterial::shader_map;
+SpatialMaterial::ShaderNames *SpatialMaterial::shader_names = NULL;
-void FixedSpatialMaterial::init_shaders() {
+void SpatialMaterial::init_shaders() {
#ifndef NO_THREADS
material_mutex = Mutex::create();
@@ -81,6 +199,10 @@ void FixedSpatialMaterial::init_shaders() {
shader_names->uv2_scale = "uv2_scale";
shader_names->uv2_offset = "uv2_offset";
+ shader_names->particle_h_frames = "particle_h_frames";
+ shader_names->particle_v_frames = "particle_v_frames";
+ shader_names->particles_anim_loop = "particles_anim_loop";
+
shader_names->texture_names[TEXTURE_ALBEDO] = "texture_albedo";
shader_names->texture_names[TEXTURE_SPECULAR] = "texture_specular";
shader_names->texture_names[TEXTURE_EMISSION] = "texture_emission";
@@ -98,7 +220,7 @@ void FixedSpatialMaterial::init_shaders() {
shader_names->texture_names[TEXTURE_DETAIL_NORMAL] = "texture_detail_normal";
}
-void FixedSpatialMaterial::finish_shaders() {
+void SpatialMaterial::finish_shaders() {
#ifndef NO_THREADS
memdelete(material_mutex);
@@ -107,7 +229,7 @@ void FixedSpatialMaterial::finish_shaders() {
memdelete(shader_names);
}
-void FixedSpatialMaterial::_update_shader() {
+void SpatialMaterial::_update_shader() {
dirty_materials.remove(&element);
@@ -135,7 +257,7 @@ void FixedSpatialMaterial::_update_shader() {
//must create a shader!
- String code = "render_mode ";
+ String code = "shader_type spatial;\nrender_mode ";
switch (blend_mode) {
case BLEND_MODE_MIX: code += "blend_mix"; break;
case BLEND_MODE_ADD: code += "blend_add"; break;
@@ -180,6 +302,11 @@ void FixedSpatialMaterial::_update_shader() {
code += "uniform vec2 uv1_offset;\n";
code += "uniform vec2 uv2_scale;\n";
code += "uniform vec2 uv2_offset;\n";
+ if (billboard_mode == BILLBOARD_PARTICLES) {
+ code += "uniform int particles_anim_h_frames;\n";
+ code += "uniform int particles_anim_v_frames;\n";
+ code += "uniform bool particles_anim_loop;\n";
+ }
if (features[FEATURE_EMISSION]) {
@@ -235,6 +362,58 @@ void FixedSpatialMaterial::_update_shader() {
code += "\tPOINT_SIZE=point_size;\n";
}
code += "\tUV=UV*uv1_scale+uv1_offset;\n";
+
+ switch (billboard_mode) {
+ case BILLBOARD_DISABLED: {
+
+ } break;
+ case BILLBOARD_ENABLED: {
+
+ code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],CAMERA_MATRIX[1],CAMERA_MATRIX[2],WORLD_MATRIX[3]);\n";
+ } break;
+ case BILLBOARD_FIXED_Y: {
+ code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],WORLD_MATRIX[1],vec4(normalize(cross(CAMERA_MATRIX[0].xyz,WORLD_MATRIX[1].xyz)),0.0),WORLD_MATRIX[3]);\n";
+ } break;
+ case BILLBOARD_PARTICLES: {
+
+ //make billboard
+ code += "\tmat4 mat_world = mat4(normalize(CAMERA_MATRIX[0])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[1])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[2])*length(WORLD_MATRIX[2]),WORLD_MATRIX[3]);\n";
+ //rotate by rotation
+ code += "\tmat_world = mat_world * mat4( vec4(cos(INSTANCE_CUSTOM.x),-sin(INSTANCE_CUSTOM.x),0.0,0.0), vec4(sin(INSTANCE_CUSTOM.x),cos(INSTANCE_CUSTOM.x),0.0,0.0),vec4(0.0,0.0,1.0,0.0),vec4(0.0,0.0,0.0,1.0));\n";
+ //set modelview
+ code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat_world;\n";
+
+ //handle animation
+ code += "\tint particle_total_frames = particles_anim_h_frames * particles_anim_v_frames;\n";
+ code += "\tint particle_frame = int(INSTANCE_CUSTOM.y * float(particle_total_frames));\n";
+ code += "\tif (particles_anim_loop) particle_frame=clamp(particle_frame,0,particle_total_frames-1); else particle_frame=abs(particle_frame)%particle_total_frames;\n";
+ //code += "\tUV /= vec2(float(particles_anim_h_frames),float(particles_anim_v_frames));\n";
+ //code += "\tUV+= UV * vec2(float(particle_frame % particles_anim_h_frames),float(particle_frame / particles_anim_v_frames));\n";
+ //handle rotation
+ // code += "\tmat4 rotation = mat4("
+
+ } break;
+ }
+
+ if (flags[FLAG_FIXED_SIZE]) {
+
+ code += "\tif (PROJECTION_MATRIX[3][3] != 0.0) {\n";
+ //orthogonal matrix, try to do about the same
+ //with viewport size
+ code += "\t\tfloat h = abs(1.0 / (2.0 * PROJECTION_MATRIX[1][1]));\n";
+ code += "\t\tfloat sc = (h * 2.0); //consistent with Y-fov\n";
+ code += "\t\tMODELVIEW_MATRIX[0]*=sc;\n";
+ code += "\t\tMODELVIEW_MATRIX[1]*=sc;\n";
+ code += "\t\tMODELVIEW_MATRIX[2]*=sc;\n";
+ code += "\t} else {\n";
+ //just scale by depth
+ code += "\t\tfloat sc = -(MODELVIEW_MATRIX)[3].z;\n";
+ code += "\t\tMODELVIEW_MATRIX[0]*=sc;\n";
+ code += "\t\tMODELVIEW_MATRIX[1]*=sc;\n";
+ code += "\t\tMODELVIEW_MATRIX[2]*=sc;\n";
+ code += "\t}\n";
+ }
+
if (detail_uv == DETAIL_UV_2) {
code += "\tUV2=UV2*uv2_scale+uv2_offset;\n";
}
@@ -336,7 +515,7 @@ void FixedSpatialMaterial::_update_shader() {
code += "}\n";
ShaderData shader_data;
- shader_data.shader = VS::get_singleton()->shader_create(VS::SHADER_SPATIAL);
+ shader_data.shader = VS::get_singleton()->shader_create();
shader_data.users = 1;
VS::get_singleton()->shader_set_code(shader_data.shader, code);
@@ -346,7 +525,7 @@ void FixedSpatialMaterial::_update_shader() {
VS::get_singleton()->material_set_shader(_get_material(), shader_data.shader);
}
-void FixedSpatialMaterial::flush_changes() {
+void SpatialMaterial::flush_changes() {
if (material_mutex)
material_mutex->lock();
@@ -360,7 +539,7 @@ void FixedSpatialMaterial::flush_changes() {
material_mutex->unlock();
}
-void FixedSpatialMaterial::_queue_shader_change() {
+void SpatialMaterial::_queue_shader_change() {
if (material_mutex)
material_mutex->lock();
@@ -373,7 +552,7 @@ void FixedSpatialMaterial::_queue_shader_change() {
material_mutex->unlock();
}
-bool FixedSpatialMaterial::_is_shader_dirty() const {
+bool SpatialMaterial::_is_shader_dirty() const {
bool dirty = false;
@@ -387,187 +566,187 @@ bool FixedSpatialMaterial::_is_shader_dirty() const {
return dirty;
}
-void FixedSpatialMaterial::set_albedo(const Color &p_albedo) {
+void SpatialMaterial::set_albedo(const Color &p_albedo) {
albedo = p_albedo;
VS::get_singleton()->material_set_param(_get_material(), shader_names->albedo, p_albedo);
}
-Color FixedSpatialMaterial::get_albedo() const {
+Color SpatialMaterial::get_albedo() const {
return albedo;
}
-void FixedSpatialMaterial::set_specular_mode(SpecularMode p_mode) {
+void SpatialMaterial::set_specular_mode(SpecularMode p_mode) {
specular_mode = p_mode;
_change_notify();
_queue_shader_change();
}
-FixedSpatialMaterial::SpecularMode FixedSpatialMaterial::get_specular_mode() const {
+SpatialMaterial::SpecularMode SpatialMaterial::get_specular_mode() const {
return specular_mode;
}
-void FixedSpatialMaterial::set_specular(const Color &p_specular) {
+void SpatialMaterial::set_specular(const Color &p_specular) {
specular = p_specular;
VS::get_singleton()->material_set_param(_get_material(), shader_names->specular, p_specular);
}
-Color FixedSpatialMaterial::get_specular() const {
+Color SpatialMaterial::get_specular() const {
return specular;
}
-void FixedSpatialMaterial::set_roughness(float p_roughness) {
+void SpatialMaterial::set_roughness(float p_roughness) {
roughness = p_roughness;
VS::get_singleton()->material_set_param(_get_material(), shader_names->roughness, p_roughness);
}
-float FixedSpatialMaterial::get_roughness() const {
+float SpatialMaterial::get_roughness() const {
return roughness;
}
-void FixedSpatialMaterial::set_metalness(float p_metalness) {
+void SpatialMaterial::set_metalness(float p_metalness) {
metalness = p_metalness;
VS::get_singleton()->material_set_param(_get_material(), shader_names->metalness, p_metalness);
}
-float FixedSpatialMaterial::get_metalness() const {
+float SpatialMaterial::get_metalness() const {
return metalness;
}
-void FixedSpatialMaterial::set_emission(const Color &p_emission) {
+void SpatialMaterial::set_emission(const Color &p_emission) {
emission = p_emission;
VS::get_singleton()->material_set_param(_get_material(), shader_names->emission, p_emission);
}
-Color FixedSpatialMaterial::get_emission() const {
+Color SpatialMaterial::get_emission() const {
return emission;
}
-void FixedSpatialMaterial::set_emission_energy(float p_emission_energy) {
+void SpatialMaterial::set_emission_energy(float p_emission_energy) {
emission_energy = p_emission_energy;
VS::get_singleton()->material_set_param(_get_material(), shader_names->emission_energy, p_emission_energy);
}
-float FixedSpatialMaterial::get_emission_energy() const {
+float SpatialMaterial::get_emission_energy() const {
return emission_energy;
}
-void FixedSpatialMaterial::set_normal_scale(float p_normal_scale) {
+void SpatialMaterial::set_normal_scale(float p_normal_scale) {
normal_scale = p_normal_scale;
VS::get_singleton()->material_set_param(_get_material(), shader_names->normal_scale, p_normal_scale);
}
-float FixedSpatialMaterial::get_normal_scale() const {
+float SpatialMaterial::get_normal_scale() const {
return normal_scale;
}
-void FixedSpatialMaterial::set_rim(float p_rim) {
+void SpatialMaterial::set_rim(float p_rim) {
rim = p_rim;
VS::get_singleton()->material_set_param(_get_material(), shader_names->rim, p_rim);
}
-float FixedSpatialMaterial::get_rim() const {
+float SpatialMaterial::get_rim() const {
return rim;
}
-void FixedSpatialMaterial::set_rim_tint(float p_rim_tint) {
+void SpatialMaterial::set_rim_tint(float p_rim_tint) {
rim_tint = p_rim_tint;
VS::get_singleton()->material_set_param(_get_material(), shader_names->rim_tint, p_rim_tint);
}
-float FixedSpatialMaterial::get_rim_tint() const {
+float SpatialMaterial::get_rim_tint() const {
return rim_tint;
}
-void FixedSpatialMaterial::set_clearcoat(float p_clearcoat) {
+void SpatialMaterial::set_clearcoat(float p_clearcoat) {
clearcoat = p_clearcoat;
VS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat, p_clearcoat);
}
-float FixedSpatialMaterial::get_clearcoat() const {
+float SpatialMaterial::get_clearcoat() const {
return clearcoat;
}
-void FixedSpatialMaterial::set_clearcoat_gloss(float p_clearcoat_gloss) {
+void SpatialMaterial::set_clearcoat_gloss(float p_clearcoat_gloss) {
clearcoat_gloss = p_clearcoat_gloss;
VS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat_gloss, p_clearcoat_gloss);
}
-float FixedSpatialMaterial::get_clearcoat_gloss() const {
+float SpatialMaterial::get_clearcoat_gloss() const {
return clearcoat_gloss;
}
-void FixedSpatialMaterial::set_anisotropy(float p_anisotropy) {
+void SpatialMaterial::set_anisotropy(float p_anisotropy) {
anisotropy = p_anisotropy;
VS::get_singleton()->material_set_param(_get_material(), shader_names->anisotropy, p_anisotropy);
}
-float FixedSpatialMaterial::get_anisotropy() const {
+float SpatialMaterial::get_anisotropy() const {
return anisotropy;
}
-void FixedSpatialMaterial::set_height_scale(float p_height_scale) {
+void SpatialMaterial::set_height_scale(float p_height_scale) {
height_scale = p_height_scale;
VS::get_singleton()->material_set_param(_get_material(), shader_names->height_scale, p_height_scale);
}
-float FixedSpatialMaterial::get_height_scale() const {
+float SpatialMaterial::get_height_scale() const {
return height_scale;
}
-void FixedSpatialMaterial::set_subsurface_scattering_strength(float p_subsurface_scattering_strength) {
+void SpatialMaterial::set_subsurface_scattering_strength(float p_subsurface_scattering_strength) {
subsurface_scattering_strength = p_subsurface_scattering_strength;
VS::get_singleton()->material_set_param(_get_material(), shader_names->subsurface_scattering_strength, subsurface_scattering_strength);
}
-float FixedSpatialMaterial::get_subsurface_scattering_strength() const {
+float SpatialMaterial::get_subsurface_scattering_strength() const {
return subsurface_scattering_strength;
}
-void FixedSpatialMaterial::set_refraction(float p_refraction) {
+void SpatialMaterial::set_refraction(float p_refraction) {
refraction = p_refraction;
VS::get_singleton()->material_set_param(_get_material(), shader_names->refraction, refraction);
}
-float FixedSpatialMaterial::get_refraction() const {
+float SpatialMaterial::get_refraction() const {
return refraction;
}
-void FixedSpatialMaterial::set_refraction_roughness(float p_refraction_roughness) {
+void SpatialMaterial::set_refraction_roughness(float p_refraction_roughness) {
refraction_roughness = p_refraction_roughness;
VS::get_singleton()->material_set_param(_get_material(), shader_names->refraction_roughness, refraction_roughness);
}
-float FixedSpatialMaterial::get_refraction_roughness() const {
+float SpatialMaterial::get_refraction_roughness() const {
return refraction_roughness;
}
-void FixedSpatialMaterial::set_detail_uv(DetailUV p_detail_uv) {
+void SpatialMaterial::set_detail_uv(DetailUV p_detail_uv) {
if (detail_uv == p_detail_uv)
return;
@@ -575,12 +754,12 @@ void FixedSpatialMaterial::set_detail_uv(DetailUV p_detail_uv) {
detail_uv = p_detail_uv;
_queue_shader_change();
}
-FixedSpatialMaterial::DetailUV FixedSpatialMaterial::get_detail_uv() const {
+SpatialMaterial::DetailUV SpatialMaterial::get_detail_uv() const {
return detail_uv;
}
-void FixedSpatialMaterial::set_blend_mode(BlendMode p_mode) {
+void SpatialMaterial::set_blend_mode(BlendMode p_mode) {
if (blend_mode == p_mode)
return;
@@ -588,22 +767,22 @@ void FixedSpatialMaterial::set_blend_mode(BlendMode p_mode) {
blend_mode = p_mode;
_queue_shader_change();
}
-FixedSpatialMaterial::BlendMode FixedSpatialMaterial::get_blend_mode() const {
+SpatialMaterial::BlendMode SpatialMaterial::get_blend_mode() const {
return blend_mode;
}
-void FixedSpatialMaterial::set_detail_blend_mode(BlendMode p_mode) {
+void SpatialMaterial::set_detail_blend_mode(BlendMode p_mode) {
detail_blend_mode = p_mode;
_queue_shader_change();
}
-FixedSpatialMaterial::BlendMode FixedSpatialMaterial::get_detail_blend_mode() const {
+SpatialMaterial::BlendMode SpatialMaterial::get_detail_blend_mode() const {
return detail_blend_mode;
}
-void FixedSpatialMaterial::set_depth_draw_mode(DepthDrawMode p_mode) {
+void SpatialMaterial::set_depth_draw_mode(DepthDrawMode p_mode) {
if (depth_draw_mode == p_mode)
return;
@@ -611,12 +790,12 @@ void FixedSpatialMaterial::set_depth_draw_mode(DepthDrawMode p_mode) {
depth_draw_mode = p_mode;
_queue_shader_change();
}
-FixedSpatialMaterial::DepthDrawMode FixedSpatialMaterial::get_depth_draw_mode() const {
+SpatialMaterial::DepthDrawMode SpatialMaterial::get_depth_draw_mode() const {
return depth_draw_mode;
}
-void FixedSpatialMaterial::set_cull_mode(CullMode p_mode) {
+void SpatialMaterial::set_cull_mode(CullMode p_mode) {
if (cull_mode == p_mode)
return;
@@ -624,12 +803,12 @@ void FixedSpatialMaterial::set_cull_mode(CullMode p_mode) {
cull_mode = p_mode;
_queue_shader_change();
}
-FixedSpatialMaterial::CullMode FixedSpatialMaterial::get_cull_mode() const {
+SpatialMaterial::CullMode SpatialMaterial::get_cull_mode() const {
return cull_mode;
}
-void FixedSpatialMaterial::set_diffuse_mode(DiffuseMode p_mode) {
+void SpatialMaterial::set_diffuse_mode(DiffuseMode p_mode) {
if (diffuse_mode == p_mode)
return;
@@ -637,12 +816,12 @@ void FixedSpatialMaterial::set_diffuse_mode(DiffuseMode p_mode) {
diffuse_mode = p_mode;
_queue_shader_change();
}
-FixedSpatialMaterial::DiffuseMode FixedSpatialMaterial::get_diffuse_mode() const {
+SpatialMaterial::DiffuseMode SpatialMaterial::get_diffuse_mode() const {
return diffuse_mode;
}
-void FixedSpatialMaterial::set_flag(Flags p_flag, bool p_enabled) {
+void SpatialMaterial::set_flag(Flags p_flag, bool p_enabled) {
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
@@ -653,13 +832,13 @@ void FixedSpatialMaterial::set_flag(Flags p_flag, bool p_enabled) {
_queue_shader_change();
}
-bool FixedSpatialMaterial::get_flag(Flags p_flag) const {
+bool SpatialMaterial::get_flag(Flags p_flag) const {
ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
return flags[p_flag];
}
-void FixedSpatialMaterial::set_feature(Feature p_feature, bool p_enabled) {
+void SpatialMaterial::set_feature(Feature p_feature, bool p_enabled) {
ERR_FAIL_INDEX(p_feature, FEATURE_MAX);
if (features[p_feature] == p_enabled)
@@ -670,13 +849,13 @@ void FixedSpatialMaterial::set_feature(Feature p_feature, bool p_enabled) {
_queue_shader_change();
}
-bool FixedSpatialMaterial::get_feature(Feature p_feature) const {
+bool SpatialMaterial::get_feature(Feature p_feature) const {
ERR_FAIL_INDEX_V(p_feature, FEATURE_MAX, false);
return features[p_feature];
}
-void FixedSpatialMaterial::set_texture(TextureParam p_param, const Ref<Texture> &p_texture) {
+void SpatialMaterial::set_texture(TextureParam p_param, const Ref<Texture> &p_texture) {
ERR_FAIL_INDEX(p_param, TEXTURE_MAX);
textures[p_param] = p_texture;
@@ -684,19 +863,19 @@ void FixedSpatialMaterial::set_texture(TextureParam p_param, const Ref<Texture>
VS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid);
}
-Ref<Texture> FixedSpatialMaterial::get_texture(TextureParam p_param) const {
+Ref<Texture> SpatialMaterial::get_texture(TextureParam p_param) const {
ERR_FAIL_INDEX_V(p_param, TEXTURE_MAX, Ref<Texture>());
return textures[p_param];
}
-void FixedSpatialMaterial::_validate_feature(const String &text, Feature feature, PropertyInfo &property) const {
+void SpatialMaterial::_validate_feature(const String &text, Feature feature, PropertyInfo &property) const {
if (property.name.begins_with(text) && property.name != text + "_enabled" && !features[feature]) {
property.usage = 0;
}
}
-void FixedSpatialMaterial::_validate_property(PropertyInfo &property) const {
+void SpatialMaterial::_validate_property(PropertyInfo &property) const {
_validate_feature("normal", FEATURE_NORMAL_MAPPING, property);
_validate_feature("emission", FEATURE_EMISSION, property);
_validate_feature("rim", FEATURE_RIM, property);
@@ -714,187 +893,253 @@ void FixedSpatialMaterial::_validate_property(PropertyInfo &property) const {
if (property.name == "specular/metalness" && specular_mode == SPECULAR_MODE_SPECULAR) {
property.usage = 0;
}
+
+ if (property.name.begins_with("particles_anim_") && billboard_mode != BILLBOARD_PARTICLES) {
+ property.usage = 0;
+ }
}
-void FixedSpatialMaterial::set_line_width(float p_line_width) {
+void SpatialMaterial::set_line_width(float p_line_width) {
line_width = p_line_width;
VS::get_singleton()->material_set_line_width(_get_material(), line_width);
}
-float FixedSpatialMaterial::get_line_width() const {
+float SpatialMaterial::get_line_width() const {
return line_width;
}
-void FixedSpatialMaterial::set_point_size(float p_point_size) {
+void SpatialMaterial::set_point_size(float p_point_size) {
point_size = p_point_size;
VS::get_singleton()->material_set_param(_get_material(), shader_names->point_size, p_point_size);
}
-float FixedSpatialMaterial::get_point_size() const {
+float SpatialMaterial::get_point_size() const {
return point_size;
}
-void FixedSpatialMaterial::set_uv1_scale(const Vector2 &p_scale) {
+void SpatialMaterial::set_uv1_scale(const Vector2 &p_scale) {
uv1_scale = p_scale;
VS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_scale, p_scale);
}
-Vector2 FixedSpatialMaterial::get_uv1_scale() const {
+Vector2 SpatialMaterial::get_uv1_scale() const {
return uv1_scale;
}
-void FixedSpatialMaterial::set_uv1_offset(const Vector2 &p_offset) {
+void SpatialMaterial::set_uv1_offset(const Vector2 &p_offset) {
uv1_offset = p_offset;
VS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_offset, p_offset);
}
-Vector2 FixedSpatialMaterial::get_uv1_offset() const {
+Vector2 SpatialMaterial::get_uv1_offset() const {
return uv1_offset;
}
-void FixedSpatialMaterial::set_uv2_scale(const Vector2 &p_scale) {
+void SpatialMaterial::set_uv2_scale(const Vector2 &p_scale) {
uv2_scale = p_scale;
VS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_scale, p_scale);
}
-Vector2 FixedSpatialMaterial::get_uv2_scale() const {
+Vector2 SpatialMaterial::get_uv2_scale() const {
return uv2_scale;
}
-void FixedSpatialMaterial::set_uv2_offset(const Vector2 &p_offset) {
+void SpatialMaterial::set_uv2_offset(const Vector2 &p_offset) {
uv2_offset = p_offset;
VS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_offset, p_offset);
}
-Vector2 FixedSpatialMaterial::get_uv2_offset() const {
+Vector2 SpatialMaterial::get_uv2_offset() const {
return uv2_offset;
}
-void FixedSpatialMaterial::_bind_methods() {
+void SpatialMaterial::set_billboard_mode(BillboardMode p_mode) {
+
+ billboard_mode = p_mode;
+ _queue_shader_change();
+ _change_notify();
+}
+
+SpatialMaterial::BillboardMode SpatialMaterial::get_billboard_mode() const {
+
+ return billboard_mode;
+}
+
+void SpatialMaterial::set_particles_anim_h_frames(int p_frames) {
+
+ particles_anim_h_frames = p_frames;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->particle_h_frames, p_frames);
+}
+
+int SpatialMaterial::get_particles_anim_h_frames() const {
+
+ return particles_anim_h_frames;
+}
+void SpatialMaterial::set_particles_anim_v_frames(int p_frames) {
+
+ particles_anim_v_frames = p_frames;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->particle_v_frames, p_frames);
+}
+
+int SpatialMaterial::get_particles_anim_v_frames() const {
- ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &FixedSpatialMaterial::set_albedo);
- ClassDB::bind_method(D_METHOD("get_albedo"), &FixedSpatialMaterial::get_albedo);
+ return particles_anim_v_frames;
+}
- ClassDB::bind_method(D_METHOD("set_specular_mode", "specular_mode"), &FixedSpatialMaterial::set_specular_mode);
- ClassDB::bind_method(D_METHOD("get_specular_mode"), &FixedSpatialMaterial::get_specular_mode);
+void SpatialMaterial::set_particles_anim_loop(int p_frames) {
- ClassDB::bind_method(D_METHOD("set_specular", "specular"), &FixedSpatialMaterial::set_specular);
- ClassDB::bind_method(D_METHOD("get_specular"), &FixedSpatialMaterial::get_specular);
+ particles_anim_loop = p_frames;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, p_frames);
+}
- ClassDB::bind_method(D_METHOD("set_metalness", "metalness"), &FixedSpatialMaterial::set_metalness);
- ClassDB::bind_method(D_METHOD("get_metalness"), &FixedSpatialMaterial::get_metalness);
+int SpatialMaterial::get_particles_anim_loop() const {
- ClassDB::bind_method(D_METHOD("set_roughness", "roughness"), &FixedSpatialMaterial::set_roughness);
- ClassDB::bind_method(D_METHOD("get_roughness"), &FixedSpatialMaterial::get_roughness);
+ return particles_anim_loop;
+}
- ClassDB::bind_method(D_METHOD("set_emission", "emission"), &FixedSpatialMaterial::set_emission);
- ClassDB::bind_method(D_METHOD("get_emission"), &FixedSpatialMaterial::get_emission);
+void SpatialMaterial::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_emission_energy", "emission_energy"), &FixedSpatialMaterial::set_emission_energy);
- ClassDB::bind_method(D_METHOD("get_emission_energy"), &FixedSpatialMaterial::get_emission_energy);
+ ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &SpatialMaterial::set_albedo);
+ ClassDB::bind_method(D_METHOD("get_albedo"), &SpatialMaterial::get_albedo);
- ClassDB::bind_method(D_METHOD("set_normal_scale", "normal_scale"), &FixedSpatialMaterial::set_normal_scale);
- ClassDB::bind_method(D_METHOD("get_normal_scale"), &FixedSpatialMaterial::get_normal_scale);
+ ClassDB::bind_method(D_METHOD("set_specular_mode", "specular_mode"), &SpatialMaterial::set_specular_mode);
+ ClassDB::bind_method(D_METHOD("get_specular_mode"), &SpatialMaterial::get_specular_mode);
- ClassDB::bind_method(D_METHOD("set_rim", "rim"), &FixedSpatialMaterial::set_rim);
- ClassDB::bind_method(D_METHOD("get_rim"), &FixedSpatialMaterial::get_rim);
+ ClassDB::bind_method(D_METHOD("set_specular", "specular"), &SpatialMaterial::set_specular);
+ ClassDB::bind_method(D_METHOD("get_specular"), &SpatialMaterial::get_specular);
- ClassDB::bind_method(D_METHOD("set_rim_tint", "rim_tint"), &FixedSpatialMaterial::set_rim_tint);
- ClassDB::bind_method(D_METHOD("get_rim_tint"), &FixedSpatialMaterial::get_rim_tint);
+ ClassDB::bind_method(D_METHOD("set_metalness", "metalness"), &SpatialMaterial::set_metalness);
+ ClassDB::bind_method(D_METHOD("get_metalness"), &SpatialMaterial::get_metalness);
- ClassDB::bind_method(D_METHOD("set_clearcoat", "clearcoat"), &FixedSpatialMaterial::set_clearcoat);
- ClassDB::bind_method(D_METHOD("get_clearcoat"), &FixedSpatialMaterial::get_clearcoat);
+ ClassDB::bind_method(D_METHOD("set_roughness", "roughness"), &SpatialMaterial::set_roughness);
+ ClassDB::bind_method(D_METHOD("get_roughness"), &SpatialMaterial::get_roughness);
- ClassDB::bind_method(D_METHOD("set_clearcoat_gloss", "clearcoat_gloss"), &FixedSpatialMaterial::set_clearcoat_gloss);
- ClassDB::bind_method(D_METHOD("get_clearcoat_gloss"), &FixedSpatialMaterial::get_clearcoat_gloss);
+ ClassDB::bind_method(D_METHOD("set_emission", "emission"), &SpatialMaterial::set_emission);
+ ClassDB::bind_method(D_METHOD("get_emission"), &SpatialMaterial::get_emission);
- ClassDB::bind_method(D_METHOD("set_anisotropy", "anisotropy"), &FixedSpatialMaterial::set_anisotropy);
- ClassDB::bind_method(D_METHOD("get_anisotropy"), &FixedSpatialMaterial::get_anisotropy);
+ ClassDB::bind_method(D_METHOD("set_emission_energy", "emission_energy"), &SpatialMaterial::set_emission_energy);
+ ClassDB::bind_method(D_METHOD("get_emission_energy"), &SpatialMaterial::get_emission_energy);
- ClassDB::bind_method(D_METHOD("set_height_scale", "height_scale"), &FixedSpatialMaterial::set_height_scale);
- ClassDB::bind_method(D_METHOD("get_height_scale"), &FixedSpatialMaterial::get_height_scale);
+ ClassDB::bind_method(D_METHOD("set_normal_scale", "normal_scale"), &SpatialMaterial::set_normal_scale);
+ ClassDB::bind_method(D_METHOD("get_normal_scale"), &SpatialMaterial::get_normal_scale);
- ClassDB::bind_method(D_METHOD("set_subsurface_scattering_strength", "strength"), &FixedSpatialMaterial::set_subsurface_scattering_strength);
- ClassDB::bind_method(D_METHOD("get_subsurface_scattering_strength"), &FixedSpatialMaterial::get_subsurface_scattering_strength);
+ ClassDB::bind_method(D_METHOD("set_rim", "rim"), &SpatialMaterial::set_rim);
+ ClassDB::bind_method(D_METHOD("get_rim"), &SpatialMaterial::get_rim);
- ClassDB::bind_method(D_METHOD("set_refraction", "refraction"), &FixedSpatialMaterial::set_refraction);
- ClassDB::bind_method(D_METHOD("get_refraction"), &FixedSpatialMaterial::get_refraction);
+ ClassDB::bind_method(D_METHOD("set_rim_tint", "rim_tint"), &SpatialMaterial::set_rim_tint);
+ ClassDB::bind_method(D_METHOD("get_rim_tint"), &SpatialMaterial::get_rim_tint);
- ClassDB::bind_method(D_METHOD("set_refraction_roughness", "refraction_roughness"), &FixedSpatialMaterial::set_refraction_roughness);
- ClassDB::bind_method(D_METHOD("get_refraction_roughness"), &FixedSpatialMaterial::get_refraction_roughness);
+ ClassDB::bind_method(D_METHOD("set_clearcoat", "clearcoat"), &SpatialMaterial::set_clearcoat);
+ ClassDB::bind_method(D_METHOD("get_clearcoat"), &SpatialMaterial::get_clearcoat);
- ClassDB::bind_method(D_METHOD("set_line_width", "line_width"), &FixedSpatialMaterial::set_line_width);
- ClassDB::bind_method(D_METHOD("get_line_width"), &FixedSpatialMaterial::get_line_width);
+ ClassDB::bind_method(D_METHOD("set_clearcoat_gloss", "clearcoat_gloss"), &SpatialMaterial::set_clearcoat_gloss);
+ ClassDB::bind_method(D_METHOD("get_clearcoat_gloss"), &SpatialMaterial::get_clearcoat_gloss);
- ClassDB::bind_method(D_METHOD("set_point_size", "point_size"), &FixedSpatialMaterial::set_point_size);
- ClassDB::bind_method(D_METHOD("get_point_size"), &FixedSpatialMaterial::get_point_size);
+ ClassDB::bind_method(D_METHOD("set_anisotropy", "anisotropy"), &SpatialMaterial::set_anisotropy);
+ ClassDB::bind_method(D_METHOD("get_anisotropy"), &SpatialMaterial::get_anisotropy);
- ClassDB::bind_method(D_METHOD("set_detail_uv", "detail_uv"), &FixedSpatialMaterial::set_detail_uv);
- ClassDB::bind_method(D_METHOD("get_detail_uv"), &FixedSpatialMaterial::get_detail_uv);
+ ClassDB::bind_method(D_METHOD("set_height_scale", "height_scale"), &SpatialMaterial::set_height_scale);
+ ClassDB::bind_method(D_METHOD("get_height_scale"), &SpatialMaterial::get_height_scale);
- ClassDB::bind_method(D_METHOD("set_blend_mode", "blend_mode"), &FixedSpatialMaterial::set_blend_mode);
- ClassDB::bind_method(D_METHOD("get_blend_mode"), &FixedSpatialMaterial::get_blend_mode);
+ ClassDB::bind_method(D_METHOD("set_subsurface_scattering_strength", "strength"), &SpatialMaterial::set_subsurface_scattering_strength);
+ ClassDB::bind_method(D_METHOD("get_subsurface_scattering_strength"), &SpatialMaterial::get_subsurface_scattering_strength);
- ClassDB::bind_method(D_METHOD("set_depth_draw_mode", "depth_draw_mode"), &FixedSpatialMaterial::set_depth_draw_mode);
- ClassDB::bind_method(D_METHOD("get_depth_draw_mode"), &FixedSpatialMaterial::get_depth_draw_mode);
+ ClassDB::bind_method(D_METHOD("set_refraction", "refraction"), &SpatialMaterial::set_refraction);
+ ClassDB::bind_method(D_METHOD("get_refraction"), &SpatialMaterial::get_refraction);
- ClassDB::bind_method(D_METHOD("set_cull_mode", "cull_mode"), &FixedSpatialMaterial::set_cull_mode);
- ClassDB::bind_method(D_METHOD("get_cull_mode"), &FixedSpatialMaterial::get_cull_mode);
+ ClassDB::bind_method(D_METHOD("set_refraction_roughness", "refraction_roughness"), &SpatialMaterial::set_refraction_roughness);
+ ClassDB::bind_method(D_METHOD("get_refraction_roughness"), &SpatialMaterial::get_refraction_roughness);
- ClassDB::bind_method(D_METHOD("set_diffuse_mode", "diffuse_mode"), &FixedSpatialMaterial::set_diffuse_mode);
- ClassDB::bind_method(D_METHOD("get_diffuse_mode"), &FixedSpatialMaterial::get_diffuse_mode);
+ ClassDB::bind_method(D_METHOD("set_line_width", "line_width"), &SpatialMaterial::set_line_width);
+ ClassDB::bind_method(D_METHOD("get_line_width"), &SpatialMaterial::get_line_width);
- ClassDB::bind_method(D_METHOD("set_flag", "flag", "enable"), &FixedSpatialMaterial::set_flag);
- ClassDB::bind_method(D_METHOD("get_flag"), &FixedSpatialMaterial::get_flag);
+ ClassDB::bind_method(D_METHOD("set_point_size", "point_size"), &SpatialMaterial::set_point_size);
+ ClassDB::bind_method(D_METHOD("get_point_size"), &SpatialMaterial::get_point_size);
- ClassDB::bind_method(D_METHOD("set_feature", "feature", "enable"), &FixedSpatialMaterial::set_feature);
- ClassDB::bind_method(D_METHOD("get_feature", "feature"), &FixedSpatialMaterial::get_feature);
+ ClassDB::bind_method(D_METHOD("set_detail_uv", "detail_uv"), &SpatialMaterial::set_detail_uv);
+ ClassDB::bind_method(D_METHOD("get_detail_uv"), &SpatialMaterial::get_detail_uv);
- ClassDB::bind_method(D_METHOD("set_texture", "param:Texture", "texture"), &FixedSpatialMaterial::set_texture);
- ClassDB::bind_method(D_METHOD("get_texture:Texture", "param:Texture"), &FixedSpatialMaterial::get_texture);
+ ClassDB::bind_method(D_METHOD("set_blend_mode", "blend_mode"), &SpatialMaterial::set_blend_mode);
+ ClassDB::bind_method(D_METHOD("get_blend_mode"), &SpatialMaterial::get_blend_mode);
- ClassDB::bind_method(D_METHOD("set_detail_blend_mode", "detail_blend_mode"), &FixedSpatialMaterial::set_detail_blend_mode);
- ClassDB::bind_method(D_METHOD("get_detail_blend_mode"), &FixedSpatialMaterial::get_detail_blend_mode);
+ ClassDB::bind_method(D_METHOD("set_depth_draw_mode", "depth_draw_mode"), &SpatialMaterial::set_depth_draw_mode);
+ ClassDB::bind_method(D_METHOD("get_depth_draw_mode"), &SpatialMaterial::get_depth_draw_mode);
- ClassDB::bind_method(D_METHOD("set_uv1_scale", "scale"), &FixedSpatialMaterial::set_uv1_scale);
- ClassDB::bind_method(D_METHOD("get_uv1_scale"), &FixedSpatialMaterial::get_uv1_scale);
+ ClassDB::bind_method(D_METHOD("set_cull_mode", "cull_mode"), &SpatialMaterial::set_cull_mode);
+ ClassDB::bind_method(D_METHOD("get_cull_mode"), &SpatialMaterial::get_cull_mode);
- ClassDB::bind_method(D_METHOD("set_uv1_offset", "offset"), &FixedSpatialMaterial::set_uv1_offset);
- ClassDB::bind_method(D_METHOD("get_uv1_offset"), &FixedSpatialMaterial::get_uv1_offset);
+ ClassDB::bind_method(D_METHOD("set_diffuse_mode", "diffuse_mode"), &SpatialMaterial::set_diffuse_mode);
+ ClassDB::bind_method(D_METHOD("get_diffuse_mode"), &SpatialMaterial::get_diffuse_mode);
- ClassDB::bind_method(D_METHOD("set_uv2_scale", "scale"), &FixedSpatialMaterial::set_uv2_scale);
- ClassDB::bind_method(D_METHOD("get_uv2_scale"), &FixedSpatialMaterial::get_uv2_scale);
+ ClassDB::bind_method(D_METHOD("set_flag", "flag", "enable"), &SpatialMaterial::set_flag);
+ ClassDB::bind_method(D_METHOD("get_flag"), &SpatialMaterial::get_flag);
- ClassDB::bind_method(D_METHOD("set_uv2_offset", "offset"), &FixedSpatialMaterial::set_uv2_offset);
- ClassDB::bind_method(D_METHOD("get_uv2_offset"), &FixedSpatialMaterial::get_uv2_offset);
+ ClassDB::bind_method(D_METHOD("set_feature", "feature", "enable"), &SpatialMaterial::set_feature);
+ ClassDB::bind_method(D_METHOD("get_feature", "feature"), &SpatialMaterial::get_feature);
+
+ ClassDB::bind_method(D_METHOD("set_texture", "param:Texture", "texture"), &SpatialMaterial::set_texture);
+ ClassDB::bind_method(D_METHOD("get_texture:Texture", "param:Texture"), &SpatialMaterial::get_texture);
+
+ ClassDB::bind_method(D_METHOD("set_detail_blend_mode", "detail_blend_mode"), &SpatialMaterial::set_detail_blend_mode);
+ ClassDB::bind_method(D_METHOD("get_detail_blend_mode"), &SpatialMaterial::get_detail_blend_mode);
+
+ ClassDB::bind_method(D_METHOD("set_uv1_scale", "scale"), &SpatialMaterial::set_uv1_scale);
+ ClassDB::bind_method(D_METHOD("get_uv1_scale"), &SpatialMaterial::get_uv1_scale);
+
+ ClassDB::bind_method(D_METHOD("set_uv1_offset", "offset"), &SpatialMaterial::set_uv1_offset);
+ ClassDB::bind_method(D_METHOD("get_uv1_offset"), &SpatialMaterial::get_uv1_offset);
+
+ ClassDB::bind_method(D_METHOD("set_uv2_scale", "scale"), &SpatialMaterial::set_uv2_scale);
+ ClassDB::bind_method(D_METHOD("get_uv2_scale"), &SpatialMaterial::get_uv2_scale);
+
+ ClassDB::bind_method(D_METHOD("set_uv2_offset", "offset"), &SpatialMaterial::set_uv2_offset);
+ ClassDB::bind_method(D_METHOD("get_uv2_offset"), &SpatialMaterial::get_uv2_offset);
+
+ ClassDB::bind_method(D_METHOD("set_billboard_mode", "mode"), &SpatialMaterial::set_billboard_mode);
+ ClassDB::bind_method(D_METHOD("get_billboard_mode"), &SpatialMaterial::get_billboard_mode);
+
+ ClassDB::bind_method(D_METHOD("set_particles_anim_h_frames", "frames"), &SpatialMaterial::set_particles_anim_h_frames);
+ ClassDB::bind_method(D_METHOD("get_particles_anim_h_frames"), &SpatialMaterial::get_particles_anim_h_frames);
+
+ ClassDB::bind_method(D_METHOD("set_particles_anim_v_frames", "frames"), &SpatialMaterial::set_particles_anim_v_frames);
+ ClassDB::bind_method(D_METHOD("get_particles_anim_v_frames"), &SpatialMaterial::get_particles_anim_v_frames);
+
+ ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "frames"), &SpatialMaterial::set_particles_anim_loop);
+ ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &SpatialMaterial::get_particles_anim_loop);
ADD_GROUP("Flags", "flags_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_transparent"), "set_feature", "get_feature", FEATURE_TRANSPARENT);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_unshaded"), "set_flag", "get_flag", FLAG_UNSHADED);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_on_top"), "set_flag", "get_flag", FLAG_ONTOP);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_use_point_size"), "set_flag", "get_flag", FLAG_USE_POINT_SIZE);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_fixed_size"), "set_flag", "get_flag", FLAG_FIXED_SIZE);
ADD_GROUP("Vertex Color", "vertex_color");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_use_as_albedo"), "set_flag", "get_flag", FLAG_ALBEDO_FROM_VERTEX_COLOR);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_is_srgb"), "set_flag", "get_flag", FLAG_SRGB_VERTEX_COLOR);
ADD_GROUP("Parameters", "params_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "params_diffuse_mode", PROPERTY_HINT_ENUM, "Labert,Lambert Wrap,Oren Nayar,Burley"), "set_diffuse_mode", "get_diffuse_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "params_diffuse_mode", PROPERTY_HINT_ENUM, "Lambert,Lambert Wrap,Oren Nayar,Burley"), "set_diffuse_mode", "get_diffuse_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "params_blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_blend_mode", "get_blend_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "params_cull_mode", PROPERTY_HINT_ENUM, "Back,Front,Disabled"), "set_cull_mode", "get_cull_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "params_depth_draw_mode", PROPERTY_HINT_ENUM, "Opaque Only,Always,Never,Opaque Pre-Pass"), "set_depth_draw_mode", "get_depth_draw_mode");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_line_width", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_line_width", "get_line_width");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_point_size", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_point_size", "get_point_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "params_billboard_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particle Billboard"), "set_billboard_mode", "get_billboard_mode");
+ ADD_GROUP("Particles Anim", "particles_anim_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_h_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_h_frames", "get_particles_anim_h_frames");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_v_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_v_frames", "get_particles_anim_v_frames");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_anim_loop"), "set_particles_anim_loop", "get_particles_anim_loop");
ADD_GROUP("Albedo", "albedo_");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "albedo_color"), "set_albedo", "get_albedo");
@@ -913,7 +1158,7 @@ void FixedSpatialMaterial::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_emission_energy", "get_emission_energy");
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "emission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_EMISSION);
- ADD_GROUP("NormapMap", "normal_");
+ ADD_GROUP("NormalMap", "normal_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "normal_enabled"), "set_feature", "get_feature", FEATURE_NORMAL_MAPPING);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "normal_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_normal_scale", "get_normal_scale");
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_NORMAL);
@@ -1023,6 +1268,7 @@ void FixedSpatialMaterial::_bind_methods() {
BIND_CONSTANT(FLAG_ALBEDO_FROM_VERTEX_COLOR);
BIND_CONSTANT(FLAG_SRGB_VERTEX_COLOR)
BIND_CONSTANT(FLAG_USE_POINT_SIZE)
+ BIND_CONSTANT(FLAG_FIXED_SIZE)
BIND_CONSTANT(FLAG_MAX);
BIND_CONSTANT(DIFFUSE_LAMBERT);
@@ -1032,9 +1278,14 @@ void FixedSpatialMaterial::_bind_methods() {
BIND_CONSTANT(SPECULAR_MODE_METALLIC);
BIND_CONSTANT(SPECULAR_MODE_SPECULAR);
+
+ BIND_CONSTANT(BILLBOARD_DISABLED);
+ BIND_CONSTANT(BILLBOARD_ENABLED);
+ BIND_CONSTANT(BILLBOARD_FIXED_Y);
+ BIND_CONSTANT(BILLBOARD_PARTICLES);
}
-FixedSpatialMaterial::FixedSpatialMaterial()
+SpatialMaterial::SpatialMaterial()
: element(this) {
//initialize to right values
@@ -1061,6 +1312,10 @@ FixedSpatialMaterial::FixedSpatialMaterial()
set_uv1_scale(Vector2(1, 1));
set_uv2_offset(Vector2(0, 0));
set_uv2_scale(Vector2(1, 1));
+ set_billboard_mode(BILLBOARD_DISABLED);
+ set_particles_anim_h_frames(1);
+ set_particles_anim_v_frames(1);
+ set_particles_anim_loop(false);
detail_uv = DETAIL_UV_1;
blend_mode = BLEND_MODE_MIX;
@@ -1081,7 +1336,7 @@ FixedSpatialMaterial::FixedSpatialMaterial()
_queue_shader_change();
}
-FixedSpatialMaterial::~FixedSpatialMaterial() {
+SpatialMaterial::~SpatialMaterial() {
if (material_mutex)
material_mutex->lock();
diff --git a/scene/resources/material.h b/scene/resources/material.h
index a8288153c3..147e7a46ba 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -56,9 +56,34 @@ public:
virtual ~Material();
};
-class FixedSpatialMaterial : public Material {
+class ShaderMaterial : public Material {
- GDCLASS(FixedSpatialMaterial, Material)
+ GDCLASS(ShaderMaterial, Material);
+ Ref<Shader> shader;
+
+protected:
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ void _get_property_list(List<PropertyInfo> *p_list) const;
+
+ static void _bind_methods();
+
+ void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
+
+public:
+ void set_shader(const Ref<Shader> &p_shader);
+ Ref<Shader> get_shader() const;
+
+ void set_shader_param(const StringName &p_param, const Variant &p_value);
+ Variant get_shader_param(const StringName &p_param) const;
+
+ ShaderMaterial();
+ ~ShaderMaterial();
+};
+
+class SpatialMaterial : public Material {
+
+ GDCLASS(SpatialMaterial, Material)
public:
enum TextureParam {
@@ -128,6 +153,7 @@ public:
FLAG_ALBEDO_FROM_VERTEX_COLOR,
FLAG_SRGB_VERTEX_COLOR,
FLAG_USE_POINT_SIZE,
+ FLAG_FIXED_SIZE,
FLAG_MAX
};
@@ -143,20 +169,28 @@ public:
SPECULAR_MODE_SPECULAR,
};
+ enum BillboardMode {
+ BILLBOARD_DISABLED,
+ BILLBOARD_ENABLED,
+ BILLBOARD_FIXED_Y,
+ BILLBOARD_PARTICLES,
+ };
+
private:
union MaterialKey {
struct {
- uint32_t feature_mask : 14;
+ uint32_t feature_mask : 11;
uint32_t detail_uv : 1;
uint32_t blend_mode : 2;
uint32_t depth_draw_mode : 2;
uint32_t cull_mode : 2;
- uint32_t flags : 5;
+ uint32_t flags : 6;
uint32_t detail_blend_mode : 2;
uint32_t diffuse_mode : 2;
uint32_t invalid_key : 1;
uint32_t specular_mode : 1;
+ uint32_t billboard_mode : 2;
};
uint32_t key;
@@ -196,6 +230,7 @@ private:
mk.detail_blend_mode = detail_blend_mode;
mk.diffuse_mode = diffuse_mode;
mk.specular_mode = specular_mode;
+ mk.billboard_mode = billboard_mode;
return mk;
}
@@ -222,14 +257,17 @@ private:
StringName uv1_offset;
StringName uv2_scale;
StringName uv2_offset;
+ StringName particle_h_frames;
+ StringName particle_v_frames;
+ StringName particles_anim_loop;
StringName texture_names[TEXTURE_MAX];
};
static Mutex *material_mutex;
- static SelfList<FixedSpatialMaterial>::List dirty_materials;
+ static SelfList<SpatialMaterial>::List dirty_materials;
static ShaderNames *shader_names;
- SelfList<FixedSpatialMaterial> element;
+ SelfList<SpatialMaterial> element;
void _update_shader();
_FORCE_INLINE_ void _queue_shader_change();
@@ -253,6 +291,9 @@ private:
float refraction_roughness;
float line_width;
float point_size;
+ int particles_anim_h_frames;
+ int particles_anim_v_frames;
+ bool particles_anim_loop;
Vector2 uv1_scale;
Vector2 uv1_offset;
@@ -269,6 +310,7 @@ private:
bool flags[FLAG_MAX];
DiffuseMode diffuse_mode;
SpecularMode specular_mode;
+ BillboardMode billboard_mode;
bool features[FEATURE_MAX];
@@ -377,23 +419,35 @@ public:
void set_uv2_offset(const Vector2 &p_offset);
Vector2 get_uv2_offset() const;
+ void set_billboard_mode(BillboardMode p_mode);
+ BillboardMode get_billboard_mode() const;
+
+ void set_particles_anim_h_frames(int p_frames);
+ int get_particles_anim_h_frames() const;
+ void set_particles_anim_v_frames(int p_frames);
+ int get_particles_anim_v_frames() const;
+
+ void set_particles_anim_loop(int p_frames);
+ int get_particles_anim_loop() const;
+
static void init_shaders();
static void finish_shaders();
static void flush_changes();
- FixedSpatialMaterial();
- virtual ~FixedSpatialMaterial();
+ SpatialMaterial();
+ virtual ~SpatialMaterial();
};
-VARIANT_ENUM_CAST(FixedSpatialMaterial::TextureParam)
-VARIANT_ENUM_CAST(FixedSpatialMaterial::DetailUV)
-VARIANT_ENUM_CAST(FixedSpatialMaterial::Feature)
-VARIANT_ENUM_CAST(FixedSpatialMaterial::BlendMode)
-VARIANT_ENUM_CAST(FixedSpatialMaterial::DepthDrawMode)
-VARIANT_ENUM_CAST(FixedSpatialMaterial::CullMode)
-VARIANT_ENUM_CAST(FixedSpatialMaterial::Flags)
-VARIANT_ENUM_CAST(FixedSpatialMaterial::DiffuseMode)
-VARIANT_ENUM_CAST(FixedSpatialMaterial::SpecularMode)
+VARIANT_ENUM_CAST(SpatialMaterial::TextureParam)
+VARIANT_ENUM_CAST(SpatialMaterial::DetailUV)
+VARIANT_ENUM_CAST(SpatialMaterial::Feature)
+VARIANT_ENUM_CAST(SpatialMaterial::BlendMode)
+VARIANT_ENUM_CAST(SpatialMaterial::DepthDrawMode)
+VARIANT_ENUM_CAST(SpatialMaterial::CullMode)
+VARIANT_ENUM_CAST(SpatialMaterial::Flags)
+VARIANT_ENUM_CAST(SpatialMaterial::DiffuseMode)
+VARIANT_ENUM_CAST(SpatialMaterial::SpecularMode)
+VARIANT_ENUM_CAST(SpatialMaterial::BillboardMode)
//////////////////////
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index f951cf1620..8da8f09007 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -192,6 +192,9 @@ bool Mesh::_set(const StringName &p_name, const Variant &p_value) {
bool Mesh::_get(const StringName &p_name, Variant &r_ret) const {
+ if (_is_generated())
+ return false;
+
String sname = p_name;
if (p_name == "blend_shape/names") {
@@ -268,6 +271,9 @@ bool Mesh::_get(const StringName &p_name, Variant &r_ret) const {
void Mesh::_get_property_list(List<PropertyInfo> *p_list) const {
+ if (_is_generated())
+ return;
+
if (blend_shapes.size()) {
p_list->push_back(PropertyInfo(Variant::POOL_STRING_ARRAY, "blend_shape/names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::INT, "blend_shape/mode", PROPERTY_HINT_ENUM, "Normalized,Relative"));
@@ -1025,3 +1031,71 @@ Mesh::~Mesh() {
VisualServer::get_singleton()->free(mesh);
}
+
+////////////////////////
+
+void QuadMesh::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_material", "material:Material"), &QuadMesh::set_material);
+ ClassDB::bind_method(D_METHOD("get_material:Material"), &QuadMesh::get_material);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_material", "get_material");
+}
+
+void QuadMesh::set_material(const Ref<Material> &p_material) {
+
+ surface_set_material(0, p_material);
+}
+
+Ref<Material> QuadMesh::get_material() const {
+
+ return surface_get_material(0);
+}
+
+QuadMesh::QuadMesh() {
+
+ PoolVector<Vector3> faces;
+ PoolVector<Vector3> normals;
+ PoolVector<float> tangents;
+ PoolVector<Vector2> uvs;
+
+ faces.resize(4);
+ normals.resize(4);
+ tangents.resize(4 * 4);
+ uvs.resize(4);
+
+ for (int i = 0; i < 4; i++) {
+
+ static const Vector3 quad_faces[4] = {
+ Vector3(-1, -1, 0),
+ Vector3(-1, 1, 0),
+ Vector3(1, 1, 0),
+ Vector3(1, -1, 0),
+ };
+
+ faces.set(i, quad_faces[i]);
+ normals.set(i, Vector3(0, 0, 1));
+ tangents.set(i * 4 + 0, 1.0);
+ tangents.set(i * 4 + 1, 0.0);
+ tangents.set(i * 4 + 2, 0.0);
+ tangents.set(i * 4 + 3, 1.0);
+
+ static const Vector2 quad_uv[4] = {
+ Vector2(0, 1),
+ Vector2(0, 0),
+ Vector2(1, 0),
+ Vector2(1, 1),
+ };
+
+ uvs.set(i, quad_uv[i]);
+ }
+
+ Array arr;
+ arr.resize(ARRAY_MAX);
+ arr[ARRAY_VERTEX] = faces;
+ arr[ARRAY_NORMAL] = normals;
+ arr[ARRAY_TANGENT] = tangents;
+ arr[ARRAY_TEX_UV] = uvs;
+
+ add_surface_from_arrays(PRIMITIVE_TRIANGLE_FAN, arr);
+}
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index 8b1936ed06..77907ddbcd 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -128,6 +128,8 @@ private:
void _recompute_aabb();
protected:
+ virtual bool _is_generated() const { return false; }
+
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
@@ -189,6 +191,20 @@ public:
~Mesh();
};
+class QuadMesh : public Mesh {
+
+ GDCLASS(QuadMesh, Mesh)
+
+protected:
+ virtual bool _is_generated() const { return true; }
+ static void _bind_methods();
+
+public:
+ void set_material(const Ref<Material> &p_material);
+ Ref<Material> get_material() const;
+ QuadMesh();
+};
+
VARIANT_ENUM_CAST(Mesh::ArrayType);
VARIANT_ENUM_CAST(Mesh::PrimitiveType);
VARIANT_ENUM_CAST(Mesh::BlendShapeMode);
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index fd058a4a6f..a0a8a9eca2 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -29,6 +29,7 @@
#include "shader.h"
#include "os/file_access.h"
#include "scene/scene_string_names.h"
+#include "servers/visual/shader_language.h"
#include "servers/visual_server.h"
#include "texture.h"
@@ -39,6 +40,18 @@ Shader::Mode Shader::get_mode() const {
void Shader::set_code(const String &p_code) {
+ String type = ShaderLanguage::get_shader_type(p_code);
+
+ print_line("mode: " + type);
+
+ if (type == "canvas_item") {
+ mode = MODE_CANVAS_ITEM;
+ } else if (type == "particles") {
+ mode = MODE_PARTICLES;
+ } else {
+ mode = MODE_SPATIAL;
+ }
+
VisualServer::get_singleton()->shader_set_code(shader, p_code);
params_cache_dirty = true;
emit_signal(SceneStringNames::get_singleton()->changed);
@@ -128,10 +141,10 @@ void Shader::_bind_methods() {
BIND_CONSTANT(MODE_PARTICLES);
}
-Shader::Shader(Mode p_mode) {
+Shader::Shader() {
- mode = p_mode;
- shader = VisualServer::get_singleton()->shader_create(VS::ShaderMode(p_mode));
+ mode = MODE_SPATIAL;
+ shader = VisualServer::get_singleton()->shader_create();
params_cache_dirty = true;
}
diff --git a/scene/resources/shader.h b/scene/resources/shader.h
index bc98fbf737..984ea84fb4 100644
--- a/scene/resources/shader.h
+++ b/scene/resources/shader.h
@@ -88,37 +88,10 @@ public:
virtual RID get_rid() const;
- Shader(Mode p_mode);
+ Shader();
~Shader();
};
VARIANT_ENUM_CAST(Shader::Mode);
-class SpatialShader : public Shader {
-
- GDCLASS(SpatialShader, Shader);
-
-public:
- SpatialShader()
- : Shader(MODE_SPATIAL){};
-};
-
-class CanvasItemShader : public Shader {
-
- GDCLASS(CanvasItemShader, Shader);
-
-public:
- CanvasItemShader()
- : Shader(MODE_CANVAS_ITEM){};
-};
-
-class ParticlesShader : public Shader {
-
- GDCLASS(ParticlesShader, Shader);
-
-public:
- ParticlesShader()
- : Shader(MODE_PARTICLES){};
-};
-
#endif // SHADER_H
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 7a503207bc..a3bb52d0f1 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -103,9 +103,11 @@ void StyleBoxTexture::set_texture(RES p_texture) {
if (texture == p_texture)
return;
texture = p_texture;
+ region_rect = Rect2(Point2(), texture->get_size());
emit_signal("texture_changed");
emit_changed();
}
+
RES StyleBoxTexture::get_texture() const {
return texture;
@@ -130,12 +132,12 @@ void StyleBoxTexture::draw(RID p_canvas_item, const Rect2 &p_rect) const {
if (texture.is_null())
return;
- Rect2 r = p_rect;
- r.pos.x -= expand_margin[MARGIN_LEFT];
- r.pos.y -= expand_margin[MARGIN_TOP];
- r.size.x += expand_margin[MARGIN_LEFT] + expand_margin[MARGIN_RIGHT];
- r.size.y += expand_margin[MARGIN_TOP] + expand_margin[MARGIN_BOTTOM];
- VisualServer::get_singleton()->canvas_item_add_nine_patch(p_canvas_item, r, region_rect, texture->get_rid(), Vector2(margin[MARGIN_LEFT], margin[MARGIN_TOP]), Vector2(margin[MARGIN_RIGHT], margin[MARGIN_BOTTOM]), VS::NINE_PATCH_STRETCH, VS::NINE_PATCH_STRETCH, draw_center, modulate);
+ Rect2 rect = p_rect;
+ Rect2 src_rect = region_rect;
+
+ texture->get_rect_region(rect, src_rect, rect, src_rect);
+
+ VisualServer::get_singleton()->canvas_item_add_nine_patch(p_canvas_item, rect, src_rect, texture->get_rid(), Vector2(margin[MARGIN_LEFT], margin[MARGIN_TOP]), Vector2(margin[MARGIN_RIGHT], margin[MARGIN_BOTTOM]), VS::NINE_PATCH_STRETCH, VS::NINE_PATCH_STRETCH, draw_center, modulate);
}
void StyleBoxTexture::set_draw_center(bool p_draw) {
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index d08fc2634e..d4732281be 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -1367,3 +1367,471 @@ CubeMap::~CubeMap() {
BIND_CONSTANT( CUBEMAP_FRONT );
BIND_CONSTANT( CUBEMAP_BACK );
*/
+///////////////////////////
+
+void CurveTexture::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_max", "max"), &CurveTexture::set_max);
+ ClassDB::bind_method(D_METHOD("get_max"), &CurveTexture::get_max);
+
+ ClassDB::bind_method(D_METHOD("set_min", "min"), &CurveTexture::set_min);
+ ClassDB::bind_method(D_METHOD("get_min"), &CurveTexture::get_min);
+
+ ClassDB::bind_method(D_METHOD("set_width", "width"), &CurveTexture::set_width);
+
+ ClassDB::bind_method(D_METHOD("set_points", "points"), &CurveTexture::set_points);
+ ClassDB::bind_method(D_METHOD("get_points"), &CurveTexture::get_points);
+
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "min", PROPERTY_HINT_RANGE, "-1024,1024"), "set_min", "get_min");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "max", PROPERTY_HINT_RANGE, "-1024,1024"), "set_max", "get_max");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "32,4096"), "set_width", "get_width");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "points"), "set_points", "get_points");
+}
+void CurveTexture::set_max(float p_max) {
+
+ max = p_max;
+ emit_changed();
+}
+float CurveTexture::get_max() const {
+
+ return max;
+}
+
+void CurveTexture::set_min(float p_min) {
+
+ min = p_min;
+ emit_changed();
+}
+float CurveTexture::get_min() const {
+
+ return min;
+}
+void CurveTexture::set_width(int p_width) {
+
+ ERR_FAIL_COND(p_width < 32 || p_width > 4096);
+ width = p_width;
+ if (points.size())
+ set_points(points);
+}
+int CurveTexture::get_width() const {
+
+ return width;
+}
+
+static void _plot_curve(const Vector2 &p_a, const Vector2 &p_b, const Vector2 &p_c, const Vector2 &p_d, float *p_heights, bool *p_useds, int p_width, float p_min, float p_max) {
+
+ float geometry[4][4];
+ float tmp1[4][4];
+ float tmp2[4][4];
+ float deltas[4][4];
+ double x, dx, dx2, dx3;
+ double y, dy, dy2, dy3;
+ double d, d2, d3;
+ int lastx;
+ int newx;
+ float lasty;
+ float newy;
+ int ntimes;
+ int i, j;
+
+ int xmax = p_width;
+
+ /* construct the geometry matrix from the segment */
+ for (i = 0; i < 4; i++) {
+ geometry[i][2] = 0;
+ geometry[i][3] = 0;
+ }
+
+ geometry[0][0] = (p_a[0] * xmax);
+ geometry[1][0] = (p_b[0] * xmax);
+ geometry[2][0] = (p_c[0] * xmax);
+ geometry[3][0] = (p_d[0] * xmax);
+
+ geometry[0][1] = (p_a[1]);
+ geometry[1][1] = (p_b[1]);
+ geometry[2][1] = (p_c[1]);
+ geometry[3][1] = (p_d[1]);
+
+ /* subdivide the curve ntimes (1000) times */
+ ntimes = 4 * xmax;
+ /* ntimes can be adjusted to give a finer or coarser curve */
+ d = 1.0 / ntimes;
+ d2 = d * d;
+ d3 = d * d * d;
+
+ /* construct a temporary matrix for determining the forward differencing deltas */
+ tmp2[0][0] = 0;
+ tmp2[0][1] = 0;
+ tmp2[0][2] = 0;
+ tmp2[0][3] = 1;
+ tmp2[1][0] = d3;
+ tmp2[1][1] = d2;
+ tmp2[1][2] = d;
+ tmp2[1][3] = 0;
+ tmp2[2][0] = 6 * d3;
+ tmp2[2][1] = 2 * d2;
+ tmp2[2][2] = 0;
+ tmp2[2][3] = 0;
+ tmp2[3][0] = 6 * d3;
+ tmp2[3][1] = 0;
+ tmp2[3][2] = 0;
+ tmp2[3][3] = 0;
+
+ /* compose the basis and geometry matrices */
+
+ static const float CR_basis[4][4] = {
+ { -0.5, 1.5, -1.5, 0.5 },
+ { 1.0, -2.5, 2.0, -0.5 },
+ { -0.5, 0.0, 0.5, 0.0 },
+ { 0.0, 1.0, 0.0, 0.0 },
+ };
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ tmp1[i][j] = (CR_basis[i][0] * geometry[0][j] +
+ CR_basis[i][1] * geometry[1][j] +
+ CR_basis[i][2] * geometry[2][j] +
+ CR_basis[i][3] * geometry[3][j]);
+ }
+ }
+ /* compose the above results to get the deltas matrix */
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ deltas[i][j] = (tmp2[i][0] * tmp1[0][j] +
+ tmp2[i][1] * tmp1[1][j] +
+ tmp2[i][2] * tmp1[2][j] +
+ tmp2[i][3] * tmp1[3][j]);
+ }
+ }
+
+ /* extract the x deltas */
+ x = deltas[0][0];
+ dx = deltas[1][0];
+ dx2 = deltas[2][0];
+ dx3 = deltas[3][0];
+
+ /* extract the y deltas */
+ y = deltas[0][1];
+ dy = deltas[1][1];
+ dy2 = deltas[2][1];
+ dy3 = deltas[3][1];
+
+ lastx = CLAMP(x, 0, xmax);
+ lasty = y;
+
+ p_heights[lastx] = lasty;
+ p_useds[lastx] = true;
+
+ /* loop over the curve */
+ for (i = 0; i < ntimes; i++) {
+ /* increment the x values */
+ x += dx;
+ dx += dx2;
+ dx2 += dx3;
+
+ /* increment the y values */
+ y += dy;
+ dy += dy2;
+ dy2 += dy3;
+
+ newx = CLAMP((Math::round(x)), 0, xmax);
+ newy = CLAMP(y, p_min, p_max);
+
+ /* if this point is different than the last one...then draw it */
+ if ((lastx != newx) || (lasty != newy)) {
+ p_useds[newx] = true;
+ p_heights[newx] = newy;
+ }
+
+ lastx = newx;
+ lasty = newy;
+ }
+}
+
+void CurveTexture::set_points(const PoolVector<Vector2> &p_points) {
+
+ points = p_points;
+
+ PoolVector<uint8_t> data;
+ PoolVector<bool> used;
+ data.resize(width * sizeof(float));
+ used.resize(width);
+ {
+ PoolVector<uint8_t>::Write wd8 = data.write();
+ float *wd = (float *)wd8.ptr();
+ PoolVector<bool>::Write wu = used.write();
+ int pc = p_points.size();
+ PoolVector<Vector2>::Read pr = p_points.read();
+
+ for (int i = 0; i < width; i++) {
+ wd[i] = 0.0;
+ wu[i] = false;
+ }
+
+ Vector2 prev = Vector2(0, 0);
+ Vector2 prev2 = Vector2(0, 0);
+
+ for (int i = -1; i < pc; i++) {
+
+ Vector2 next;
+ Vector2 next2;
+ if (i + 1 >= pc) {
+ next = Vector2(1, 0);
+ } else {
+ next = Vector2(pr[i + 1].x, pr[i + 1].y);
+ }
+
+ if (i + 2 >= pc) {
+ next2 = Vector2(1, 0);
+ } else {
+ next2 = Vector2(pr[i + 2].x, pr[i + 2].y);
+ }
+
+ /*if (i==-1 && prev.offset==next.offset) {
+ prev=next;
+ continue;
+ }*/
+
+ _plot_curve(prev2, prev, next, next2, wd, wu.ptr(), width, min, max);
+
+ prev2 = prev;
+ prev = next;
+ }
+ }
+
+ Image image(width, 1, false, Image::FORMAT_RF, data);
+
+ VS::get_singleton()->texture_allocate(texture, width, 1, Image::FORMAT_RF, VS::TEXTURE_FLAG_FILTER);
+ VS::get_singleton()->texture_set_data(texture, image);
+
+ emit_changed();
+}
+
+PoolVector<Vector2> CurveTexture::get_points() const {
+
+ return points;
+}
+
+RID CurveTexture::get_rid() const {
+
+ return texture;
+}
+
+CurveTexture::CurveTexture() {
+
+ max = 1;
+ min = 0;
+ width = 2048;
+ texture = VS::get_singleton()->texture_create();
+}
+CurveTexture::~CurveTexture() {
+ VS::get_singleton()->free(texture);
+}
+//////////////////
+
+//setter and getter names for property serialization
+#define COLOR_RAMP_GET_OFFSETS "get_offsets"
+#define COLOR_RAMP_GET_COLORS "get_colors"
+#define COLOR_RAMP_SET_OFFSETS "set_offsets"
+#define COLOR_RAMP_SET_COLORS "set_colors"
+
+GradientTexture::GradientTexture() {
+ //Set initial color ramp transition from black to white
+ points.resize(2);
+ points[0].color = Color(0, 0, 0, 1);
+ points[0].offset = 0;
+ points[1].color = Color(1, 1, 1, 1);
+ points[1].offset = 1;
+ is_sorted = true;
+ update_pending = false;
+ width = 2048;
+
+ texture = VS::get_singleton()->texture_create();
+ _queue_update();
+}
+
+GradientTexture::~GradientTexture() {
+ VS::get_singleton()->free(texture);
+}
+
+void GradientTexture::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("add_point", "offset", "color"), &GradientTexture::add_point);
+ ClassDB::bind_method(D_METHOD("remove_point", "offset", "color"), &GradientTexture::remove_point);
+
+ ClassDB::bind_method(D_METHOD("set_offset", "point", "offset"), &GradientTexture::set_offset);
+ ClassDB::bind_method(D_METHOD("get_offset", "point"), &GradientTexture::get_offset);
+
+ ClassDB::bind_method(D_METHOD("set_color", "point", "color"), &GradientTexture::set_color);
+ ClassDB::bind_method(D_METHOD("get_color", "point"), &GradientTexture::get_color);
+
+ ClassDB::bind_method(D_METHOD("set_width", "width"), &GradientTexture::set_width);
+
+ ClassDB::bind_method(D_METHOD("interpolate", "offset"), &GradientTexture::get_color_at_offset);
+
+ ClassDB::bind_method(D_METHOD("get_point_count"), &GradientTexture::get_points_count);
+
+ ClassDB::bind_method(D_METHOD("_update"), &GradientTexture::_update);
+
+ ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_OFFSETS, "offsets"), &GradientTexture::set_offsets);
+ ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_OFFSETS), &GradientTexture::get_offsets);
+
+ ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_COLORS, "colors"), &GradientTexture::set_colors);
+ ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_COLORS), &GradientTexture::get_colors);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "width"), "set_width", "get_width");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "offsets"), COLOR_RAMP_SET_OFFSETS, COLOR_RAMP_GET_OFFSETS);
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "colors"), COLOR_RAMP_SET_COLORS, COLOR_RAMP_GET_COLORS);
+}
+
+void GradientTexture::_queue_update() {
+
+ if (update_pending)
+ return;
+
+ call_deferred("_update");
+}
+
+void GradientTexture::_update() {
+
+ update_pending = false;
+
+ PoolVector<uint8_t> data;
+ data.resize(width * 4);
+ {
+ PoolVector<uint8_t>::Write wd8 = data.write();
+ for (int i = 0; i < width; i++) {
+ float ofs = float(i) / (width - 1);
+
+ Color color = get_color_at_offset(ofs);
+ wd8[i * 4 + 0] = uint8_t(CLAMP(color.r * 255.0, 0, 255));
+ wd8[i * 4 + 1] = uint8_t(CLAMP(color.g * 255.0, 0, 255));
+ wd8[i * 4 + 2] = uint8_t(CLAMP(color.b * 255.0, 0, 255));
+ wd8[i * 4 + 3] = uint8_t(CLAMP(color.a * 255.0, 0, 255));
+ }
+ }
+
+ Image image(width, 1, false, Image::FORMAT_RGBA8, data);
+
+ VS::get_singleton()->texture_allocate(texture, width, 1, Image::FORMAT_RGBA8, VS::TEXTURE_FLAG_FILTER);
+ VS::get_singleton()->texture_set_data(texture, image);
+
+ emit_changed();
+}
+
+void GradientTexture::set_width(int p_width) {
+
+ width = p_width;
+ _queue_update();
+}
+int GradientTexture::get_width() const {
+
+ return width;
+}
+
+Vector<float> GradientTexture::get_offsets() const {
+ Vector<float> offsets;
+ offsets.resize(points.size());
+ for (int i = 0; i < points.size(); i++) {
+ offsets[i] = points[i].offset;
+ }
+ return offsets;
+}
+
+Vector<Color> GradientTexture::get_colors() const {
+ Vector<Color> colors;
+ colors.resize(points.size());
+ for (int i = 0; i < points.size(); i++) {
+ colors[i] = points[i].color;
+ }
+ return colors;
+}
+
+void GradientTexture::set_offsets(const Vector<float> &p_offsets) {
+ points.resize(p_offsets.size());
+ for (int i = 0; i < points.size(); i++) {
+ points[i].offset = p_offsets[i];
+ }
+ is_sorted = false;
+ emit_changed();
+ _queue_update();
+}
+
+void GradientTexture::set_colors(const Vector<Color> &p_colors) {
+ if (points.size() < p_colors.size())
+ is_sorted = false;
+ points.resize(p_colors.size());
+ for (int i = 0; i < points.size(); i++) {
+ points[i].color = p_colors[i];
+ }
+ emit_changed();
+ _queue_update();
+}
+
+Vector<GradientTexture::Point> &GradientTexture::get_points() {
+ return points;
+}
+
+void GradientTexture::add_point(float p_offset, const Color &p_color) {
+
+ Point p;
+ p.offset = p_offset;
+ p.color = p_color;
+ is_sorted = false;
+ points.push_back(p);
+
+ emit_changed();
+ _queue_update();
+}
+
+void GradientTexture::remove_point(int p_index) {
+
+ ERR_FAIL_INDEX(p_index, points.size());
+ ERR_FAIL_COND(points.size() <= 2);
+ points.remove(p_index);
+ emit_changed();
+ _queue_update();
+}
+
+void GradientTexture::set_points(Vector<GradientTexture::Point> &p_points) {
+ points = p_points;
+ is_sorted = false;
+ emit_changed();
+ _queue_update();
+}
+
+void GradientTexture::set_offset(int pos, const float offset) {
+ if (points.size() <= pos)
+ points.resize(pos + 1);
+ points[pos].offset = offset;
+ is_sorted = false;
+ emit_changed();
+ _queue_update();
+}
+
+float GradientTexture::get_offset(int pos) const {
+ if (points.size() > pos)
+ return points[pos].offset;
+ return 0; //TODO: Maybe throw some error instead?
+}
+
+void GradientTexture::set_color(int pos, const Color &color) {
+ if (points.size() <= pos) {
+ points.resize(pos + 1);
+ is_sorted = false;
+ }
+ points[pos].color = color;
+ emit_changed();
+ _queue_update();
+}
+
+Color GradientTexture::get_color(int pos) const {
+ if (points.size() > pos)
+ return points[pos].color;
+ return Color(0, 0, 0, 1); //TODO: Maybe throw some error instead?
+}
+
+int GradientTexture::get_points_count() const {
+ return points.size();
+}
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 0092fee836..52e5fdd161 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -394,6 +394,44 @@ VARIANT_ENUM_CAST(CubeMap::Flags);
VARIANT_ENUM_CAST(CubeMap::Side);
VARIANT_ENUM_CAST(CubeMap::Storage);
+class CurveTexture : public Texture {
+
+ GDCLASS(CurveTexture, Texture);
+ RES_BASE_EXTENSION("cvtex");
+
+private:
+ RID texture;
+ PoolVector<Vector2> points;
+ float min, max;
+ int width;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_max(float p_max);
+ float get_max() const;
+
+ void set_min(float p_min);
+ float get_min() const;
+
+ void set_width(int p_width);
+ int get_width() const;
+
+ void set_points(const PoolVector<Vector2> &p_points);
+ PoolVector<Vector2> get_points() const;
+
+ virtual RID get_rid() const;
+
+ virtual int get_height() const { return 1; }
+ virtual bool has_alpha() const { return false; }
+
+ virtual void set_flags(uint32_t p_flags) {}
+ virtual uint32_t get_flags() const { return FLAG_FILTER; }
+
+ CurveTexture();
+ ~CurveTexture();
+};
/*
enum CubeMapSide {
@@ -408,4 +446,107 @@ VARIANT_ENUM_CAST(CubeMap::Storage);
*/
//VARIANT_ENUM_CAST( Texture::CubeMapSide );
+class GradientTexture : public Texture {
+ GDCLASS(GradientTexture, Texture);
+
+public:
+ struct Point {
+
+ float offset;
+ Color color;
+ bool operator<(const Point &p_ponit) const {
+ return offset < p_ponit.offset;
+ }
+ };
+
+private:
+ Vector<Point> points;
+ bool is_sorted;
+ bool update_pending;
+ RID texture;
+ int width;
+
+ void _queue_update();
+ void _update();
+
+protected:
+ static void _bind_methods();
+
+public:
+ void add_point(float p_offset, const Color &p_color);
+ void remove_point(int p_index);
+
+ void set_points(Vector<Point> &points);
+ Vector<Point> &get_points();
+
+ void set_offset(int pos, const float offset);
+ float get_offset(int pos) const;
+
+ void set_color(int pos, const Color &color);
+ Color get_color(int pos) const;
+
+ void set_offsets(const Vector<float> &offsets);
+ Vector<float> get_offsets() const;
+
+ void set_colors(const Vector<Color> &colors);
+ Vector<Color> get_colors() const;
+
+ void set_width(int p_width);
+ int get_width() const;
+
+ virtual RID get_rid() const { return texture; }
+ virtual int get_height() const { return 1; }
+ virtual bool has_alpha() const { return true; }
+
+ virtual void set_flags(uint32_t p_flags) {}
+ virtual uint32_t get_flags() const { return FLAG_FILTER; }
+
+ _FORCE_INLINE_ Color get_color_at_offset(float p_offset) {
+
+ if (points.empty())
+ return Color(0, 0, 0, 1);
+
+ if (!is_sorted) {
+ points.sort();
+ is_sorted = true;
+ }
+
+ //binary search
+ int low = 0;
+ int high = points.size() - 1;
+ int middle;
+
+ while (low <= high) {
+ middle = (low + high) / 2;
+ Point &point = points[middle];
+ if (point.offset > p_offset) {
+ high = middle - 1; //search low end of array
+ } else if (point.offset < p_offset) {
+ low = middle + 1; //search high end of array
+ } else {
+ return point.color;
+ }
+ }
+
+ //return interpolated value
+ if (points[middle].offset > p_offset) {
+ middle--;
+ }
+ int first = middle;
+ int second = middle + 1;
+ if (second >= points.size())
+ return points[points.size() - 1].color;
+ if (first < 0)
+ return points[0].color;
+ Point &pointFirst = points[first];
+ Point &pointSecond = points[second];
+ return pointFirst.color.linear_interpolate(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset));
+ }
+
+ int get_points_count() const;
+
+ GradientTexture();
+ virtual ~GradientTexture();
+};
+
#endif
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 3e128379ae..13fbac3417 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -125,7 +125,7 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::STRING, pre + "name"));
p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "tex_offset"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "material", PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial"));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial"));
p_list->push_back(PropertyInfo(Variant::COLOR, pre + "modulate"));
p_list->push_back(PropertyInfo(Variant::RECT2, pre + "region"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "occluder_offset"));
@@ -159,16 +159,16 @@ Ref<Texture> TileSet::tile_get_texture(int p_id) const {
return tile_map[p_id].texture;
}
-void TileSet::tile_set_material(int p_id, const Ref<CanvasItemMaterial> &p_material) {
+void TileSet::tile_set_material(int p_id, const Ref<ShaderMaterial> &p_material) {
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].material = p_material;
emit_changed();
}
-Ref<CanvasItemMaterial> TileSet::tile_get_material(int p_id) const {
+Ref<ShaderMaterial> TileSet::tile_get_material(int p_id) const {
- ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<CanvasItemMaterial>());
+ ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<ShaderMaterial>());
return tile_map[p_id].material;
}
@@ -403,8 +403,8 @@ void TileSet::_bind_methods() {
ClassDB::bind_method(D_METHOD("tile_get_name", "id"), &TileSet::tile_get_name);
ClassDB::bind_method(D_METHOD("tile_set_texture", "id", "texture:Texture"), &TileSet::tile_set_texture);
ClassDB::bind_method(D_METHOD("tile_get_texture:Texture", "id"), &TileSet::tile_get_texture);
- ClassDB::bind_method(D_METHOD("tile_set_material", "id", "material:CanvasItemMaterial"), &TileSet::tile_set_material);
- ClassDB::bind_method(D_METHOD("tile_get_material:CanvasItemMaterial", "id"), &TileSet::tile_get_material);
+ ClassDB::bind_method(D_METHOD("tile_set_material", "id", "material:ShaderMaterial"), &TileSet::tile_set_material);
+ ClassDB::bind_method(D_METHOD("tile_get_material:ShaderMaterial", "id"), &TileSet::tile_get_material);
ClassDB::bind_method(D_METHOD("tile_set_texture_offset", "id", "texture_offset"), &TileSet::tile_set_texture_offset);
ClassDB::bind_method(D_METHOD("tile_get_texture_offset", "id"), &TileSet::tile_get_texture_offset);
ClassDB::bind_method(D_METHOD("tile_set_shape_offset", "id", "shape_offset"), &TileSet::tile_set_shape_offset);
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index 53f68d00a5..4c8adb760f 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -51,7 +51,7 @@ class TileSet : public Resource {
Ref<OccluderPolygon2D> occluder;
Vector2 navigation_polygon_offset;
Ref<NavigationPolygon> navigation_polygon;
- Ref<CanvasItemMaterial> material;
+ Ref<ShaderMaterial> material;
Color modulate;
// Default modulate for back-compat
@@ -92,8 +92,8 @@ public:
void tile_set_shape(int p_id, const Ref<Shape2D> &p_shape);
Ref<Shape2D> tile_get_shape(int p_id) const;
- void tile_set_material(int p_id, const Ref<CanvasItemMaterial> &p_material);
- Ref<CanvasItemMaterial> tile_get_material(int p_id) const;
+ void tile_set_material(int p_id, const Ref<ShaderMaterial> &p_material);
+ Ref<ShaderMaterial> tile_get_material(int p_id) const;
void tile_set_modulate(int p_id, const Color &p_color);
Color tile_get_modulate(int p_id) const;
diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp
index f0a33e0d3b..d4a5429c02 100644
--- a/scene/scene_string_names.cpp
+++ b/scene/scene_string_names.cpp
@@ -32,6 +32,9 @@ SceneStringNames *SceneStringNames::singleton = NULL;
SceneStringNames::SceneStringNames() {
+ _estimate_cost = StaticCString::create("_estimate_cost");
+ _compute_cost = StaticCString::create("_compute_cost");
+
resized = StaticCString::create("resized");
dot = StaticCString::create(".");
doubledot = StaticCString::create("..");
diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h
index 8900bbe1d9..3ca006daba 100644
--- a/scene/scene_string_names.h
+++ b/scene/scene_string_names.h
@@ -49,6 +49,9 @@ class SceneStringNames {
public:
_FORCE_INLINE_ static SceneStringNames *get_singleton() { return singleton; }
+ StringName _estimate_cost;
+ StringName _compute_cost;
+
StringName resized;
StringName dot;
StringName doubledot;
diff --git a/servers/visual/rasterizer.cpp b/servers/visual/rasterizer.cpp
index 1be65be927..22bec0a31f 100644
--- a/servers/visual/rasterizer.cpp
+++ b/servers/visual/rasterizer.cpp
@@ -54,10 +54,10 @@ RID Rasterizer::create_default_material() {
/* Fixed MAterial SHADER API */
-RID Rasterizer::_create_shader(const FixedSpatialMaterialShaderKey& p_key) {
+RID Rasterizer::_create_shader(const SpatialMaterialShaderKey& p_key) {
ERR_FAIL_COND_V(!p_key.valid,RID());
- Map<FixedSpatialMaterialShaderKey,FixedSpatialMaterialShader>::Element *E=fixed_material_shaders.find(p_key);
+ Map<SpatialMaterialShaderKey,SpatialMaterialShader>::Element *E=fixed_material_shaders.find(p_key);
if (E) {
E->get().refcount++;
@@ -66,7 +66,7 @@ RID Rasterizer::_create_shader(const FixedSpatialMaterialShaderKey& p_key) {
uint64_t t = OS::get_singleton()->get_ticks_usec();
- FixedSpatialMaterialShader fms;
+ SpatialMaterialShader fms;
fms.refcount=1;
fms.shader=shader_create();
@@ -312,12 +312,12 @@ RID Rasterizer::_create_shader(const FixedSpatialMaterialShaderKey& p_key) {
return fms.shader;
}
-void Rasterizer::_free_shader(const FixedSpatialMaterialShaderKey& p_key) {
+void Rasterizer::_free_shader(const SpatialMaterialShaderKey& p_key) {
if (p_key.valid==0)
return; //not a valid key
- Map<FixedSpatialMaterialShaderKey,FixedSpatialMaterialShader>::Element *E=fixed_material_shaders.find(p_key);
+ Map<SpatialMaterialShaderKey,SpatialMaterialShader>::Element *E=fixed_material_shaders.find(p_key);
ERR_FAIL_COND(!E);
E->get().refcount--;
@@ -329,12 +329,12 @@ void Rasterizer::_free_shader(const FixedSpatialMaterialShaderKey& p_key) {
}
-void Rasterizer::fixed_material_set_flag(RID p_material, VS::FixedSpatialMaterialFlags p_flag, bool p_enabled) {
+void Rasterizer::fixed_material_set_flag(RID p_material, VS::SpatialMaterialFlags p_flag, bool p_enabled) {
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND(!E);
- FixedSpatialMaterial &fm=*E->get();
+ SpatialMaterial &fm=*E->get();
switch(p_flag) {
@@ -350,11 +350,11 @@ void Rasterizer::fixed_material_set_flag(RID p_material, VS::FixedSpatialMateria
}
-bool Rasterizer::fixed_material_get_flag(RID p_material, VS::FixedSpatialMaterialFlags p_flag) const{
+bool Rasterizer::fixed_material_get_flag(RID p_material, VS::SpatialMaterialFlags p_flag) const{
- const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND_V(!E,false);
- const FixedSpatialMaterial &fm=*E->get();
+ const SpatialMaterial &fm=*E->get();
switch(p_flag) {
case VS::FIXED_MATERIAL_FLAG_USE_ALPHA: return fm.use_alpha;; break;
@@ -373,8 +373,8 @@ bool Rasterizer::fixed_material_get_flag(RID p_material, VS::FixedSpatialMateria
RID Rasterizer::fixed_material_create() {
RID mat = material_create();
- fixed_materials[mat]=memnew( FixedSpatialMaterial() );
- FixedSpatialMaterial &fm=*fixed_materials[mat];
+ fixed_materials[mat]=memnew( SpatialMaterial() );
+ SpatialMaterial &fm=*fixed_materials[mat];
fm.self=mat;
fm.get_key();
material_set_flag(mat,VS::MATERIAL_FLAG_COLOR_ARRAY_SRGB,true);
@@ -390,11 +390,11 @@ RID Rasterizer::fixed_material_create() {
-void Rasterizer::fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant& p_value){
+void Rasterizer::fixed_material_set_parameter(RID p_material, VS::SpatialMaterialParam p_parameter, const Variant& p_value){
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND(!E);
- FixedSpatialMaterial &fm=*E->get();
+ SpatialMaterial &fm=*E->get();
RID material=E->key();
ERR_FAIL_INDEX(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX);
@@ -417,24 +417,24 @@ void Rasterizer::fixed_material_set_parameter(RID p_material, VS::FixedSpatialMa
}
-Variant Rasterizer::fixed_material_get_parameter(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const{
+Variant Rasterizer::fixed_material_get_parameter(RID p_material,VS::SpatialMaterialParam p_parameter) const{
- const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND_V(!E,Variant());
- const FixedSpatialMaterial &fm=*E->get();
+ const SpatialMaterial &fm=*E->get();
ERR_FAIL_INDEX_V(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX,Variant());
return fm.param[p_parameter];
}
-void Rasterizer::fixed_material_set_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter, RID p_texture){
+void Rasterizer::fixed_material_set_texture(RID p_material,VS::SpatialMaterialParam p_parameter, RID p_texture){
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
if (!E) {
print_line("Not found: "+itos(p_material.get_id()));
}
ERR_FAIL_COND(!E);
- FixedSpatialMaterial &fm=*E->get();
+ SpatialMaterial &fm=*E->get();
ERR_FAIL_INDEX(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX);
@@ -449,22 +449,22 @@ void Rasterizer::fixed_material_set_texture(RID p_material,VS::FixedSpatialMater
}
-RID Rasterizer::fixed_material_get_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const{
+RID Rasterizer::fixed_material_get_texture(RID p_material,VS::SpatialMaterialParam p_parameter) const{
- const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND_V(!E,RID());
- const FixedSpatialMaterial &fm=*E->get();
+ const SpatialMaterial &fm=*E->get();
ERR_FAIL_INDEX_V(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX,RID());
return fm.texture[p_parameter];
}
-void Rasterizer::fixed_material_set_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode) {
+void Rasterizer::fixed_material_set_texcoord_mode(RID p_material,VS::SpatialMaterialParam p_parameter, VS::SpatialMaterialTexCoordMode p_mode) {
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND(!E);
- FixedSpatialMaterial &fm=*E->get();
+ SpatialMaterial &fm=*E->get();
ERR_FAIL_INDEX(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX);
fm.get_key();
@@ -476,11 +476,11 @@ void Rasterizer::fixed_material_set_texcoord_mode(RID p_material,VS::FixedSpatia
}
-VS::FixedSpatialMaterialTexCoordMode Rasterizer::fixed_material_get_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const {
+VS::SpatialMaterialTexCoordMode Rasterizer::fixed_material_get_texcoord_mode(RID p_material,VS::SpatialMaterialParam p_parameter) const {
- const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND_V(!E,VS::FIXED_MATERIAL_TEXCOORD_UV);
- const FixedSpatialMaterial &fm=*E->get();
+ const SpatialMaterial &fm=*E->get();
ERR_FAIL_INDEX_V(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX,VS::FIXED_MATERIAL_TEXCOORD_UV);
return fm.texture_tc[p_parameter];
@@ -488,9 +488,9 @@ VS::FixedSpatialMaterialTexCoordMode Rasterizer::fixed_material_get_texcoord_mod
void Rasterizer::fixed_material_set_uv_transform(RID p_material,const Transform& p_transform) {
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND(!E);
- FixedSpatialMaterial &fm=*E->get();
+ SpatialMaterial &fm=*E->get();
RID material=E->key();
VS::get_singleton()->material_set_param(material,_fixed_material_uv_xform_name,p_transform);
@@ -503,18 +503,18 @@ void Rasterizer::fixed_material_set_uv_transform(RID p_material,const Transform&
Transform Rasterizer::fixed_material_get_uv_transform(RID p_material) const {
- const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND_V(!E,Transform());
- const FixedSpatialMaterial &fm=*E->get();
+ const SpatialMaterial &fm=*E->get();
return fm.uv_xform;
}
-void Rasterizer::fixed_material_set_light_shader(RID p_material,VS::FixedSpatialMaterialLightShader p_shader) {
+void Rasterizer::fixed_material_set_light_shader(RID p_material,VS::SpatialMaterialLightShader p_shader) {
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND(!E);
- FixedSpatialMaterial &fm=*E->get();
+ SpatialMaterial &fm=*E->get();
fm.light_shader=p_shader;
@@ -523,20 +523,20 @@ void Rasterizer::fixed_material_set_light_shader(RID p_material,VS::FixedSpatial
}
-VS::FixedSpatialMaterialLightShader Rasterizer::fixed_material_get_light_shader(RID p_material) const {
+VS::SpatialMaterialLightShader Rasterizer::fixed_material_get_light_shader(RID p_material) const {
- const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND_V(!E,VS::FIXED_MATERIAL_LIGHT_SHADER_LAMBERT);
- const FixedSpatialMaterial &fm=*E->get();
+ const SpatialMaterial &fm=*E->get();
return fm.light_shader;
}
void Rasterizer::fixed_material_set_point_size(RID p_material,float p_size) {
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND(!E);
- FixedSpatialMaterial &fm=*E->get();
+ SpatialMaterial &fm=*E->get();
RID material=E->key();
VS::get_singleton()->material_set_param(material,_fixed_material_point_size_name,p_size);
@@ -548,9 +548,9 @@ void Rasterizer::fixed_material_set_point_size(RID p_material,float p_size) {
float Rasterizer::fixed_material_get_point_size(RID p_material) const{
- const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND_V(!E,1.0);
- const FixedSpatialMaterial &fm=*E->get();
+ const SpatialMaterial &fm=*E->get();
return fm.point_size;
@@ -561,9 +561,9 @@ void Rasterizer::_update_fixed_materials() {
while(fixed_material_dirty_list.first()) {
- FixedSpatialMaterial &fm=*fixed_material_dirty_list.first()->self();
+ SpatialMaterial &fm=*fixed_material_dirty_list.first()->self();
- FixedSpatialMaterialShaderKey new_key = fm.get_key();
+ SpatialMaterialShaderKey new_key = fm.get_key();
if (new_key.key!=fm.current_key.key) {
_free_shader(fm.current_key);
@@ -593,7 +593,7 @@ void Rasterizer::_update_fixed_materials() {
void Rasterizer::_free_fixed_material(const RID& p_material) {
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
if (E) {
@@ -636,7 +636,7 @@ Rasterizer::Rasterizer() {
draw_viewport_func=NULL;
- ERR_FAIL_COND( sizeof(FixedSpatialMaterialShaderKey)!=4);
+ ERR_FAIL_COND( sizeof(SpatialMaterialShaderKey)!=4);
}
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 838ddead75..56c6dfe30a 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -98,9 +98,6 @@ public:
//int baked_lightmap_id;
bool mirror : 8;
- bool depth_scale : 8;
- bool billboard : 8;
- bool billboard_y : 8;
bool receive_shadows : 8;
bool visible : 8;
@@ -120,9 +117,6 @@ public:
base_type = VS::INSTANCE_NONE;
cast_shadows = VS::SHADOW_CASTING_SETTING_ON;
receive_shadows = true;
- depth_scale = false;
- billboard = false;
- billboard_y = false;
visible = true;
depth_layer = 0;
layer_mask = 1;
@@ -198,10 +192,7 @@ public:
/* SHADER API */
- virtual RID shader_create(VS::ShaderMode p_mode = VS::SHADER_SPATIAL) = 0;
-
- virtual void shader_set_mode(RID p_shader, VS::ShaderMode p_mode) = 0;
- virtual VS::ShaderMode shader_get_mode(RID p_shader) const = 0;
+ virtual RID shader_create() = 0;
virtual void shader_set_code(RID p_shader, const String &p_code) = 0;
virtual String shader_get_code(RID p_shader) const = 0;
@@ -452,19 +443,19 @@ public:
virtual void particles_set_gravity(RID p_particles, const Vector3 &p_gravity) = 0;
virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable) = 0;
virtual void particles_set_process_material(RID p_particles, RID p_material) = 0;
-
- virtual void particles_set_emission_shape(RID p_particles, VS::ParticlesEmissionShape p_shape) = 0;
- virtual void particles_set_emission_sphere_radius(RID p_particles, float p_radius) = 0;
- virtual void particles_set_emission_box_extents(RID p_particles, const Vector3 &p_extents) = 0;
- virtual void particles_set_emission_points(RID p_particles, const PoolVector<Vector3> &p_points) = 0;
+ virtual void particles_set_fixed_fps(RID p_particles, int p_fps) = 0;
+ virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) = 0;
virtual void particles_set_draw_order(RID p_particles, VS::ParticlesDrawOrder p_order) = 0;
virtual void particles_set_draw_passes(RID p_particles, int p_count) = 0;
- virtual void particles_set_draw_pass_material(RID p_particles, int p_pass, RID p_material) = 0;
virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) = 0;
+ virtual void particles_request_process(RID p_particles) = 0;
virtual Rect3 particles_get_current_aabb(RID p_particles) = 0;
+ virtual Rect3 particles_get_aabb(RID p_particles) const = 0;
+
+ virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0;
/* RENDER TARGET */
@@ -971,7 +962,7 @@ protected:
/* Fixed Material Shader API */
- union FixedSpatialMaterialShaderKey {
+ union SpatialMaterialShaderKey {
struct {
uint16_t texcoord_mask;
@@ -987,21 +978,21 @@ protected:
uint32_t key;
- _FORCE_INLINE_ bool operator<(const FixedSpatialMaterialShaderKey& p_key) const { return key<p_key.key; }
+ _FORCE_INLINE_ bool operator<(const SpatialMaterialShaderKey& p_key) const { return key<p_key.key; }
};
- struct FixedSpatialMaterialShader {
+ struct SpatialMaterialShader {
int refcount;
RID shader;
};
- Map<FixedSpatialMaterialShaderKey,FixedSpatialMaterialShader> fixed_material_shaders;
+ Map<SpatialMaterialShaderKey,SpatialMaterialShader> fixed_material_shaders;
- RID _create_shader(const FixedSpatialMaterialShaderKey& p_key);
- void _free_shader(const FixedSpatialMaterialShaderKey& p_key);
+ RID _create_shader(const SpatialMaterialShaderKey& p_key);
+ void _free_shader(const SpatialMaterialShaderKey& p_key);
- struct FixedSpatialMaterial {
+ struct SpatialMaterial {
RID self;
@@ -1012,19 +1003,19 @@ protected:
bool use_xy_normalmap;
float point_size;
Transform uv_xform;
- VS::FixedSpatialMaterialLightShader light_shader;
+ VS::SpatialMaterialLightShader light_shader;
RID texture[VS::FIXED_MATERIAL_PARAM_MAX];
Variant param[VS::FIXED_MATERIAL_PARAM_MAX];
- VS::FixedSpatialMaterialTexCoordMode texture_tc[VS::FIXED_MATERIAL_PARAM_MAX];
+ VS::SpatialMaterialTexCoordMode texture_tc[VS::FIXED_MATERIAL_PARAM_MAX];
- SelfList<FixedSpatialMaterial> dirty_list;
+ SelfList<SpatialMaterial> dirty_list;
- FixedSpatialMaterialShaderKey current_key;
+ SpatialMaterialShaderKey current_key;
- _FORCE_INLINE_ FixedSpatialMaterialShaderKey get_key() const {
+ _FORCE_INLINE_ SpatialMaterialShaderKey get_key() const {
- FixedSpatialMaterialShaderKey k;
+ SpatialMaterialShaderKey k;
k.key=0;
k.use_alpha=use_alpha;
k.use_color_array=use_color_array;
@@ -1045,7 +1036,7 @@ protected:
}
- FixedSpatialMaterial() : dirty_list(this) {
+ SpatialMaterial() : dirty_list(this) {
use_alpha=false;
use_color_array=false;
@@ -1077,9 +1068,9 @@ protected:
StringName _fixed_material_uv_xform_name;
StringName _fixed_material_point_size_name;
- Map<RID,FixedSpatialMaterial*> fixed_materials;
+ Map<RID,SpatialMaterial*> fixed_materials;
- SelfList<FixedSpatialMaterial>::List fixed_material_dirty_list;
+ SelfList<SpatialMaterial>::List fixed_material_dirty_list;
protected:
void _update_fixed_materials();
@@ -1166,23 +1157,23 @@ public:
virtual RID fixed_material_create();
- virtual void fixed_material_set_flag(RID p_material, VS::FixedSpatialMaterialFlags p_flag, bool p_enabled);
- virtual bool fixed_material_get_flag(RID p_material, VS::FixedSpatialMaterialFlags p_flag) const;
+ virtual void fixed_material_set_flag(RID p_material, VS::SpatialMaterialFlags p_flag, bool p_enabled);
+ virtual bool fixed_material_get_flag(RID p_material, VS::SpatialMaterialFlags p_flag) const;
- virtual void fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant& p_value);
- virtual Variant fixed_material_get_parameter(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const;
+ virtual void fixed_material_set_parameter(RID p_material, VS::SpatialMaterialParam p_parameter, const Variant& p_value);
+ virtual Variant fixed_material_get_parameter(RID p_material,VS::SpatialMaterialParam p_parameter) const;
- virtual void fixed_material_set_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter, RID p_texture);
- virtual RID fixed_material_get_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const;
+ virtual void fixed_material_set_texture(RID p_material,VS::SpatialMaterialParam p_parameter, RID p_texture);
+ virtual RID fixed_material_get_texture(RID p_material,VS::SpatialMaterialParam p_parameter) const;
- virtual void fixed_material_set_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode);
- virtual VS::FixedSpatialMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const;
+ virtual void fixed_material_set_texcoord_mode(RID p_material,VS::SpatialMaterialParam p_parameter, VS::SpatialMaterialTexCoordMode p_mode);
+ virtual VS::SpatialMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material,VS::SpatialMaterialParam p_parameter) const;
virtual void fixed_material_set_uv_transform(RID p_material,const Transform& p_transform);
virtual Transform fixed_material_get_uv_transform(RID p_material) const;
- virtual void fixed_material_set_light_shader(RID p_material,VS::FixedSpatialMaterialLightShader p_shader);
- virtual VS::FixedSpatialMaterialLightShader fixed_material_get_light_shader(RID p_material) const;
+ virtual void fixed_material_set_light_shader(RID p_material,VS::SpatialMaterialLightShader p_shader);
+ virtual VS::SpatialMaterialLightShader fixed_material_get_light_shader(RID p_material) const;
virtual void fixed_material_set_point_size(RID p_material,float p_size);
virtual float fixed_material_get_point_size(RID p_material) const;
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index bc4452d5a8..ecb0bdef37 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -81,7 +81,8 @@ String ShaderLanguage::get_operator_text(Operator p_op) {
"++"
"--",
"()",
- "construct" };
+ "construct",
+ "index" };
return op_names[p_op];
}
@@ -176,6 +177,9 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"PERIOD",
"UNIFORM",
"VARYING",
+ "IN",
+ "OUT",
+ "INOUT",
"RENDER_MODE",
"HINT_WHITE_TEXTURE",
"HINT_BLACK_TEXTURE",
@@ -185,6 +189,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"HINT_BLACK_ALBEDO_TEXTURE",
"HINT_COLOR",
"HINT_RANGE",
+ "SHADER_TYPE",
"CURSOR",
"ERROR",
"EOF",
@@ -258,6 +263,9 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
{ TK_CF_RETURN, "return" },
{ TK_UNIFORM, "uniform" },
{ TK_VARYING, "varying" },
+ { TK_ARG_IN, "in" },
+ { TK_ARG_OUT, "out" },
+ { TK_ARG_INOUT, "inout" },
{ TK_RENDER_MODE, "render_mode" },
{ TK_HINT_WHITE_TEXTURE, "hint_white" },
{ TK_HINT_BLACK_TEXTURE, "hint_black" },
@@ -267,6 +275,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
{ TK_HINT_BLACK_ALBEDO_TEXTURE, "hint_black_albedo" },
{ TK_HINT_COLOR, "hint_color" },
{ TK_HINT_RANGE, "hint_range" },
+ { TK_SHADER_TYPE, "shader_type" },
{ TK_ERROR, NULL }
};
@@ -368,7 +377,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
if (GETCHAR(0) == '=') {
char_idx++;
return _make_token(TK_OP_GREATER_EQUAL);
- } else if (GETCHAR(0) == '<') {
+ } else if (GETCHAR(0) == '>') {
char_idx++;
if (GETCHAR(0) == '=') {
char_idx++;
@@ -871,7 +880,7 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
}
if (na == nb) {
- valid = (na > TYPE_BOOL && na < TYPE_MAT2) || (p_op->op == OP_MUL && na >= TYPE_MAT2 && na <= TYPE_MAT4);
+ valid = (na > TYPE_BOOL && na <= TYPE_MAT4);
ret_type = na;
} else if (na == TYPE_INT && nb == TYPE_IVEC2) {
valid = true;
@@ -900,15 +909,24 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
} else if (na == TYPE_FLOAT && nb == TYPE_VEC4) {
valid = true;
ret_type = TYPE_VEC4;
- } else if (p_op->op == OP_MUL && na == TYPE_VEC2 && nb == TYPE_MAT2) {
+ } else if (p_op->op == OP_MUL && na == TYPE_FLOAT && nb == TYPE_MAT2) {
valid = true;
ret_type = TYPE_MAT2;
- } else if (p_op->op == OP_MUL && na == TYPE_VEC3 && nb == TYPE_MAT3) {
+ } else if (p_op->op == OP_MUL && na == TYPE_FLOAT && nb == TYPE_MAT3) {
valid = true;
ret_type = TYPE_MAT3;
- } else if (p_op->op == OP_MUL && na == TYPE_VEC4 && nb == TYPE_MAT4) {
+ } else if (p_op->op == OP_MUL && na == TYPE_FLOAT && nb == TYPE_MAT4) {
valid = true;
ret_type = TYPE_MAT4;
+ } else if (p_op->op == OP_MUL && na == TYPE_VEC2 && nb == TYPE_MAT2) {
+ valid = true;
+ ret_type = TYPE_VEC2;
+ } else if (p_op->op == OP_MUL && na == TYPE_VEC3 && nb == TYPE_MAT3) {
+ valid = true;
+ ret_type = TYPE_VEC3;
+ } else if (p_op->op == OP_MUL && na == TYPE_VEC4 && nb == TYPE_MAT4) {
+ valid = true;
+ ret_type = TYPE_VEC4;
}
} break;
case OP_ASSIGN_MOD:
@@ -977,14 +995,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
DataType na = p_op->arguments[0]->get_datatype();
DataType nb = p_op->arguments[1]->get_datatype();
- if (na >= TYPE_UINT && na <= TYPE_UVEC4) {
- na = DataType(na - 4);
- }
-
- if (nb >= TYPE_UINT && nb <= TYPE_UVEC4) {
- nb = DataType(nb - 4);
- }
-
if (na == TYPE_INT && nb == TYPE_INT) {
valid = true;
ret_type = TYPE_INT;
@@ -1006,6 +1016,27 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
} else if (na == TYPE_IVEC4 && nb == TYPE_IVEC4) {
valid = true;
ret_type = TYPE_IVEC4;
+ } else if (na == TYPE_UINT && nb == TYPE_UINT) {
+ valid = true;
+ ret_type = TYPE_UINT;
+ } else if (na == TYPE_UVEC2 && nb == TYPE_UINT) {
+ valid = true;
+ ret_type = TYPE_UVEC2;
+ } else if (na == TYPE_UVEC3 && nb == TYPE_UINT) {
+ valid = true;
+ ret_type = TYPE_UVEC3;
+ } else if (na == TYPE_UVEC4 && nb == TYPE_UINT) {
+ valid = true;
+ ret_type = TYPE_UVEC4;
+ } else if (na == TYPE_UVEC2 && nb == TYPE_UVEC2) {
+ valid = true;
+ ret_type = TYPE_UVEC2;
+ } else if (na == TYPE_UVEC3 && nb == TYPE_UVEC3) {
+ valid = true;
+ ret_type = TYPE_UVEC3;
+ } else if (na == TYPE_UVEC4 && nb == TYPE_UVEC4) {
+ valid = true;
+ ret_type = TYPE_UVEC4;
}
} break;
case OP_ASSIGN: {
@@ -1651,25 +1682,19 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "not", TYPE_BOOL, { TYPE_BVEC4, TYPE_VOID } },
//builtins - texture
- { "textureSize", TYPE_VEC2, { TYPE_SAMPLER2D, TYPE_INT, TYPE_VOID } },
- { "textureSize", TYPE_VEC2, { TYPE_ISAMPLER2D, TYPE_INT, TYPE_VOID } },
- { "textureSize", TYPE_VEC2, { TYPE_USAMPLER2D, TYPE_INT, TYPE_VOID } },
- { "textureSize", TYPE_VEC2, { TYPE_SAMPLERCUBE, TYPE_INT, TYPE_VOID } },
+ { "textureSize", TYPE_IVEC2, { TYPE_SAMPLER2D, TYPE_INT, TYPE_VOID } },
+ { "textureSize", TYPE_IVEC2, { TYPE_ISAMPLER2D, TYPE_INT, TYPE_VOID } },
+ { "textureSize", TYPE_IVEC2, { TYPE_USAMPLER2D, TYPE_INT, TYPE_VOID } },
+ { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBE, TYPE_INT, TYPE_VOID } },
{ "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID } },
- { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_VOID } },
{ "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
- { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
{ "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VOID } },
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_VOID } },
{ "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
{ "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VOID } },
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_VOID } },
{ "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VOID } },
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
@@ -1689,9 +1714,9 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
{ "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } },
- { "textureLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
- { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
- { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
+ { "textureLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
+ { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
+ { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
{ "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
{ "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID } },
@@ -2308,9 +2333,17 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
bool ok = _parse_function_arguments(p_block, p_builtin_types, func, &carg);
+ //test if function was parsed first
for (int i = 0; i < shader->functions.size(); i++) {
if (shader->functions[i].name == name) {
- shader->functions[i].uses_function.insert(name);
+ //add to current function as dependency
+ for (int j = 0; j < shader->functions.size(); j++) {
+ if (shader->functions[j].name == current_function) {
+ shader->functions[j].uses_function.insert(name);
+ break;
+ }
+ }
+ break;
}
}
@@ -2514,18 +2547,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
} break;
- case TYPE_MAT2:
- ok = (ident == "x" || ident == "y");
- member_type = TYPE_VEC2;
- break;
- case TYPE_MAT3:
- ok = (ident == "x" || ident == "y" || ident == "z");
- member_type = TYPE_VEC3;
- break;
- case TYPE_MAT4:
- ok = (ident == "x" || ident == "y" || ident == "z" || ident == "w");
- member_type = TYPE_VEC4;
- break;
+
default: {}
}
@@ -2552,6 +2574,116 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
//creates a subindexing expression in place
*/
+ } else if (tk.type == TK_BRACKET_OPEN) {
+
+ Node *index = _parse_and_reduce_expression(p_block, p_builtin_types);
+
+ if (index->get_datatype() != TYPE_INT && index->get_datatype() != TYPE_UINT) {
+ _set_error("Only integer datatypes are allowed for indexing");
+ return NULL;
+ }
+
+ bool index_valid = false;
+ DataType member_type;
+
+ switch (expr->get_datatype()) {
+ case TYPE_BVEC2:
+ case TYPE_VEC2:
+ case TYPE_IVEC2:
+ case TYPE_UVEC2:
+ case TYPE_MAT2:
+ if (index->type == Node::TYPE_CONSTANT) {
+ uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
+ if (index_constant >= 2) {
+ _set_error("Index out of range (0-1)");
+ return NULL;
+ }
+ } else {
+ _set_error("Only integer constants are allowed as index at the moment");
+ return NULL;
+ }
+ index_valid = true;
+ switch (expr->get_datatype()) {
+ case TYPE_BVEC2: member_type = TYPE_BOOL; break;
+ case TYPE_VEC2: member_type = TYPE_FLOAT; break;
+ case TYPE_IVEC2: member_type = TYPE_INT; break;
+ case TYPE_UVEC2: member_type = TYPE_UINT; break;
+ case TYPE_MAT2: member_type = TYPE_VEC2; break;
+ }
+
+ break;
+ case TYPE_BVEC3:
+ case TYPE_VEC3:
+ case TYPE_IVEC3:
+ case TYPE_UVEC3:
+ case TYPE_MAT3:
+ if (index->type == Node::TYPE_CONSTANT) {
+ uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
+ if (index_constant >= 3) {
+ _set_error("Index out of range (0-2)");
+ return NULL;
+ }
+ } else {
+ _set_error("Only integer constants are allowed as index at the moment");
+ return NULL;
+ }
+ index_valid = true;
+ switch (expr->get_datatype()) {
+ case TYPE_BVEC3: member_type = TYPE_BOOL; break;
+ case TYPE_VEC3: member_type = TYPE_FLOAT; break;
+ case TYPE_IVEC3: member_type = TYPE_INT; break;
+ case TYPE_UVEC3: member_type = TYPE_UINT; break;
+ case TYPE_MAT3: member_type = TYPE_VEC3; break;
+ }
+ break;
+ case TYPE_BVEC4:
+ case TYPE_VEC4:
+ case TYPE_IVEC4:
+ case TYPE_UVEC4:
+ case TYPE_MAT4:
+ if (index->type == Node::TYPE_CONSTANT) {
+ uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
+ if (index_constant >= 4) {
+ _set_error("Index out of range (0-3)");
+ return NULL;
+ }
+ } else {
+ _set_error("Only integer constants are allowed as index at the moment");
+ return NULL;
+ }
+ index_valid = true;
+ switch (expr->get_datatype()) {
+ case TYPE_BVEC4: member_type = TYPE_BOOL; break;
+ case TYPE_VEC4: member_type = TYPE_FLOAT; break;
+ case TYPE_IVEC4: member_type = TYPE_INT; break;
+ case TYPE_UVEC4: member_type = TYPE_UINT; break;
+ case TYPE_MAT4: member_type = TYPE_VEC4; break;
+ }
+ break;
+ default: {
+ _set_error("Object of type '" + get_datatype_name(expr->get_datatype()) + "' can't be indexed");
+ return NULL;
+ }
+ }
+
+ if (!index_valid) {
+ _set_error("Invalid index");
+ return NULL;
+ }
+
+ OperatorNode *op = alloc_node<OperatorNode>();
+ op->op = OP_INDEX;
+ op->return_cache = member_type;
+ op->arguments.push_back(expr);
+ op->arguments.push_back(index);
+ expr = op;
+
+ tk = _get_token();
+ if (tk.type != TK_BRACKET_CLOSE) {
+ _set_error("Expected ']' after indexing expression");
+ return NULL;
+ }
+
} else if (tk.type == TK_OP_INCREMENT || tk.type == TK_OP_DECREMENT) {
OperatorNode *op = alloc_node<OperatorNode>();
@@ -3077,6 +3209,52 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
_set_tkpos(pos); //rollback
}
+ } else if (tk.type == TK_CF_RETURN) {
+
+ //check return type
+ BlockNode *b = p_block;
+ while (b && !b->parent_function) {
+ b = b->parent_block;
+ }
+
+ if (!b) {
+ _set_error("Bug");
+ return ERR_BUG;
+ }
+
+ ControlFlowNode *flow = alloc_node<ControlFlowNode>();
+ flow->flow_op = FLOW_OP_RETURN;
+
+ pos = _get_tkpos();
+ tk = _get_token();
+ if (tk.type == TK_SEMICOLON) {
+ //all is good
+ if (b->parent_function->return_type != TYPE_VOID) {
+ _set_error("Expected return with expression of type '" + get_datatype_name(b->parent_function->return_type) + "'");
+ return ERR_PARSE_ERROR;
+ }
+ } else {
+ _set_tkpos(pos); //rollback, wants expression
+ Node *expr = _parse_and_reduce_expression(p_block, p_builtin_types);
+ if (!expr)
+ return ERR_PARSE_ERROR;
+
+ if (b->parent_function->return_type != expr->get_datatype()) {
+ _set_error("Expected return expression of type '" + get_datatype_name(b->parent_function->return_type) + "'");
+ return ERR_PARSE_ERROR;
+ }
+
+ tk = _get_token();
+ if (tk.type != TK_SEMICOLON) {
+ _set_error("Expected ';' after return expression");
+ return ERR_PARSE_ERROR;
+ }
+
+ flow->expressions.push_back(expr);
+ }
+
+ p_block->statements.push_back(flow);
+
} else {
//nothng else, so expression
@@ -3100,10 +3278,47 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
return OK;
}
-Error ShaderLanguage::_parse_shader(const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes) {
+Error ShaderLanguage::_parse_shader(const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types) {
Token tk = _get_token();
+ if (tk.type != TK_SHADER_TYPE) {
+ _set_error("Expected 'shader_type' at the begining of shader.");
+ return ERR_PARSE_ERROR;
+ }
+
+ tk = _get_token();
+
+ if (tk.type != TK_IDENTIFIER) {
+ _set_error("Expected identifier after 'shader_type', indicating type of shader.");
+ return ERR_PARSE_ERROR;
+ }
+
+ String shader_type_identifier;
+
+ shader_type_identifier = tk.text;
+
+ if (!p_shader_types.has(shader_type_identifier)) {
+
+ String valid;
+ for (Set<String>::Element *E = p_shader_types.front(); E; E = E->next()) {
+ if (valid != String()) {
+ valid += ", ";
+ }
+ valid += "'" + E->get() + "'";
+ }
+ _set_error("Invalid shader type, valid types are: " + valid);
+ return ERR_PARSE_ERROR;
+ }
+
+ tk = _get_token();
+
+ if (tk.type != TK_SEMICOLON) {
+ _set_error("Expected ';' after 'shader_type <type>'.");
+ }
+
+ tk = _get_token();
+
int texture_uniforms = 0;
int uniforms = 0;
@@ -3428,6 +3643,19 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, Map<StringName, DataTy
break;
}
+ ArgumentQualifier qualifier = ARGUMENT_QUALIFIER_IN;
+
+ if (tk.type == TK_ARG_IN) {
+ qualifier = ARGUMENT_QUALIFIER_IN;
+ tk = _get_token();
+ } else if (tk.type == TK_ARG_OUT) {
+ qualifier = ARGUMENT_QUALIFIER_OUT;
+ tk = _get_token();
+ } else if (tk.type == TK_ARG_INOUT) {
+ qualifier = ARGUMENT_QUALIFIER_INOUT;
+ tk = _get_token();
+ }
+
DataType ptype;
StringName pname;
DataPrecision pprecision = PRECISION_DEFAULT;
@@ -3466,6 +3694,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, Map<StringName, DataTy
arg.type = ptype;
arg.name = pname;
arg.precision = pprecision;
+ arg.qualifier = qualifier;
func_node->arguments.push_back(arg);
@@ -3515,7 +3744,42 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, Map<StringName, DataTy
return OK;
}
-Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes) {
+String ShaderLanguage::get_shader_type(const String &p_code) {
+
+ bool reading_type = false;
+
+ String cur_identifier;
+
+ for (int i = 0; i < p_code.length() + 1; i++) {
+
+ if (p_code[i] == ';') {
+ break;
+
+ } else if (p_code[i] <= 32) {
+ if (cur_identifier != String()) {
+ if (!reading_type) {
+ if (cur_identifier != "shader_type") {
+ return String();
+ }
+
+ reading_type = true;
+ cur_identifier = String();
+ } else {
+ return cur_identifier;
+ }
+ }
+ } else {
+ cur_identifier += String::chr(p_code[i]);
+ }
+ }
+
+ if (reading_type)
+ return cur_identifier;
+
+ return String();
+}
+
+Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types) {
clear();
@@ -3524,7 +3788,7 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Map<St
nodes = NULL;
shader = alloc_node<ShaderNode>();
- Error err = _parse_shader(p_functions, p_render_modes);
+ Error err = _parse_shader(p_functions, p_render_modes, p_shader_types);
if (err != OK) {
return err;
@@ -3532,7 +3796,7 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Map<St
return OK;
}
-Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, List<String> *r_options, String &r_call_hint) {
+Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint) {
clear();
@@ -3541,7 +3805,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Map<S
nodes = NULL;
shader = alloc_node<ShaderNode>();
- Error err = _parse_shader(p_functions, p_render_modes);
+ Error err = _parse_shader(p_functions, p_render_modes, p_shader_types);
switch (completion_type) {
diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h
index a4757e3419..5e7ae3b70f 100644
--- a/servers/visual/shader_language.h
+++ b/servers/visual/shader_language.h
@@ -130,6 +130,9 @@ public:
TK_PERIOD,
TK_UNIFORM,
TK_VARYING,
+ TK_ARG_IN,
+ TK_ARG_OUT,
+ TK_ARG_INOUT,
TK_RENDER_MODE,
TK_HINT_WHITE_TEXTURE,
TK_HINT_BLACK_TEXTURE,
@@ -139,6 +142,7 @@ public:
TK_HINT_BLACK_ALBEDO_TEXTURE,
TK_HINT_COLOR,
TK_HINT_RANGE,
+ TK_SHADER_TYPE,
TK_CURSOR,
TK_ERROR,
TK_EOF,
@@ -227,6 +231,7 @@ public:
OP_POST_DECREMENT,
OP_CALL,
OP_CONSTRUCT,
+ OP_INDEX,
OP_MAX
};
@@ -242,6 +247,13 @@ public:
};
+ enum ArgumentQualifier {
+ ARGUMENT_QUALIFIER_IN,
+ ARGUMENT_QUALIFIER_OUT,
+ ARGUMENT_QUALIFIER_INOUT,
+
+ };
+
struct Node {
Node *next;
@@ -363,6 +375,7 @@ public:
struct Argument {
+ ArgumentQualifier qualifier;
StringName name;
DataType type;
DataPrecision precision;
@@ -577,14 +590,16 @@ private:
Error _parse_block(BlockNode *p_block, const Map<StringName, DataType> &p_builtin_types, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false);
- Error _parse_shader(const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes);
+ Error _parse_shader(const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types);
public:
//static void get_keyword_list(ShaderType p_type,List<String> *p_keywords);
void clear();
- Error compile(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes);
- Error complete(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, List<String> *r_options, String &r_call_hint);
+
+ static String get_shader_type(const String &p_code);
+ Error compile(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types);
+ Error complete(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint);
String get_error_text();
int get_error_line();
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index c5e31b235a..02e970c786 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -38,6 +38,10 @@ const Set<String> &ShaderTypes::get_modes(VS::ShaderMode p_mode) {
return shader_modes[p_mode].modes;
}
+const Set<String> &ShaderTypes::get_types() {
+ return shader_types;
+}
+
ShaderTypes *ShaderTypes::singleton = NULL;
ShaderTypes::ShaderTypes() {
@@ -61,11 +65,14 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["POINT_SIZE"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["INSTANCE_ID"] = ShaderLanguage::TYPE_INT;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["INSTANCE_CUSTOM"] = ShaderLanguage::TYPE_VEC4;
//builtins
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["INV_CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["MODELVIEW_MATRIX"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["VIEWPORT_SIZE"] = ShaderLanguage::TYPE_VEC2;
@@ -122,7 +129,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].modes.insert("unshaded");
shader_modes[VS::SHADER_SPATIAL].modes.insert("ontop");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("skip_transform");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("skip_default_transform");
/************ CANVAS ITEM **************************/
@@ -136,6 +143,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["EXTRA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["PARTICLE_CUSTOM"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["SRC_COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["POSITION"] = ShaderLanguage::TYPE_VEC2;
@@ -189,14 +197,21 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["RESTART"] = ShaderLanguage::TYPE_BOOL;
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["CUSTOM"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["TRANSFORM"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["TIME"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["LIFETIME"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["DELTA"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["SEED"] = ShaderLanguage::TYPE_BOOL;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["ORIGIN"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["NUMBER"] = ShaderLanguage::TYPE_UINT;
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["INDEX"] = ShaderLanguage::TYPE_INT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["SEED"] = ShaderLanguage::TYPE_UINT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["GRAVITY"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["EMISSION_TRANSFORM"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_PARTICLES].modes.insert("billboard");
shader_modes[VS::SHADER_PARTICLES].modes.insert("disable_force");
shader_modes[VS::SHADER_PARTICLES].modes.insert("disable_velocity");
+ shader_modes[VS::SHADER_PARTICLES].modes.insert("keep_data");
+
+ shader_types.insert("spatial");
+ shader_types.insert("canvas_item");
+ shader_types.insert("particles");
}
diff --git a/servers/visual/shader_types.h b/servers/visual/shader_types.h
index 1bddde8c82..1f5131e019 100644
--- a/servers/visual/shader_types.h
+++ b/servers/visual/shader_types.h
@@ -43,11 +43,14 @@ class ShaderTypes {
static ShaderTypes *singleton;
+ Set<String> shader_types;
+
public:
static ShaderTypes *get_singleton() { return singleton; }
const Map<StringName, Map<StringName, ShaderLanguage::DataType> > &get_functions(VS::ShaderMode p_mode);
const Set<String> &get_modes(VS::ShaderMode p_mode);
+ const Set<String> &get_types();
ShaderTypes();
};
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 2666a95595..624dc6dfe0 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -38,6 +38,8 @@
// careful, these may run in different threads than the visual server
+int VisualServerRaster::changes = 0;
+
/* CURSOR */
void VisualServerRaster::cursor_set_rotation(float p_rotation, int p_cursor) {
}
@@ -391,33 +393,33 @@ RID VisualServerRaster::fixed_material_create() {
return rasterizer->fixed_material_create();
}
-void VisualServerRaster::fixed_material_set_flag(RID p_material, FixedSpatialMaterialFlags p_flag, bool p_enabled) {
+void VisualServerRaster::fixed_material_set_flag(RID p_material, SpatialMaterialFlags p_flag, bool p_enabled) {
rasterizer->fixed_material_set_flag(p_material,p_flag,p_enabled);
}
-bool VisualServerRaster::fixed_material_get_flag(RID p_material, FixedSpatialMaterialFlags p_flag) const {
+bool VisualServerRaster::fixed_material_get_flag(RID p_material, SpatialMaterialFlags p_flag) const {
return rasterizer->fixed_material_get_flag(p_material,p_flag);
}
-void VisualServerRaster::fixed_material_set_param(RID p_material, FixedSpatialMaterialParam p_parameter, const Variant& p_value) {
+void VisualServerRaster::fixed_material_set_param(RID p_material, SpatialMaterialParam p_parameter, const Variant& p_value) {
VS_CHANGED;
rasterizer->fixed_material_set_parameter(p_material,p_parameter,p_value);
}
-Variant VisualServerRaster::fixed_material_get_param(RID p_material,FixedSpatialMaterialParam p_parameter) const {
+Variant VisualServerRaster::fixed_material_get_param(RID p_material,SpatialMaterialParam p_parameter) const {
return rasterizer->fixed_material_get_parameter(p_material,p_parameter);
}
-void VisualServerRaster::fixed_material_set_texture(RID p_material,FixedSpatialMaterialParam p_parameter, RID p_texture) {
+void VisualServerRaster::fixed_material_set_texture(RID p_material,SpatialMaterialParam p_parameter, RID p_texture) {
VS_CHANGED;
rasterizer->fixed_material_set_texture(p_material,p_parameter,p_texture);
}
-RID VisualServerRaster::fixed_material_get_texture(RID p_material,FixedSpatialMaterialParam p_parameter) const {
+RID VisualServerRaster::fixed_material_get_texture(RID p_material,SpatialMaterialParam p_parameter) const {
return rasterizer->fixed_material_get_texture(p_material,p_parameter);
}
@@ -425,12 +427,12 @@ RID VisualServerRaster::fixed_material_get_texture(RID p_material,FixedSpatialMa
-void VisualServerRaster::fixed_material_set_texcoord_mode(RID p_material,FixedSpatialMaterialParam p_parameter, FixedSpatialMaterialTexCoordMode p_mode) {
+void VisualServerRaster::fixed_material_set_texcoord_mode(RID p_material,SpatialMaterialParam p_parameter, SpatialMaterialTexCoordMode p_mode) {
VS_CHANGED;
rasterizer->fixed_material_set_texcoord_mode(p_material,p_parameter,p_mode);
}
-VS::FixedSpatialMaterialTexCoordMode VisualServerRaster::fixed_material_get_texcoord_mode(RID p_material,FixedSpatialMaterialParam p_parameter) const {
+VS::SpatialMaterialTexCoordMode VisualServerRaster::fixed_material_get_texcoord_mode(RID p_material,SpatialMaterialParam p_parameter) const {
return rasterizer->fixed_material_get_texcoord_mode(p_material,p_parameter);
}
@@ -457,14 +459,14 @@ Transform VisualServerRaster::fixed_material_get_uv_transform(RID p_material) co
return rasterizer->fixed_material_get_uv_transform(p_material);
}
-void VisualServerRaster::fixed_material_set_light_shader(RID p_material,FixedSpatialMaterialLightShader p_shader) {
+void VisualServerRaster::fixed_material_set_light_shader(RID p_material,SpatialMaterialLightShader p_shader) {
VS_CHANGED;
rasterizer->fixed_material_set_light_shader(p_material,p_shader);
}
-VisualServerRaster::FixedSpatialMaterialLightShader VisualServerRaster::fixed_material_get_light_shader(RID p_material) const{
+VisualServerRaster::SpatialMaterialLightShader VisualServerRaster::fixed_material_get_light_shader(RID p_material) const{
return rasterizer->fixed_material_get_light_shader(p_material);
}
@@ -4521,7 +4523,7 @@ void VisualServerRaster::canvas_occluder_polygon_set_cull_mode(RID p_occluder_po
RID VisualServerRaster::canvas_item_material_create() {
- Rasterizer::CanvasItemMaterial *material = memnew( Rasterizer::CanvasItemMaterial );
+ Rasterizer::ShaderMaterial *material = memnew( Rasterizer::ShaderMaterial );
return canvas_item_material_owner.make_rid(material);
}
@@ -4529,7 +4531,7 @@ RID VisualServerRaster::canvas_item_material_create() {
void VisualServerRaster::canvas_item_material_set_shader(RID p_material, RID p_shader){
VS_CHANGED;
- Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material );
+ Rasterizer::ShaderMaterial *material = canvas_item_material_owner.get( p_material );
ERR_FAIL_COND(!material);
material->shader=p_shader;
@@ -4537,7 +4539,7 @@ void VisualServerRaster::canvas_item_material_set_shader(RID p_material, RID p_s
void VisualServerRaster::canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value){
VS_CHANGED;
- Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material );
+ Rasterizer::ShaderMaterial *material = canvas_item_material_owner.get( p_material );
ERR_FAIL_COND(!material);
if (p_value.get_type()==Variant::NIL)
material->shader_param.erase(p_param);
@@ -4547,7 +4549,7 @@ void VisualServerRaster::canvas_item_material_set_shader_param(RID p_material, c
}
Variant VisualServerRaster::canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const{
- Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material );
+ Rasterizer::ShaderMaterial *material = canvas_item_material_owner.get( p_material );
ERR_FAIL_COND_V(!material,Variant());
if (!material->shader_param.has(p_param)) {
ERR_FAIL_COND_V(!material->shader.is_valid(),Variant());
@@ -4560,7 +4562,7 @@ Variant VisualServerRaster::canvas_item_material_get_shader_param(RID p_material
void VisualServerRaster::canvas_item_material_set_shading_mode(RID p_material, CanvasItemShadingMode p_mode) {
VS_CHANGED;
- Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material );
+ Rasterizer::ShaderMaterial *material = canvas_item_material_owner.get( p_material );
ERR_FAIL_COND(!material);
material->shading_mode=p_mode;
@@ -4869,7 +4871,7 @@ void VisualServerRaster::free( RID p_rid ) {
} else if (canvas_item_material_owner.owns(p_rid)) {
- Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get(p_rid);
+ Rasterizer::ShaderMaterial *material = canvas_item_material_owner.get(p_rid);
ERR_FAIL_COND(!material);
for(Set<Rasterizer::CanvasItem*>::Element *E=material->owners.front();E;E=E->next()) {
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 58e07057f2..a0d567e872 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -56,7 +56,7 @@ class VisualServerRaster : public VisualServer {
};
- int changes;
+ static int changes;
bool draw_extra_frame;
RID test_cube;
@@ -376,7 +376,7 @@ class VisualServerRaster : public VisualServer {
- mutable RID_Owner<Rasterizer::CanvasItemMaterial> canvas_item_material_owner;
+ mutable RID_Owner<Rasterizer::ShaderMaterial> canvas_item_material_owner;
@@ -575,6 +575,8 @@ class VisualServerRaster : public VisualServer {
#endif
public:
+ _FORCE_INLINE_ static void redraw_request() { changes++; }
+
#define DISPLAY_CHANGED changes++;
#define BIND0R(m_r, m_name) \
@@ -647,10 +649,7 @@ public:
/* SHADER API */
- BIND1R(RID, shader_create, ShaderMode)
-
- BIND2(shader_set_mode, RID, ShaderMode)
- BIND1RC(ShaderMode, shader_get_mode, RID)
+ BIND0R(RID, shader_create)
BIND2(shader_set_code, RID, const String &)
BIND1RC(String, shader_get_code, RID)
@@ -855,16 +854,12 @@ public:
BIND2(particles_set_gravity, RID, const Vector3 &)
BIND2(particles_set_use_local_coordinates, RID, bool)
BIND2(particles_set_process_material, RID, RID)
-
- BIND2(particles_set_emission_shape, RID, VS::ParticlesEmissionShape)
- BIND2(particles_set_emission_sphere_radius, RID, float)
- BIND2(particles_set_emission_box_extents, RID, const Vector3 &)
- BIND2(particles_set_emission_points, RID, const PoolVector<Vector3> &)
+ BIND2(particles_set_fixed_fps, RID, int)
+ BIND2(particles_set_fractional_delta, RID, bool)
BIND2(particles_set_draw_order, RID, VS::ParticlesDrawOrder)
BIND2(particles_set_draw_passes, RID, int)
- BIND3(particles_set_draw_pass_material, RID, int, RID)
BIND3(particles_set_draw_pass_mesh, RID, int, RID)
BIND1R(Rect3, particles_get_current_aabb, RID);
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 9b77ca9e1c..acaf5dc792 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -29,6 +29,7 @@
#include "visual_server_scene.h"
#include "os/os.h"
#include "visual_server_global.h"
+#include "visual_server_raster.h"
/* CAMERA API */
RID VisualServerScene::camera_create() {
@@ -609,7 +610,8 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) {
} break;
case VS::INSTANCE_MESH:
case VS::INSTANCE_MULTIMESH:
- case VS::INSTANCE_IMMEDIATE: {
+ case VS::INSTANCE_IMMEDIATE:
+ case VS::INSTANCE_PARTICLES: {
InstanceGeometryData *geom = memnew(InstanceGeometryData);
instance->base_data = geom;
@@ -975,16 +977,6 @@ void VisualServerScene::instance_geometry_set_flag(RID p_instance, VS::InstanceF
switch (p_flags) {
- case VS::INSTANCE_FLAG_BILLBOARD: {
-
- instance->billboard = p_enabled;
-
- } break;
- case VS::INSTANCE_FLAG_BILLBOARD_FIX_Y: {
-
- instance->billboard_y = p_enabled;
-
- } break;
case VS::INSTANCE_FLAG_CAST_SHADOW: {
if (p_enabled == true) {
instance->cast_shadows = VS::SHADOW_CASTING_SETTING_ON;
@@ -995,11 +987,6 @@ void VisualServerScene::instance_geometry_set_flag(RID p_instance, VS::InstanceF
instance->base_material_changed(); // to actually compute if shadows are visible or not
} break;
- case VS::INSTANCE_FLAG_DEPH_SCALE: {
-
- instance->depth_scale = p_enabled;
-
- } break;
case VS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS: {
instance->visible_in_all_rooms = p_enabled;
@@ -1050,6 +1037,11 @@ void VisualServerScene::_update_instance(Instance *p_instance) {
reflection_probe->reflection_dirty = true;
}
+ if (p_instance->base_type == VS::INSTANCE_PARTICLES) {
+
+ VSG::storage->particles_set_emission_transform(p_instance->base, p_instance->transform);
+ }
+
if (p_instance->aabb.has_no_surface())
return;
@@ -1235,6 +1227,11 @@ void VisualServerScene::_update_instance_aabb(Instance *p_instance) {
new_aabb = VSG::storage->immediate_get_aabb(p_instance->base);
} break;
+ case VisualServer::INSTANCE_PARTICLES: {
+
+ new_aabb = VSG::storage->particles_get_aabb(p_instance->base);
+
+ } break;
#if 0
case VisualServer::INSTANCE_PARTICLES: {
@@ -1914,6 +1911,13 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(ins->base_data);
+ if (ins->base_type == VS::INSTANCE_PARTICLES) {
+ //particles visible? process them
+ VSG::storage->particles_request_process(ins->base);
+ //particles visible? request redraw
+ VisualServerRaster::redraw_request();
+ }
+
if (geom->lighting_dirty) {
int l = 0;
//only called when lights AABB enter/exit this geometry
diff --git a/servers/visual_server.h b/servers/visual_server.h
index dfa253ff25..d9a84697a4 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -153,10 +153,7 @@ public:
SHADER_MAX
};
- virtual RID shader_create(ShaderMode p_mode = SHADER_SPATIAL) = 0;
-
- virtual void shader_set_mode(RID p_shader, ShaderMode p_mode) = 0;
- virtual ShaderMode shader_get_mode(RID p_shader) const = 0;
+ virtual RID shader_create() = 0;
virtual void shader_set_code(RID p_shader, const String &p_code) = 0;
virtual String shader_get_code(RID p_shader) const = 0;
@@ -485,19 +482,8 @@ public:
virtual void particles_set_gravity(RID p_particles, const Vector3 &p_gravity) = 0;
virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable) = 0;
virtual void particles_set_process_material(RID p_particles, RID p_material) = 0;
-
- enum ParticlesEmissionShape {
- PARTICLES_EMSSION_POINT,
- PARTICLES_EMSSION_SPHERE,
- PARTICLES_EMSSION_BOX,
- PARTICLES_EMSSION_POINTS,
- PARTICLES_EMSSION_SEGMENTS,
- };
-
- virtual void particles_set_emission_shape(RID p_particles, ParticlesEmissionShape) = 0;
- virtual void particles_set_emission_sphere_radius(RID p_particles, float p_radius) = 0;
- virtual void particles_set_emission_box_extents(RID p_particles, const Vector3 &p_extents) = 0;
- virtual void particles_set_emission_points(RID p_particles, const PoolVector<Vector3> &p_points) = 0;
+ virtual void particles_set_fixed_fps(RID p_particles, int p_fps) = 0;
+ virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) = 0;
enum ParticlesDrawOrder {
PARTICLES_DRAW_ORDER_INDEX,
@@ -507,13 +493,7 @@ public:
virtual void particles_set_draw_order(RID p_particles, ParticlesDrawOrder p_order) = 0;
- enum ParticlesDrawPassMode {
- PARTICLES_DRAW_PASS_MODE_QUAD,
- PARTICLES_DRAW_PASS_MODE_MESH
- };
-
virtual void particles_set_draw_passes(RID p_particles, int p_count) = 0;
- virtual void particles_set_draw_pass_material(RID p_particles, int p_pass, RID p_material) = 0;
virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) = 0;
virtual Rect3 particles_get_current_aabb(RID p_particles) = 0;
@@ -689,7 +669,7 @@ public:
INSTANCE_MAX,
/*INSTANCE_BAKED_LIGHT_SAMPLER,*/
- INSTANCE_GEOMETRY_MASK = (1 << INSTANCE_MESH) | (1 << INSTANCE_MULTIMESH) | (1 << INSTANCE_IMMEDIATE)
+ INSTANCE_GEOMETRY_MASK = (1 << INSTANCE_MESH) | (1 << INSTANCE_MULTIMESH) | (1 << INSTANCE_IMMEDIATE) | (1 << INSTANCE_PARTICLES)
};
virtual RID instance_create2(RID p_base, RID p_scenario);
@@ -718,10 +698,7 @@ public:
virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario = RID()) const = 0;
enum InstanceFlags {
- INSTANCE_FLAG_BILLBOARD,
- INSTANCE_FLAG_BILLBOARD_FIX_Y,
INSTANCE_FLAG_CAST_SHADOW,
- INSTANCE_FLAG_DEPH_SCALE,
INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS,
INSTANCE_FLAG_USE_BAKED_LIGHT,
INSTANCE_FLAG_MAX